From 6d5a2eebb609da67239ea37d12d6b2d3bbfef76e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 28 Oct 2020 16:41:53 +0100 Subject: ui: Do not clutter component tree with Redux connects This change refactors the frontend to use hooks for obtaining state within the Redux store as opposed to using Higher-Order Components (HOCs). This eliminates a lot of clutter in the components. --- opendc-web/opendc-web-ui/package.json | 2 +- .../src/components/app/map/MapStageComponent.js | 28 +--- .../src/containers/app/map/GrayContainer.js | 13 +- .../src/containers/app/map/MapStage.js | 33 ++-- .../src/containers/app/map/RackContainer.js | 12 +- .../containers/app/map/RackEnergyFillContainer.js | 44 +++--- .../containers/app/map/RackSpaceFillContainer.js | 20 +-- .../src/containers/app/map/RoomContainer.js | 27 ++-- .../src/containers/app/map/TileContainer.js | 29 ++-- .../src/containers/app/map/TopologyContainer.js | 19 +-- .../src/containers/app/map/WallContainer.js | 14 +- .../app/map/controls/ScaleIndicatorContainer.js | 12 +- .../app/map/controls/ZoomControlContainer.js | 19 +-- .../src/containers/app/map/layers/MapLayer.js | 13 +- .../containers/app/map/layers/ObjectHoverLayer.js | 45 +++--- .../containers/app/map/layers/RoomHoverLayer.js | 63 ++++---- .../app/results/PortfolioResultsContainer.js | 43 +++--- .../app/sidebars/project/PortfolioListContainer.js | 42 +++--- .../sidebars/project/ProjectSidebarContainer.js | 9 +- .../app/sidebars/project/ScenarioListContainer.js | 68 +++++---- .../app/sidebars/project/TopologyListContainer.js | 74 +++++---- .../sidebars/topology/TopologySidebarContainer.js | 12 +- .../building/NewRoomConstructionContainer.js | 23 +-- .../topology/machine/BackToRackContainer.js | 12 +- .../topology/machine/DeleteMachineContainer.js | 12 +- .../topology/machine/MachineNameContainer.js | 12 +- .../topology/machine/MachineSidebarContainer.js | 16 +- .../sidebars/topology/machine/UnitAddContainer.js | 20 +-- .../app/sidebars/topology/machine/UnitContainer.js | 20 +-- .../sidebars/topology/machine/UnitListContainer.js | 16 +- .../sidebars/topology/rack/AddPrefabContainer.js | 12 +- .../sidebars/topology/rack/BackToRoomContainer.js | 12 +- .../sidebars/topology/rack/DeleteRackContainer.js | 12 +- .../sidebars/topology/rack/EmptySlotContainer.js | 13 +- .../app/sidebars/topology/rack/MachineContainer.js | 21 +-- .../sidebars/topology/rack/MachineListContainer.js | 14 +- .../sidebars/topology/rack/RackNameContainer.js | 21 +-- .../sidebars/topology/rack/RackSidebarContainer.js | 12 +- .../topology/room/BackToBuildingContainer.js | 13 +- .../sidebars/topology/room/DeleteRoomContainer.js | 13 +- .../sidebars/topology/room/EditRoomContainer.js | 32 ++-- .../topology/room/RackConstructionContainer.js | 31 ++-- .../sidebars/topology/room/RoomNameContainer.js | 20 +-- .../sidebars/topology/room/RoomSidebarContainer.js | 12 +- .../opendc-web-ui/src/containers/auth/Login.js | 64 +++----- .../opendc-web-ui/src/containers/auth/Logout.js | 12 +- .../src/containers/auth/ProfileName.js | 13 +- .../src/containers/modals/DeleteMachineModal.js | 43 +++--- .../src/containers/modals/DeleteProfileModal.js | 42 +++--- .../src/containers/modals/DeleteRackModal.js | 44 +++--- .../src/containers/modals/DeleteRoomModal.js | 43 +++--- .../src/containers/modals/EditRackNameModal.js | 57 ++++--- .../src/containers/modals/EditRoomNameModal.js | 51 +++---- .../src/containers/modals/NewPortfolioModal.js | 40 +++-- .../src/containers/modals/NewProjectModal.js | 31 ++-- .../src/containers/modals/NewScenarioModal.js | 78 +++++----- .../src/containers/modals/NewTopologyModal.js | 70 +++++---- .../containers/navigation/AppNavbarContainer.js | 14 +- .../src/containers/projects/FilterLink.js | 18 +-- .../projects/NewProjectButtonContainer.js | 12 +- .../src/containers/projects/ProjectActions.js | 17 +-- .../containers/projects/VisibleProjectAuthList.js | 26 ++-- opendc-web/opendc-web-ui/src/pages/App.js | 168 ++++++++------------- opendc-web/opendc-web-ui/src/pages/Profile.js | 51 ++++--- opendc-web/opendc-web-ui/src/pages/Projects.js | 48 +++--- opendc-web/opendc-web-ui/src/shortcuts/keymap.js | 10 +- opendc-web/opendc-web-ui/yarn.lock | 41 +---- 67 files changed, 895 insertions(+), 1108 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 0531c648..025f9584 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -34,11 +34,11 @@ "react-dom": "~16.13.1", "react-fontawesome": "~1.7.1", "react-google-login": "~5.1.14", + "react-hotkeys": "^2.0.0", "react-konva": "~16.13.0-2", "react-redux": "~7.2.0", "react-router-dom": "~5.1.2", "react-scripts": "~3.4.1", - "react-shortcuts": "~2.1.0", "reactstrap": "^8.6.0", "recharts": "~1.8.5", "redux": "~4.0.5", diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js index 2cd0ed6e..60bf3104 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js @@ -1,6 +1,6 @@ import React from 'react' +import { HotKeys } from 'react-hotkeys' import { Stage } from 'react-konva' -import { Shortcuts } from 'react-shortcuts' import MapLayer from '../../../containers/app/map/layers/MapLayer' import ObjectHoverLayer from '../../../containers/app/map/layers/ObjectHoverLayer' import RoomHoverLayer from '../../../containers/app/map/layers/RoomHoverLayer' @@ -55,23 +55,11 @@ class MapStageComponent extends React.Component { this.setState({ mouseX: mousePos.x, mouseY: mousePos.y }) } - handleShortcuts(action) { - switch (action) { - case 'MOVE_LEFT': - this.moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0) - break - case 'MOVE_RIGHT': - this.moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0) - break - case 'MOVE_UP': - this.moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT) - break - case 'MOVE_DOWN': - this.moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT) - break - default: - break - } + handlers = { + MOVE_LEFT: () => this.moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_RIGHT: () => this.moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_UP: () => this.moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), + MOVE_DOWN: () => this.moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), } moveWithDelta(deltaX, deltaY) { @@ -80,7 +68,7 @@ class MapStageComponent extends React.Component { render() { return ( - + { this.stage = stage @@ -95,7 +83,7 @@ class MapStageComponent extends React.Component { - + ) } } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js index 9e4a6969..651b3459 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../actions/interaction-level' import GrayLayer from '../../../components/app/map/elements/GrayLayer' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const GrayContainer = () => { + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + return } -const GrayContainer = connect(undefined, mapDispatchToProps)(GrayLayer) - export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js index 23c920b6..61d123e8 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -1,22 +1,23 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../actions/map' import MapStageComponent from '../../../components/app/map/MapStageComponent' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapDimensions: state.map.dimensions, - } +const MapStage = () => { + const { position, dimensions } = useSelector((state) => state.map) + const dispatch = useDispatch() + const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) + const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) + const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height)) + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - zoomInOnPosition: (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)), - setMapPositionWithBoundsCheck: (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)), - setMapDimensions: (width, height) => dispatch(setMapDimensions(width, height)), - } -} - -const MapStage = connect(mapStateToProps, mapDispatchToProps)(MapStageComponent) - export default MapStage diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js index 40077608..e5af5117 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackGroup from '../../../components/app/map/groups/RackGroup' -const mapStateToProps = (state) => { - return { - interactionLevel: state.interactionLevel, - } +const RackContainer = ({ tile }) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + return } -const RackContainer = connect(mapStateToProps)(RackGroup) - export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js index 53746271..00d3152f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js @@ -1,26 +1,32 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackFillBar from '../../../components/app/map/elements/RackFillBar' -const mapStateToProps = (state, ownProps) => { - let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[ownProps.tileId].rackId] - const machineIds = rack.machineIds - machineIds.forEach((machineId) => { - if (machineId !== null) { - const machine = state.objects.machine[machineId] - machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) - machine.memoryIds.forEach((id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW)) - machine.storageIds.forEach((id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW)) +const RackSpaceFillContainer = (props) => { + const state = useSelector((state) => { + let energyConsumptionTotal = 0 + const rack = state.objects.rack[state.objects.tile[props.tileId].rackId] + const machineIds = rack.machineIds + machineIds.forEach((machineId) => { + if (machineId !== null) { + const machine = state.objects.machine[machineId] + machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) + machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) + machine.memoryIds.forEach( + (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) + ) + machine.storageIds.forEach( + (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) + ) + } + }) + + return { + type: 'energy', + fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), } }) - - return { - type: 'energy', - fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), - } + return } -const RackSpaceFillContainer = connect(mapStateToProps)(RackFillBar) - export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js index 0509a5a5..dc5119fd 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js @@ -1,14 +1,16 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackFillBar from '../../../components/app/map/elements/RackFillBar' -const mapStateToProps = (state, ownProps) => { - const machineIds = state.objects.rack[state.objects.tile[ownProps.tileId].rackId].machineIds - return { - type: 'space', - fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, - } +const RackSpaceFillContainer = (props) => { + const state = useSelector((state) => { + const machineIds = state.objects.rack[state.objects.tile[props.tileId].rackId].machineIds + return { + type: 'space', + fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, + } + }) + return } -const RackSpaceFillContainer = connect(mapStateToProps)(RackFillBar) - export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js index 91bf4e5d..877233fc 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js @@ -1,21 +1,18 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { goFromBuildingToRoom } from '../../../actions/interaction-level' import RoomGroup from '../../../components/app/map/groups/RoomGroup' -const mapStateToProps = (state, ownProps) => { - return { - interactionLevel: state.interactionLevel, - currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.objects.room[ownProps.roomId], - } +const RoomContainer = (props) => { + const state = useSelector((state) => { + return { + interactionLevel: state.interactionLevel, + currentRoomInConstruction: state.construction.currentRoomInConstruction, + room: state.objects.room[props.roomId], + } + }) + const dispatch = useDispatch() + return dispatch(goFromBuildingToRoom(props.roomId))} /> } -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onClick: () => dispatch(goFromBuildingToRoom(ownProps.roomId)), - } -} - -const RoomContainer = connect(mapStateToProps, mapDispatchToProps)(RoomGroup) - export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js index 04d6c8d6..ad7301a7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js @@ -1,26 +1,19 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { goFromRoomToRack } from '../../../actions/interaction-level' import TileGroup from '../../../components/app/map/groups/TileGroup' -const mapStateToProps = (state, ownProps) => { - const tile = state.objects.tile[ownProps.tileId] +const TileContainer = (props) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + const tile = useSelector((state) => state.objects.tile[props.tileId]) - return { - interactionLevel: state.interactionLevel, - tile, + const dispatch = useDispatch() + const onClick = (tile) => { + if (tile.rackId) { + dispatch(goFromRoomToRack(tile._id)) + } } + return } -const mapDispatchToProps = (dispatch) => { - return { - onClick: (tile) => { - if (tile.rackId) { - dispatch(goFromRoomToRack(tile._id)) - } - }, - } -} - -const TileContainer = connect(mapStateToProps, mapDispatchToProps)(TileGroup) - export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js index de43a151..612ca41c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js @@ -1,17 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -const mapStateToProps = (state) => { - if (state.currentTopologyId === '-1') { - return {} - } +const TopologyContainer = () => { + const topology = useSelector( + (state) => state.currentTopologyId !== '-1' && state.objects.topology[state.currentTopologyId] + ) + const interactionLevel = useSelector((state) => state.interactionLevel) - return { - topology: state.objects.topology[state.currentTopologyId], - interactionLevel: state.interactionLevel, - } + return } -const TopologyContainer = connect(mapStateToProps)(TopologyGroup) - export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js index 67f8a242..2a469860 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import WallGroup from '../../../components/app/map/groups/WallGroup' -const mapStateToProps = (state, ownProps) => { - return { - tiles: state.objects.room[ownProps.roomId].tileIds.map((tileId) => state.objects.tile[tileId]), - } +const WallContainer = (props) => { + const tiles = useSelector((state) => + state.objects.room[props.roomId].tileIds.map((tileId) => state.objects.tile[tileId]) + ) + return } -const WallContainer = connect(mapStateToProps)(WallGroup) - export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js index fa3b9d22..e9d58b9f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' -const mapStateToProps = (state) => { - return { - scale: state.map.scale, - } +const ScaleIndicatorContainer = (props) => { + const scale = useSelector((state) => state.map.scale) + return } -const ScaleIndicatorContainer = connect(mapStateToProps)(ScaleIndicatorComponent) - export default ScaleIndicatorContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js index ddc68cc7..a18dfd5b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js @@ -1,19 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { zoomInOnCenter } from '../../../../actions/map' import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent' -const mapStateToProps = (state) => { - return { - mapScale: state.map.scale, - } +const ZoomControlContainer = () => { + const dispatch = useDispatch() + const scale = useSelector((state) => state.map.scale) + return dispatch(zoomInOnCenter(zoomIn))} /> } -const mapDispatchToProps = (dispatch) => { - return { - zoomInOnCenter: (zoomIn) => dispatch(zoomInOnCenter(zoomIn)), - } -} - -const ZoomControlContainer = connect(mapStateToProps, mapDispatchToProps)(ZoomControlComponent) - export default ZoomControlContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js index 8596cb9c..5f701b4b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js @@ -1,13 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - } +const MapLayer = (props) => { + const { position, scale } = useSelector((state) => state.map) + return } -const MapLayer = connect(mapStateToProps)(MapLayerComponent) - export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js index a4927862..cefdf35c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js @@ -1,33 +1,32 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { addRackToTile } from '../../../../actions/topology/room' import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' import { findTileWithPosition } from '../../../../util/tile-calculations' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.inRackConstructionMode, - isValid: (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } +const ObjectHoverLayer = (props) => { + const state = useSelector((state) => { + return { + mapPosition: state.map.position, + mapScale: state.map.scale, + isEnabled: () => state.construction.inRackConstructionMode, + isValid: (x, y) => { + if (state.interactionLevel.mode !== 'ROOM') { + return false + } - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId]) - const tile = findTileWithPosition(tiles, x, y) + const currentRoom = state.objects.room[state.interactionLevel.roomId] + const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId]) + const tile = findTileWithPosition(tiles, x, y) - return !(tile === null || tile.rackId) - }, - } -} + return !(tile === null || tile.rackId) + }, + } + }) -const mapDispatchToProps = (dispatch) => { - return { - onClick: (x, y) => dispatch(addRackToTile(x, y)), - } + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(addRackToTile(x, y)) + return } -const ObjectHoverLayer = connect(mapStateToProps, mapDispatchToProps)(ObjectHoverLayerComponent) - export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js index 66404f9e..2717d890 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js @@ -1,4 +1,5 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { toggleTileAtLocation } from '../../../../actions/topology/building' import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' import { @@ -7,40 +8,38 @@ import { findPositionInRooms, } from '../../../../util/tile-calculations' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.currentRoomInConstruction !== '-1', - isValid: (x, y) => { - const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) - const oldRooms = Object.keys(state.objects.room) - .map((id) => Object.assign({}, state.objects.room[id])) - .filter( - (room) => - state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 && - room._id !== state.construction.currentRoomInConstruction - ) +const RoomHoverLayer = (props) => { + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId]) - }) - if (newRoom.tileIds.length === 0) { - return findPositionInRooms(oldRooms, x, y) === -1 - } + const state = useSelector((state) => { + return { + mapPosition: state.map.position, + mapScale: state.map.scale, + isEnabled: () => state.construction.currentRoomInConstruction !== '-1', + isValid: (x, y) => { + const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) + const oldRooms = Object.keys(state.objects.room) + .map((id) => Object.assign({}, state.objects.room[id])) + .filter( + (room) => + state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 && + room._id !== state.construction.currentRoomInConstruction + ) - const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) - return findPositionInPositions(validNextPositions, x, y) !== -1 - }, - } -} + ;[...oldRooms, newRoom].forEach((room) => { + room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId]) + }) + if (newRoom.tileIds.length === 0) { + return findPositionInRooms(oldRooms, x, y) === -1 + } -const mapDispatchToProps = (dispatch) => { - return { - onClick: (x, y) => dispatch(toggleTileAtLocation(x, y)), - } + const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) + return findPositionInPositions(validNextPositions, x, y) !== -1 + }, + } + }) + return } -const RoomHoverLayer = connect(mapStateToProps, mapDispatchToProps)(RoomHoverLayerComponent) - export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js index 4b430e54..e60abe18 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js @@ -1,28 +1,31 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' -const mapStateToProps = (state) => { - if ( - state.currentPortfolioId === '-1' || - !state.objects.portfolio[state.currentPortfolioId] || - state.objects.portfolio[state.currentPortfolioId].scenarioIds - .map((scenarioId) => state.objects.scenario[scenarioId]) - .some((s) => s === undefined) - ) { +const PortfolioResultsContainer = (props) => { + const { scenarios, portfolio } = useSelector((state) => { + if ( + state.currentPortfolioId === '-1' || + !state.objects.portfolio[state.currentPortfolioId] || + state.objects.portfolio[state.currentPortfolioId].scenarioIds + .map((scenarioId) => state.objects.scenario[scenarioId]) + .some((s) => s === undefined) + ) { + return { + portfolio: undefined, + scenarios: [], + } + } + return { - portfolio: undefined, - scenarios: [], + portfolio: state.objects.portfolio[state.currentPortfolioId], + scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map( + (scenarioId) => state.objects.scenario[scenarioId] + ), } - } + }) - return { - portfolio: state.objects.portfolio[state.currentPortfolioId], - scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map( - (scenarioId) => state.objects.scenario[scenarioId] - ), - } + return } -const PortfolioResultsContainer = connect(mapStateToProps)(PortfolioResultsComponent) - export default PortfolioResultsContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index b32c8b1d..86f465b6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -1,28 +1,31 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { useHistory } from 'react-router-dom' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' import { deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios' import { openNewPortfolioModal } from '../../../../actions/modals/portfolios' import { getState } from '../../../../util/state-utils' import { setCurrentTopology } from '../../../../actions/topology/building' -const mapStateToProps = (state) => { - let portfolios = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t]) - : [] - if (portfolios.filter((t) => !t).length > 0) { - portfolios = [] - } +const PortfolioListContainer = (props) => { + const state = useSelector((state) => { + let portfolios = state.objects.project[state.currentProjectId] + ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t]) + : [] + if (portfolios.filter((t) => !t).length > 0) { + portfolios = [] + } - return { - currentProjectId: state.currentProjectId, - currentPortfolioId: state.currentPortfolioId, - portfolios, - } -} + return { + currentProjectId: state.currentProjectId, + currentPortfolioId: state.currentPortfolioId, + portfolios, + } + }) -const mapDispatchToProps = (dispatch, ownProps) => { - return { + const dispatch = useDispatch() + const history = useHistory() + const actions = { onNewPortfolio: () => { dispatch(openNewPortfolioModal()) }, @@ -34,12 +37,11 @@ const mapDispatchToProps = (dispatch, ownProps) => { const state = await getState(dispatch) dispatch(deletePortfolio(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - ownProps.history.push(`/projects/${state.currentProjectId}`) + history.push(`/projects/${state.currentProjectId}`) } }, } + return } -const PortfolioListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(PortfolioListComponent)) - export default PortfolioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js index 49001099..35e6c52b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js @@ -1,10 +1,11 @@ import React from 'react' -import { withRouter } from 'react-router-dom' +import { useLocation } from 'react-router-dom' import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' import { isCollapsible } from '../../../../util/sidebar-space' -const ProjectSidebarContainer = withRouter(({ location, ...props }) => ( - -)) +const ProjectSidebarContainer = (props) => { + const location = useLocation() + return +} export default ProjectSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 415e2792..18d0735e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -1,41 +1,49 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' import { openNewScenarioModal } from '../../../../actions/modals/scenarios' import { deleteScenario, setCurrentScenario } from '../../../../actions/scenarios' import { setCurrentPortfolio } from '../../../../actions/portfolios' -const mapStateToProps = (state, ownProps) => { - let scenarios = state.objects.portfolio[ownProps.portfolioId] - ? state.objects.portfolio[ownProps.portfolioId].scenarioIds.map((t) => state.objects.scenario[t]) - : [] - if (scenarios.filter((t) => !t).length > 0) { - scenarios = [] - } +const ScenarioListContainer = ({ portfolioId, children }) => { + const currentProjectId = useSelector((state) => state.currentProjectId) + const currentScenarioId = useSelector((state) => state.currentScenarioId) + const scenarios = useSelector((state) => { + let scenarios = state.objects.portfolio[portfolioId] + ? state.objects.portfolio[portfolioId].scenarioIds.map((t) => state.objects.scenario[t]) + : [] + if (scenarios.filter((t) => !t).length > 0) { + scenarios = [] + } - return { - currentProjectId: state.currentProjectId, - currentScenarioId: state.currentScenarioId, - scenarios, - } -} + return scenarios + }) -const mapDispatchToProps = (dispatch) => { - return { - onNewScenario: (currentPortfolioId) => { - dispatch(setCurrentPortfolio(currentPortfolioId)) - dispatch(openNewScenarioModal()) - }, - onChooseScenario: (portfolioId, scenarioId) => { - dispatch(setCurrentScenario(portfolioId, scenarioId)) - }, - onDeleteScenario: (id) => { - if (id) { - dispatch(deleteScenario(id)) - } - }, + const dispatch = useDispatch() + const onNewScenario = (currentPortfolioId) => { + dispatch(setCurrentPortfolio(currentPortfolioId)) + dispatch(openNewScenarioModal()) + } + const onChooseScenario = (portfolioId, scenarioId) => { + dispatch(setCurrentScenario(portfolioId, scenarioId)) + } + const onDeleteScenario = (id) => { + if (id) { + dispatch(deleteScenario(id)) + } } -} -const ScenarioListContainer = connect(mapStateToProps, mapDispatchToProps)(ScenarioListComponent) + return ( + + ) +} export default ScenarioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index e1de18f9..954284a6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -1,46 +1,54 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' import { setCurrentTopology } from '../../../../actions/topology/building' import { openNewTopologyModal } from '../../../../actions/modals/topology' -import { withRouter } from 'react-router-dom' +import { useHistory } from 'react-router-dom' import { getState } from '../../../../util/state-utils' import { deleteTopology } from '../../../../actions/topologies' -const mapStateToProps = (state) => { - let topologies = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) - : [] - if (topologies.filter((t) => !t).length > 0) { - topologies = [] - } +const TopologyListContainer = () => { + const dispatch = useDispatch() + const history = useHistory() - return { - currentTopologyId: state.currentTopologyId, - topologies, - } -} + const topologies = useSelector((state) => { + let topologies = state.objects.project[state.currentProjectId] + ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) + : [] + if (topologies.filter((t) => !t).length > 0) { + topologies = [] + } + + return topologies + }) + const currentTopologyId = useSelector((state) => state.currentTopologyId) -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onChooseTopology: async (id) => { - dispatch(setCurrentTopology(id)) + const onChooseTopology = async (id) => { + dispatch(setCurrentTopology(id)) + const state = await getState(dispatch) + history.push(`/projects/${state.currentProjectId}`) + } + const onNewTopology = () => { + dispatch(openNewTopologyModal()) + } + const onDeleteTopology = async (id) => { + if (id) { const state = await getState(dispatch) - ownProps.history.push(`/projects/${state.currentProjectId}`) - }, - onNewTopology: () => { - dispatch(openNewTopologyModal()) - }, - onDeleteTopology: async (id) => { - if (id) { - const state = await getState(dispatch) - dispatch(deleteTopology(id)) - dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - ownProps.history.push(`/projects/${state.currentProjectId}`) - } - }, + dispatch(deleteTopology(id)) + dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) + history.push(`/projects/${state.currentProjectId}`) + } } -} -const TopologyListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(TopologyListComponent)) + return ( + + ) +} export default TopologyListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js index fe7c02fd..42c81c65 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import TopologySidebarComponent from '../../../../components/app/sidebars/topology/TopologySidebarComponent' -const mapStateToProps = (state) => { - return { - interactionLevel: state.interactionLevel, - } +const TopologySidebarContainer = (props) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + return } -const TopologySidebarContainer = connect(mapStateToProps)(TopologySidebarComponent) - export default TopologySidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js index ea9e9e60..ea36539c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js @@ -1,4 +1,5 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { cancelNewRoomConstruction, finishNewRoomConstruction, @@ -6,20 +7,22 @@ import { } from '../../../../../actions/topology/building' import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent' -const mapStateToProps = (state) => { - return { - currentRoomInConstruction: state.construction.currentRoomInConstruction, - } -} +const NewRoomConstructionButton = (props) => { + const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) -const mapDispatchToProps = (dispatch) => { - return { + const dispatch = useDispatch() + const actions = { onStart: () => dispatch(startNewRoomConstruction()), onFinish: () => dispatch(finishNewRoomConstruction()), onCancel: () => dispatch(cancelNewRoomConstruction()), } + return ( + + ) } -const NewRoomConstructionButton = connect(mapStateToProps, mapDispatchToProps)(StartNewRoomConstructionComponent) - export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js index 24287ab0..46862472 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' import BackToRackComponent from '../../../../../components/app/sidebars/topology/machine/BackToRackComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const BackToRackContainer = (props) => { + const dispatch = useDispatch() + return dispatch(goDownOneInteractionLevel())} /> } -const BackToRackContainer = connect(undefined, mapDispatchToProps)(BackToRackComponent) - export default BackToRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js index 65e683e6..1510a436 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openDeleteMachineModal } from '../../../../../actions/modals/topology' import DeleteMachineComponent from '../../../../../components/app/sidebars/topology/machine/DeleteMachineComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openDeleteMachineModal()), - } +const DeleteMachineContainer = (props) => { + const dispatch = useDispatch() + return dispatch(openDeleteMachineModal())} /> } -const DeleteMachineContainer = connect(undefined, mapDispatchToProps)(DeleteMachineComponent) - export default DeleteMachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js index 1cf35b05..6f4285b2 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MachineNameComponent from '../../../../../components/app/sidebars/topology/machine/MachineNameComponent' -const mapStateToProps = (state) => { - return { - position: state.interactionLevel.position, - } +const MachineNameContainer = (props) => { + const position = useSelector((state) => state.interactionLevel.position) + return } -const MachineNameContainer = connect(mapStateToProps)(MachineNameComponent) - export default MachineNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js index b04e3118..cb7ec8f9 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js @@ -1,15 +1,15 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MachineSidebarComponent from '../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent' -const mapStateToProps = (state) => { - return { - machineId: +const MachineSidebarContainer = (props) => { + const machineId = useSelector( + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ state.interactionLevel.position - 1 - ], - } + ] + ) + return } -const MachineSidebarContainer = connect(mapStateToProps)(MachineSidebarComponent) - export default MachineSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js index 29e48016..3795cdff 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js @@ -1,19 +1,15 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { addUnit } from '../../../../../actions/topology/machine' import UnitAddComponent from '../../../../../components/app/sidebars/topology/machine/UnitAddComponent' -const mapStateToProps = (state, ownProps) => { - return { - units: Object.values(state.objects[ownProps.unitType]), - } -} +const UnitAddContainer = (props) => { + const units = useSelector((state) => Object.values(state.objects[props.unitType])) + const dispatch = useDispatch() -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onAdd: (id) => dispatch(addUnit(ownProps.unitType, id)), - } -} + const onAdd = (id) => dispatch(addUnit(props.unitType, id)) -const UnitAddContainer = connect(mapStateToProps, mapDispatchToProps)(UnitAddComponent) + return +} export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js index f334f9f2..3d24859e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js @@ -1,20 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { deleteUnit } from '../../../../../actions/topology/machine' import UnitComponent from '../../../../../components/app/sidebars/topology/machine/UnitComponent' -const mapStateToProps = (state, ownProps) => { - return { - unit: state.objects[ownProps.unitType][ownProps.unitId], - index: ownProps.unitId, - } -} +const UnitContainer = ({ unitId, unitType }) => { + const dispatch = useDispatch() + const unit = useSelector((state) => state.objects[unitType][unitId]) + const onDelete = () => dispatch(deleteUnit(unitType, unitId)) -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onDelete: () => dispatch(deleteUnit(ownProps.unitType, ownProps.index)), - } + return } -const UnitContainer = connect(mapStateToProps, mapDispatchToProps)(UnitComponent) - export default UnitContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js index f382ff74..c5c9444d 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js @@ -1,17 +1,17 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent' -const mapStateToProps = (state, ownProps) => { - return { - unitIds: +const UnitListContainer = (props) => { + const unitIds = useSelector( + (state) => state.objects.machine[ state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ state.interactionLevel.position - 1 ] - ][ownProps.unitType + 'Ids'], - } + ][props.unitType + 'Ids'] + ) + return } -const UnitListContainer = connect(mapStateToProps)(UnitListComponent) - export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js index c941e745..3708e33e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { addPrefab } from '../../../../../actions/prefabs' import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(addPrefab('name')), - } +const AddPrefabContainer = (props) => { + const dispatch = useDispatch() + return dispatch(addPrefab('name'))} /> } -const AddPrefabContainer = connect(undefined, mapDispatchToProps)(AddPrefabComponent) - export default AddPrefabContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js index 58c3b082..93bb749f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' import BackToRoomComponent from '../../../../../components/app/sidebars/topology/rack/BackToRoomComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const BackToRoomContainer = (props) => { + const dispatch = useDispatch() + return dispatch(goDownOneInteractionLevel())} /> } -const BackToRoomContainer = connect(undefined, mapDispatchToProps)(BackToRoomComponent) - export default BackToRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js index 8229a359..de46e491 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openDeleteRackModal } from '../../../../../actions/modals/topology' import DeleteRackComponent from '../../../../../components/app/sidebars/topology/rack/DeleteRackComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openDeleteRackModal()), - } +const DeleteRackContainer = (props) => { + const dispatch = useDispatch() + return dispatch(openDeleteRackModal())} /> } -const DeleteRackContainer = connect(undefined, mapDispatchToProps)(DeleteRackComponent) - export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js index cf341da9..5bb2c784 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { addMachine } from '../../../../../actions/topology/rack' import EmptySlotComponent from '../../../../../components/app/sidebars/topology/rack/EmptySlotComponent' -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onAdd: () => dispatch(addMachine(ownProps.position)), - } +const EmptySlotContainer = (props) => { + const dispatch = useDispatch() + const onAdd = () => dispatch(addMachine(props.position)) + return } -const EmptySlotContainer = connect(undefined, mapDispatchToProps)(EmptySlotComponent) - export default EmptySlotContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js index fe12827d..149b4d18 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js @@ -1,19 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { goFromRackToMachine } from '../../../../../actions/interaction-level' import MachineComponent from '../../../../../components/app/sidebars/topology/rack/MachineComponent' -const mapStateToProps = (state, ownProps) => { - return { - machine: state.objects.machine[ownProps.machineId], - } +const MachineContainer = (props) => { + const machine = useSelector((state) => state.objects.machine[props.machineId]) + const dispatch = useDispatch() + return ( + dispatch(goFromRackToMachine(props.position))} machine={machine} /> + ) } -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onClick: () => dispatch(goFromRackToMachine(ownProps.position)), - } -} - -const MachineContainer = connect(mapStateToProps, mapDispatchToProps)(MachineComponent) - export default MachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js index bc5a285a..b45300fc 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MachineListComponent from '../../../../../components/app/sidebars/topology/rack/MachineListComponent' -const mapStateToProps = (state) => { - return { - machineIds: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds, - } +const MachineListContainer = (props) => { + const machineIds = useSelector( + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds + ) + return } -const MachineListContainer = connect(mapStateToProps)(MachineListComponent) - export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js index 504dbc61..7dfdb473 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js @@ -1,19 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { openEditRackNameModal } from '../../../../../actions/modals/topology' import RackNameComponent from '../../../../../components/app/sidebars/topology/rack/RackNameComponent' -const mapStateToProps = (state) => { - return { - rackName: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name, - } +const RackNameContainer = (props) => { + const rackName = useSelector( + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name + ) + const dispatch = useDispatch() + return dispatch(openEditRackNameModal())} /> } -const mapDispatchToProps = (dispatch) => { - return { - onEdit: () => dispatch(openEditRackNameModal()), - } -} - -const RackNameContainer = connect(mapStateToProps, mapDispatchToProps)(RackNameComponent) - export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js index 453d7e41..b8fc3bfb 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackSidebarComponent from '../../../../../components/app/sidebars/topology/rack/RackSidebarComponent' -const mapStateToProps = (state) => { - return { - rackId: state.objects.tile[state.interactionLevel.tileId].rackId, - } +const RackSidebarContainer = (props) => { + const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rackId) + return } -const RackSidebarContainer = connect(mapStateToProps)(RackSidebarComponent) - export default RackSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js index 4c1ab99d..a48bf0a7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' import BackToBuildingComponent from '../../../../../components/app/sidebars/topology/room/BackToBuildingComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const BackToBuildingContainer = () => { + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + return } -const BackToBuildingContainer = connect(undefined, mapDispatchToProps)(BackToBuildingComponent) - export default BackToBuildingContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js index 636fa5c5..6a80e9b0 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openDeleteRoomModal } from '../../../../../actions/modals/topology' import DeleteRoomComponent from '../../../../../components/app/sidebars/topology/room/DeleteRoomComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openDeleteRoomModal()), - } +const DeleteRoomContainer = (props) => { + const dispatch = useDispatch() + const onClick = () => dispatch(openDeleteRoomModal()) + return } -const DeleteRoomContainer = connect(undefined, mapDispatchToProps)(DeleteRoomComponent) - export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js index d17a45d1..37027fc5 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js @@ -1,21 +1,25 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { finishRoomEdit, startRoomEdit } from '../../../../../actions/topology/building' import EditRoomComponent from '../../../../../components/app/sidebars/topology/room/EditRoomComponent' -const mapStateToProps = (state) => { - return { - isEditing: state.construction.currentRoomInConstruction !== '-1', - isInRackConstructionMode: state.construction.inRackConstructionMode, - } -} +const EditRoomContainer = (props) => { + const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) -const mapDispatchToProps = (dispatch) => { - return { - onEdit: () => dispatch(startRoomEdit()), - onFinish: () => dispatch(finishRoomEdit()), - } -} + const dispatch = useDispatch() + const onEdit = () => dispatch(startRoomEdit()) + const onFinish = () => dispatch(finishRoomEdit()) -const EditRoomContainer = connect(mapStateToProps, mapDispatchToProps)(EditRoomComponent) + return ( + + ) +} export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js index cd8319de..726e9d37 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js @@ -1,21 +1,24 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { startRackConstruction, stopRackConstruction } from '../../../../../actions/topology/room' import RackConstructionComponent from '../../../../../components/app/sidebars/topology/room/RackConstructionComponent' -const mapStateToProps = (state) => { - return { - inRackConstructionMode: state.construction.inRackConstructionMode, - isEditingRoom: state.construction.currentRoomInConstruction !== '-1', - } -} +const RackConstructionContainer = (props) => { + const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) + const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') -const mapDispatchToProps = (dispatch) => { - return { - onStart: () => dispatch(startRackConstruction()), - onStop: () => dispatch(stopRackConstruction()), - } + const dispatch = useDispatch() + const onStart = () => dispatch(startRackConstruction()) + const onStop = () => dispatch(stopRackConstruction()) + return ( + + ) } -const RackConstructionContainer = connect(mapStateToProps, mapDispatchToProps)(RackConstructionComponent) - export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js index cab16016..1f53aeb6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js @@ -1,19 +1,13 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { openEditRoomNameModal } from '../../../../../actions/modals/topology' import RoomNameComponent from '../../../../../components/app/sidebars/topology/room/RoomNameComponent' -const mapStateToProps = (state) => { - return { - roomName: state.objects.room[state.interactionLevel.roomId].name, - } +const RoomNameContainer = (props) => { + const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name) + const dispatch = useDispatch() + const onEdit = () => dispatch(openEditRoomNameModal()) + return } -const mapDispatchToProps = (dispatch) => { - return { - onEdit: () => dispatch(openEditRoomNameModal()), - } -} - -const RoomNameContainer = connect(mapStateToProps, mapDispatchToProps)(RoomNameComponent) - export default RoomNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js index 8c3ca8ab..252881a0 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RoomSidebarComponent from '../../../../../components/app/sidebars/topology/room/RoomSidebarComponent' -const mapStateToProps = (state) => { - return { - roomId: state.interactionLevel.roomId, - } +const RoomSidebarContainer = (props) => { + const roomId = useSelector((state) => state.interactionLevel.roomId) + return } -const RoomSidebarContainer = connect(mapStateToProps)(RoomSidebarComponent) - export default RoomSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js index bebe015c..54605775 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js @@ -1,18 +1,16 @@ -import PropTypes from 'prop-types' import React from 'react' import GoogleLogin from 'react-google-login' -import { connect } from 'react-redux' +import { useDispatch } from 'react-redux' import { logIn } from '../../actions/auth' import config from '../../config' -class LoginContainer extends React.Component { - static propTypes = { - visible: PropTypes.bool.isRequired, - onLogin: PropTypes.func.isRequired, - } +const Login = (props) => { + const { visible } = props + const dispatch = useDispatch() - onAuthResponse(response) { - this.props.onLogin({ + const onLogin = (payload) => dispatch(logIn(payload)) + const onAuthResponse = (response) => { + onLogin({ email: response.getBasicProfile().getEmail(), givenName: response.getBasicProfile().getGivenName(), familyName: response.getBasicProfile().getFamilyName(), @@ -21,43 +19,27 @@ class LoginContainer extends React.Component { expiresAt: response.getAuthResponse().expires_at, }) } - - onAuthFailure(error) { + const onAuthFailure = (error) => { + // TODO Show error alert console.error(error) } - render() { - if (!this.props.visible) { - return - } - - return ( - ( - - Login with Google - - )} - /> - ) + if (!visible) { + return } -} -const mapStateToProps = (state, ownProps) => { - return { - visible: ownProps.visible, - } + return ( + ( + + Login with Google + + )} + /> + ) } -const mapDispatchToProps = (dispatch) => { - return { - onLogin: (payload) => dispatch(logIn(payload)), - } -} - -const Login = connect(mapStateToProps, mapDispatchToProps)(LoginContainer) - export default Login diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js index 22400381..66f0f6db 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { logOut } from '../../actions/auth' import LogoutButton from '../../components/navigation/LogoutButton' -const mapDispatchToProps = (dispatch) => { - return { - onLogout: () => dispatch(logOut()), - } +const Logout = (props) => { + const dispatch = useDispatch() + return dispatch(logOut())} /> } -const Logout = connect(undefined, mapDispatchToProps)(LogoutButton) - export default Logout diff --git a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js index 06da75ab..291c0068 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js @@ -1,14 +1,9 @@ import React from 'react' -import { connect } from 'react-redux' +import { useSelector } from 'react-redux' -const mapStateToProps = (state) => { - return { - text: state.auth.givenName + ' ' + state.auth.familyName, - } +function ProfileName() { + const name = useSelector((state) => `${state.auth.givenName} ${state.auth.familyName}`) + return {name} } -const SpanElement = ({ text }) => {text} - -const ProfileName = connect(mapStateToProps)(SpanElement) - export default ProfileName diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js index f30febdb..33b2612f 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js @@ -1,35 +1,26 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeDeleteMachineModal } from '../../actions/modals/topology' import { deleteMachine } from '../../actions/topology/machine' import ConfirmationModal from '../../components/modals/ConfirmationModal' -const DeleteMachineModalComponent = ({ visible, callback }) => ( - -) - -const mapStateToProps = (state) => { - return { - visible: state.modals.deleteMachineModalVisible, +const DeleteMachineModal = () => { + const dispatch = useDispatch() + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteMachine()) + } + dispatch(closeDeleteMachineModal()) } + const visible = useSelector((state) => state.modals.deleteMachineModalVisible) + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - callback: (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteMachine()) - } - dispatch(closeDeleteMachineModal()) - }, - } -} - -const DeleteMachineModal = connect(mapStateToProps, mapDispatchToProps)(DeleteMachineModalComponent) - export default DeleteMachineModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js index e7c4014d..93a38642 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js @@ -1,35 +1,27 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeDeleteProfileModal } from '../../actions/modals/profile' import { deleteCurrentUser } from '../../actions/users' import ConfirmationModal from '../../components/modals/ConfirmationModal' -const DeleteProfileModalComponent = ({ visible, callback }) => ( - -) +const DeleteProfileModal = () => { + const visible = useSelector((state) => state.modals.deleteProfileModalVisible) -const mapStateToProps = (state) => { - return { - visible: state.modals.deleteProfileModalVisible, + const dispatch = useDispatch() + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteCurrentUser()) + } + dispatch(closeDeleteProfileModal()) } + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - callback: (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteCurrentUser()) - } - dispatch(closeDeleteProfileModal()) - }, - } -} - -const DeleteProfileModal = connect(mapStateToProps, mapDispatchToProps)(DeleteProfileModalComponent) - export default DeleteProfileModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js index 0cb22a7e..ca76fd04 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js @@ -1,35 +1,27 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeDeleteRackModal } from '../../actions/modals/topology' import { deleteRack } from '../../actions/topology/rack' import ConfirmationModal from '../../components/modals/ConfirmationModal' -const DeleteRackModalComponent = ({ visible, callback }) => ( - -) - -const mapStateToProps = (state) => { - return { - visible: state.modals.deleteRackModalVisible, +const DeleteRackModal = (props) => { + const visible = useSelector((state) => state.modals.deleteRackModalVisible) + const dispatch = useDispatch() + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRack()) + } + dispatch(closeDeleteRackModal()) } + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - callback: (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRack()) - } - dispatch(closeDeleteRackModal()) - }, - } -} - -const DeleteRackModal = connect(mapStateToProps, mapDispatchToProps)(DeleteRackModalComponent) - export default DeleteRackModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js index 1f6eef92..9a7be6a6 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js @@ -1,35 +1,28 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeDeleteRoomModal } from '../../actions/modals/topology' import { deleteRoom } from '../../actions/topology/room' import ConfirmationModal from '../../components/modals/ConfirmationModal' -const DeleteRoomModalComponent = ({ visible, callback }) => ( - -) +const DeleteRoomModal = (props) => { + const visible = useSelector((state) => state.modals.deleteRoomModalVisible) -const mapStateToProps = (state) => { - return { - visible: state.modals.deleteRoomModalVisible, + const dispatch = useDispatch() + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRoom()) + } + dispatch(closeDeleteRoomModal()) } + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - callback: (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRoom()) - } - dispatch(closeDeleteRoomModal()) - }, - } -} - -const DeleteRoomModal = connect(mapStateToProps, mapDispatchToProps)(DeleteRoomModalComponent) - export default DeleteRoomModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js b/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js index 9128f449..edb57217 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js @@ -1,40 +1,37 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeEditRackNameModal } from '../../actions/modals/topology' import { editRackName } from '../../actions/topology/rack' import TextInputModal from '../../components/modals/TextInputModal' -const EditRackNameModalComponent = ({ visible, previousName, callback }) => ( - -) +const EditRackNameModal = (props) => { + const { visible, previousName } = useSelector((state) => { + return { + visible: state.modals.editRackNameModalVisible, + previousName: + state.interactionLevel.mode === 'RACK' + ? state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name + : '', + } + }) -const mapStateToProps = (state) => { - return { - visible: state.modals.editRackNameModalVisible, - previousName: - state.interactionLevel.mode === 'RACK' - ? state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name - : '', + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRackName(name)) + } + dispatch(closeEditRackNameModal()) } + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - callback: (name) => { - if (name) { - dispatch(editRackName(name)) - } - dispatch(closeEditRackNameModal()) - }, - } -} - -const EditRackNameModal = connect(mapStateToProps, mapDispatchToProps)(EditRackNameModalComponent) - export default EditRackNameModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js b/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js index 8032a5d1..a804c0b0 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js @@ -1,38 +1,31 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeEditRoomNameModal } from '../../actions/modals/topology' import { editRoomName } from '../../actions/topology/room' import TextInputModal from '../../components/modals/TextInputModal' -const EditRoomNameModalComponent = ({ visible, previousName, callback }) => ( - -) +const EditRoomNameModal = (props) => { + const visible = useSelector((state) => state.modals.editRoomNameModalVisible) + const previousName = useSelector((state) => + state.interactionLevel.mode === 'ROOM' ? state.objects.room[state.interactionLevel.roomId].name : '' + ) -const mapStateToProps = (state) => { - return { - visible: state.modals.editRoomNameModalVisible, - previousName: - state.interactionLevel.mode === 'ROOM' ? state.objects.room[state.interactionLevel.roomId].name : '', + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRoomName(name)) + } + dispatch(closeEditRoomNameModal()) } + return ( + + ) } - -const mapDispatchToProps = (dispatch) => { - return { - callback: (name) => { - if (name) { - dispatch(editRoomName(name)) - } - dispatch(closeEditRoomNameModal()) - }, - } -} - -const EditRoomNameModal = connect(mapStateToProps, mapDispatchToProps)(EditRoomNameModalComponent) - export default EditRoomNameModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js index 6cf12d8e..b364ed4c 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js @@ -1,30 +1,24 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { closeNewPortfolioModal } from '../../actions/modals/portfolios' import NewPortfolioModalComponent from '../../components/modals/custom-components/NewPortfolioModalComponent' import { addPortfolio } from '../../actions/portfolios' -import { closeNewPortfolioModal } from '../../actions/modals/portfolios' - -const mapStateToProps = (state) => { - return { - show: state.modals.newPortfolioModalVisible, - } -} -const mapDispatchToProps = (dispatch) => { - return { - callback: (name, targets) => { - if (name) { - dispatch( - addPortfolio({ - name, - targets, - }) - ) - } - dispatch(closeNewPortfolioModal()) - }, +const NewPortfolioModal = (props) => { + const show = useSelector((state) => state.modals.newPortfolioModalVisible) + const dispatch = useDispatch() + const callback = (name, targets) => { + if (name) { + dispatch( + addPortfolio({ + name, + targets, + }) + ) + } + dispatch(closeNewPortfolioModal()) } + return } -const NewPortfolioModal = connect(mapStateToProps, mapDispatchToProps)(NewPortfolioModalComponent) - export default NewPortfolioModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js index d306dc45..e63ba76b 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js @@ -1,30 +1,19 @@ import React from 'react' -import { connect } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { closeNewProjectModal } from '../../actions/modals/projects' import { addProject } from '../../actions/projects' import TextInputModal from '../../components/modals/TextInputModal' -const NewProjectModalComponent = ({ visible, callback }) => ( - -) - -const mapStateToProps = (state) => { - return { - visible: state.modals.newProjectModalVisible, +const NewProjectModal = (props) => { + const visible = useSelector((state) => state.modals.newProjectModalVisible) + const dispatch = useDispatch() + const callback = (text) => { + if (text) { + dispatch(addProject(text)) + } + dispatch(closeNewProjectModal()) } + return } -const mapDispatchToProps = (dispatch) => { - return { - callback: (text) => { - if (text) { - dispatch(addProject(text)) - } - dispatch(closeNewProjectModal()) - }, - } -} - -const NewProjectModal = connect(mapStateToProps, mapDispatchToProps)(NewProjectModalComponent) - export default NewProjectModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js index 7d774fa4..1de838e4 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js @@ -1,50 +1,48 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import NewScenarioModalComponent from '../../components/modals/custom-components/NewScenarioModalComponent' import { addScenario } from '../../actions/scenarios' import { closeNewScenarioModal } from '../../actions/modals/scenarios' -const mapStateToProps = (state) => { - let topologies = - state.currentProjectId !== '-1' - ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) - : [] - if (topologies.filter((t) => !t).length > 0) { - topologies = [] - } +const NewScenarioModal = (props) => { + const state = useSelector((state) => { + let topologies = + state.currentProjectId !== '-1' + ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) + : [] + if (topologies.filter((t) => !t).length > 0) { + topologies = [] + } - return { - show: state.modals.newScenarioModalVisible, - currentPortfolioId: state.currentPortfolioId, - currentPortfolioScenarioIds: - state.currentPortfolioId !== '-1' && state.objects.portfolio[state.currentPortfolioId] - ? state.objects.portfolio[state.currentPortfolioId].scenarioIds - : [], - traces: Object.values(state.objects.trace), - topologies, - schedulers: Object.values(state.objects.scheduler), - } -} + return { + show: state.modals.newScenarioModalVisible, + currentPortfolioId: state.currentPortfolioId, + currentPortfolioScenarioIds: + state.currentPortfolioId !== '-1' && state.objects.portfolio[state.currentPortfolioId] + ? state.objects.portfolio[state.currentPortfolioId].scenarioIds + : [], + traces: Object.values(state.objects.trace), + topologies, + schedulers: Object.values(state.objects.scheduler), + } + }) -const mapDispatchToProps = (dispatch) => { - return { - callback: (name, portfolioId, trace, topology, operational) => { - if (name) { - dispatch( - addScenario({ - portfolioId, - name, - trace, - topology, - operational, - }) - ) - } - - dispatch(closeNewScenarioModal()) - }, + const dispatch = useDispatch() + const callback = (name, portfolioId, trace, topology, operational) => { + if (name) { + dispatch( + addScenario({ + portfolioId, + name, + trace, + topology, + operational, + }) + ) + } + dispatch(closeNewScenarioModal()) } + return } -const NewScenarioModal = connect(mapStateToProps, mapDispatchToProps)(NewScenarioModalComponent) - export default NewScenarioModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js index 0acf6cf2..2f81706e 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js @@ -1,42 +1,48 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import NewTopologyModalComponent from '../../components/modals/custom-components/NewTopologyModalComponent' import { closeNewTopologyModal } from '../../actions/modals/topology' import { addTopology } from '../../actions/topologies' -const mapStateToProps = (state) => { - let topologies = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) - : [] - if (topologies.filter((t) => !t).length > 0) { - topologies = [] - } +const NewTopologyModal = () => { + const show = useSelector((state) => state.modals.changeTopologyModalVisible) + const topologies = useSelector((state) => { + let topologies = state.objects.project[state.currentProjectId] + ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) + : [] + if (topologies.filter((t) => !t).length > 0) { + topologies = [] + } - return { - show: state.modals.changeTopologyModalVisible, - topologies, - } -} + return topologies + }) -const mapDispatchToProps = (dispatch) => { - return { - onCreateTopology: (name) => { - if (name) { - dispatch(addTopology(name, undefined)) - } - dispatch(closeNewTopologyModal()) - }, - onDuplicateTopology: (name, id) => { - if (name) { - dispatch(addTopology(name, id)) - } - dispatch(closeNewTopologyModal()) - }, - onCancel: () => { - dispatch(closeNewTopologyModal()) - }, + const dispatch = useDispatch() + const onCreateTopology = (name) => { + if (name) { + dispatch(addTopology(name, undefined)) + } + dispatch(closeNewTopologyModal()) + } + const onDuplicateTopology = (name, id) => { + if (name) { + dispatch(addTopology(name, id)) + } + dispatch(closeNewTopologyModal()) + } + const onCancel = () => { + dispatch(closeNewTopologyModal()) } -} -const NewTopologyModal = connect(mapStateToProps, mapDispatchToProps)(NewTopologyModalComponent) + return ( + + ) +} export default NewTopologyModal diff --git a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js index 845d54e1..42a44345 100644 --- a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import AppNavbarComponent from '../../components/navigation/AppNavbarComponent' -const mapStateToProps = (state) => { - return { - project: state.currentProjectId !== '-1' ? state.objects.project[state.currentProjectId] : undefined, - } +const AppNavbarContainer = (props) => { + const project = useSelector((state) => + state.currentProjectId !== '-1' ? state.objects.project[state.currentProjectId] : undefined + ) + return } -const AppNavbarContainer = connect(mapStateToProps)(AppNavbarComponent) - export default AppNavbarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js index dfd6affe..26f95c55 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js @@ -1,19 +1,13 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { setAuthVisibilityFilter } from '../../actions/projects' import FilterButton from '../../components/projects/FilterButton' -const mapStateToProps = (state, ownProps) => { - return { - active: state.projectList.authVisibilityFilter === ownProps.filter, - } -} +const FilterLink = (props) => { + const active = useSelector((state) => state.projectList.authVisibilityFilter === props.filter) + const dispatch = useDispatch() -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onClick: () => dispatch(setAuthVisibilityFilter(ownProps.filter)), - } + return dispatch(setAuthVisibilityFilter(props.filter))} active={active} /> } -const FilterLink = connect(mapStateToProps, mapDispatchToProps)(FilterButton) - export default FilterLink diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js index ffd4a4a3..b8f6fef5 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openNewProjectModal } from '../../actions/modals/projects' import NewProjectButtonComponent from '../../components/projects/NewProjectButtonComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openNewProjectModal()), - } +const NewProjectButtonContainer = (props) => { + const dispatch = useDispatch() + return dispatch(openNewProjectModal())} /> } -const NewProjectButtonContainer = connect(undefined, mapDispatchToProps)(NewProjectButtonComponent) - export default NewProjectButtonContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js index 8bcbb7fd..a13034e9 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js @@ -1,20 +1,15 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { deleteProject } from '../../actions/projects' import ProjectActionButtons from '../../components/projects/ProjectActionButtons' -const mapStateToProps = (state, ownProps) => { - return { - projectId: ownProps.projectId, - } -} - -const mapDispatchToProps = (dispatch) => { - return { +const ProjectActions = (props) => { + const dispatch = useDispatch() + const actions = { onViewUsers: (id) => {}, // TODO implement user viewing onDelete: (id) => dispatch(deleteProject(id)), } + return } -const ProjectActions = connect(mapStateToProps, mapDispatchToProps)(ProjectActionButtons) - export default ProjectActions diff --git a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js index f0010540..b869775c 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js @@ -1,4 +1,5 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import ProjectList from '../../components/projects/ProjectAuthList' const getVisibleProjectAuths = (projectAuths, filter) => { @@ -14,19 +15,18 @@ const getVisibleProjectAuths = (projectAuths, filter) => { } } -const mapStateToProps = (state) => { - const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { - const authorization = state.objects.authorization[authorizationIds] - authorization.user = state.objects.user[authorization.userId] - authorization.project = state.objects.project[authorization.projectId] - return authorization - }) +const VisibleProjectAuthList = (props) => { + const authorizations = useSelector((state) => { + const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { + const authorization = state.objects.authorization[authorizationIds] + authorization.user = state.objects.user[authorization.userId] + authorization.project = state.objects.project[authorization.projectId] + return authorization + }) - return { - authorizations: getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter), - } + return getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter) + }) + return } -const VisibleProjectAuthList = connect(mapStateToProps)(ProjectList) - export default VisibleProjectAuthList diff --git a/opendc-web/opendc-web-ui/src/pages/App.js b/opendc-web/opendc-web-ui/src/pages/App.js index cbc805b8..03e21cc2 100644 --- a/opendc-web/opendc-web-ui/src/pages/App.js +++ b/opendc-web/opendc-web-ui/src/pages/App.js @@ -1,8 +1,8 @@ import PropTypes from 'prop-types' -import React from 'react' +import React, { useEffect } from 'react' import DocumentTitle from 'react-document-title' -import { connect } from 'react-redux' -import { ShortcutManager } from 'react-shortcuts' +import { HotKeys } from 'react-hotkeys' +import { useDispatch, useSelector } from 'react-redux' import { openPortfolioSucceeded } from '../actions/portfolios' import { openProjectSucceeded } from '../actions/projects' import ToolPanelComponent from '../components/app/map/controls/ToolPanelComponent' @@ -15,7 +15,6 @@ import DeleteRackModal from '../containers/modals/DeleteRackModal' import DeleteRoomModal from '../containers/modals/DeleteRoomModal' import EditRackNameModal from '../containers/modals/EditRackNameModal' import EditRoomNameModal from '../containers/modals/EditRoomNameModal' -import KeymapConfiguration from '../shortcuts/keymap' import NewTopologyModal from '../containers/modals/NewTopologyModal' import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' import ProjectSidebarContainer from '../containers/app/sidebars/project/ProjectSidebarContainer' @@ -23,115 +22,82 @@ import { openScenarioSucceeded } from '../actions/scenarios' import NewPortfolioModal from '../containers/modals/NewPortfolioModal' import NewScenarioModal from '../containers/modals/NewScenarioModal' import PortfolioResultsContainer from '../containers/app/results/PortfolioResultsContainer' +import KeymapConfiguration from '../shortcuts/keymap' -const shortcutManager = new ShortcutManager(KeymapConfiguration) - -class AppComponent extends React.Component { - static propTypes = { - projectId: PropTypes.string.isRequired, - portfolioId: PropTypes.string, - scenarioId: PropTypes.string, - projectName: PropTypes.string, - } - static childContextTypes = { - shortcuts: PropTypes.object.isRequired, - } +const App = ({ projectId, portfolioId, scenarioId }) => { + const projectName = useSelector( + (state) => + state.currentProjectId !== '-1' && + state.objects.project[state.currentProjectId] && + state.objects.project[state.currentProjectId].name + ) + const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') - componentDidMount() { - if (this.props.scenarioId) { - this.props.openScenarioSucceeded(this.props.projectId, this.props.portfolioId, this.props.scenarioId) - } else if (this.props.portfolioId) { - this.props.openPortfolioSucceeded(this.props.projectId, this.props.portfolioId) + const dispatch = useDispatch() + useEffect(() => { + if (scenarioId) { + dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)) + } else if (portfolioId) { + dispatch(openPortfolioSucceeded(projectId, portfolioId)) } else { - this.props.openProjectSucceeded(this.props.projectId) + dispatch(openProjectSucceeded(projectId)) } - } + }, [projectId, portfolioId, scenarioId, dispatch]) - getChildContext() { - return { - shortcuts: shortcutManager, - } - } + const constructionElements = topologyIsLoading ? ( +
+ +
+ ) : ( +
+ + + + + +
+ ) - render() { - const constructionElements = this.props.topologyIsLoading ? ( -
- -
- ) : ( -
- - - - - + const portfolioElements = ( +
+ +
+
- ) +
+ ) - const portfolioElements = ( -
- -
- -
+ const scenarioElements = ( +
+ +
+

Scenario loading

- ) +
+ ) - const scenarioElements = ( -
- -
-

Scenario loading

-
-
- ) - - return ( - -
- - {this.props.scenarioId - ? scenarioElements - : this.props.portfolioId - ? portfolioElements - : constructionElements} - - - - - - - - -
-
- ) - } + return ( + + + + {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} + + + + + + + + + + + ) } -const mapStateToProps = (state) => { - let projectName = undefined - if (state.currentProjectId !== '-1' && state.objects.project[state.currentProjectId]) { - projectName = state.objects.project[state.currentProjectId].name - } - - return { - topologyIsLoading: state.currentTopologyId === '-1', - projectName, - } +App.propTypes = { + projectId: PropTypes.string.isRequired, + portfolioId: PropTypes.string, + scenarioId: PropTypes.string, } -const mapDispatchToProps = (dispatch) => { - return { - openProjectSucceeded: (projectId) => dispatch(openProjectSucceeded(projectId)), - openPortfolioSucceeded: (projectId, portfolioId) => dispatch(openPortfolioSucceeded(projectId, portfolioId)), - openScenarioSucceeded: (projectId, portfolioId, scenarioId) => - dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)), - } -} - -const App = connect(mapStateToProps, mapDispatchToProps)(AppComponent) - export default App diff --git a/opendc-web/opendc-web-ui/src/pages/Profile.js b/opendc-web/opendc-web-ui/src/pages/Profile.js index 0d94b519..1e817037 100644 --- a/opendc-web/opendc-web-ui/src/pages/Profile.js +++ b/opendc-web/opendc-web-ui/src/pages/Profile.js @@ -1,35 +1,36 @@ import React from 'react' import DocumentTitle from 'react-document-title' -import { connect } from 'react-redux' +import { useDispatch } from 'react-redux' import { openDeleteProfileModal } from '../actions/modals/profile' import DeleteProfileModal from '../containers/modals/DeleteProfileModal' import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' -const ProfileContainer = ({ onDelete }) => ( - -
- -
- -

- This does not delete your Google account, but simply disconnects it from the OpenDC platform and - deletes any project info that is associated with you (projects you own and any authorizations you - may have on other projects). -

-
- -
-
-) +const Profile = () => { + const dispatch = useDispatch() + const onDelete = () => dispatch(openDeleteProfileModal()) -const mapDispatchToProps = (dispatch) => { - return { - onDelete: () => dispatch(openDeleteProfileModal()), - } + return ( + +
+ +
+ +

+ This does not delete your Google account, but simply disconnects it from the OpenDC platform and + deletes any project info that is associated with you (projects you own and any authorizations + you may have on other projects). +

+
+ +
+
+ ) } -const Profile = connect(undefined, mapDispatchToProps)(ProfileContainer) - export default Profile diff --git a/opendc-web/opendc-web-ui/src/pages/Projects.js b/opendc-web/opendc-web-ui/src/pages/Projects.js index bb54aaa5..f759073f 100644 --- a/opendc-web/opendc-web-ui/src/pages/Projects.js +++ b/opendc-web/opendc-web-ui/src/pages/Projects.js @@ -1,7 +1,6 @@ -import React from 'react' +import React, { useEffect } from 'react' import DocumentTitle from 'react-document-title' -import { connect } from 'react-redux' -import { openNewProjectModal } from '../actions/modals/projects' +import { useDispatch } from 'react-redux' import { fetchAuthorizationsOfCurrentUser } from '../actions/users' import ProjectFilterPanel from '../components/projects/FilterPanel' import NewProjectModal from '../containers/modals/NewProjectModal' @@ -9,35 +8,24 @@ import NewProjectButtonContainer from '../containers/projects/NewProjectButtonCo import VisibleProjectList from '../containers/projects/VisibleProjectAuthList' import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' -class ProjectsContainer extends React.Component { - componentDidMount() { - this.props.fetchAuthorizationsOfCurrentUser() - } +function Projects() { + const dispatch = useDispatch() - render() { - return ( - -
- -
- - - -
- -
-
- ) - } -} + useEffect(() => dispatch(fetchAuthorizationsOfCurrentUser())) -const mapDispatchToProps = (dispatch) => { - return { - fetchAuthorizationsOfCurrentUser: () => dispatch(fetchAuthorizationsOfCurrentUser()), - openNewProjectModal: () => dispatch(openNewProjectModal()), - } + return ( + +
+ +
+ + + +
+ +
+
+ ) } -const Projects = connect(undefined, mapDispatchToProps)(ProjectsContainer) - export default Projects diff --git a/opendc-web/opendc-web-ui/src/shortcuts/keymap.js b/opendc-web/opendc-web-ui/src/shortcuts/keymap.js index 797340d7..8260ace2 100644 --- a/opendc-web/opendc-web-ui/src/shortcuts/keymap.js +++ b/opendc-web/opendc-web-ui/src/shortcuts/keymap.js @@ -1,10 +1,8 @@ const KeymapConfiguration = { - MAP: { - MOVE_LEFT: ['a', 'left'], - MOVE_RIGHT: ['d', 'right'], - MOVE_UP: ['w', 'up'], - MOVE_DOWN: ['s', 'down'], - }, + MOVE_LEFT: ['a', 'left'], + MOVE_RIGHT: ['d', 'right'], + MOVE_UP: ['w', 'up'], + MOVE_DOWN: ['s', 'down'], } export default KeymapConfiguration diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 10f974f1..0cdb4358 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -3162,11 +3162,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -combokeys@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/combokeys/-/combokeys-3.0.1.tgz#fc8ca5c3f5f2d2b03a458544cb88b14ab5f53f86" - integrity sha512-5nAfaLZ3oO3kA+/xdoL7t197UJTz2WWidyH3BBeU6hqHtvyFERICd0y3DQFrQkJFTKBrtUDck/xCLLoFpnjaCw== - commander@^2.11.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -4582,11 +4577,6 @@ eventemitter3@^4.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== -events@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= - events@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" @@ -5814,7 +5804,7 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" -invariant@^2.1.0, invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -6801,11 +6791,6 @@ jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: array-includes "^3.1.1" object.assign "^4.1.0" -just-reduce-object@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/just-reduce-object/-/just-reduce-object-1.1.0.tgz#d29d172264f8511c74462de30d72d5838b6967e6" - integrity sha512-nGyg7N9FEZsyrGQNilkyVLxKPsf96iel5v0DrozQ19ML+96HntyS/53bOP68iK/kZUGvsL3FKygV8nQYYhgTFw== - killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -8258,11 +8243,6 @@ pkg-up@3.1.0, pkg-up@^3.1.0: dependencies: find-up "^3.0.0" -platform@^1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444" - integrity sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q== - please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -9274,6 +9254,13 @@ react-google-login@~5.1.14: "@types/react" "*" prop-types "^15.6.0" +react-hotkeys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0.tgz#a7719c7340cbba888b0e9184f806a9ec0ac2c53f" + integrity sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q== + dependencies: + prop-types "^15.6.1" + react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -9425,18 +9412,6 @@ react-scripts@~3.4.1: optionalDependencies: fsevents "2.1.2" -react-shortcuts@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/react-shortcuts/-/react-shortcuts-2.1.0.tgz#e1ac50be4f847b96a473ce0ad877edadc5067ec6" - integrity sha512-yETQgoy/KRCOPjdlGSnfTjyVHwJYsFoHtVmuLzJABYBAnilpm1M14DhDavuAAMElbaQlXunOwKjh0Oq3I6Vt0A== - dependencies: - combokeys "^3.0.1" - events "^1.0.2" - invariant "^2.1.0" - just-reduce-object "^1.0.3" - platform "^1.3.0" - prop-types "^15.5.8" - react-side-effect@^1.0.2: version "1.2.0" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.2.0.tgz#0e940c78faba0c73b9b0eba9cd3dda8dfb7e7dae" -- cgit v1.2.3 From 00c8d0086631a249f7d9dcee022e013bbc683616 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 28 Oct 2020 16:42:43 +0100 Subject: ui: Do not prevent default on mouse scroll This change removes the prevent default from the mouse scroll since Chrome does not allow it anymore. --- opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js | 1 - 1 file changed, 1 deletion(-) diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js index 60bf3104..7ca10792 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js @@ -46,7 +46,6 @@ class MapStageComponent extends React.Component { } updateScale(e) { - e.preventDefault() this.props.zoomInOnPosition(e.deltaY < 0, this.state.mouseX, this.state.mouseY) } -- cgit v1.2.3 From 4d4fb1bb19c045e78c74e57816ebee251e1d7d08 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 28 Oct 2020 23:41:16 +0100 Subject: ui: Fix undefined project in NewScenarioModal --- .../src/containers/modals/NewScenarioModal.js | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js index 1de838e4..b588b4bc 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js @@ -5,15 +5,22 @@ import { addScenario } from '../../actions/scenarios' import { closeNewScenarioModal } from '../../actions/modals/scenarios' const NewScenarioModal = (props) => { - const state = useSelector((state) => { - let topologies = - state.currentProjectId !== '-1' - ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) - : [] + const topologies = useSelector(({ currentProjectId, objects }) => { + console.log(currentProjectId, objects) + + if (currentProjectId === '-1' || !objects.project[currentProjectId]) { + return [] + } + + const topologies = objects.project[currentProjectId].topologyIds.map((t) => objects.topology[t]) + if (topologies.filter((t) => !t).length > 0) { - topologies = [] + return [] } + return topologies + }) + const state = useSelector((state) => { return { show: state.modals.newScenarioModalVisible, currentPortfolioId: state.currentPortfolioId, @@ -22,7 +29,6 @@ const NewScenarioModal = (props) => { ? state.objects.portfolio[state.currentPortfolioId].scenarioIds : [], traces: Object.values(state.objects.trace), - topologies, schedulers: Object.values(state.objects.scheduler), } }) @@ -42,7 +48,8 @@ const NewScenarioModal = (props) => { } dispatch(closeNewScenarioModal()) } - return + + return } export default NewScenarioModal -- cgit v1.2.3 From 6e6f14db8986f5de6491b51117de0e1b0438b341 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 29 Oct 2020 00:53:52 +0100 Subject: ui: Adapt home components to Reactstrap --- .../src/components/home/ContactSection.js | 44 +++++++++++----------- .../src/components/home/ContentSection.js | 13 ++++--- .../src/components/home/IntroSection.js | 21 ++++++----- .../src/components/home/ScreenshotSection.js | 13 +------ .../src/components/home/StakeholderSection.js | 18 ++++++--- .../src/components/home/TechnologiesSection.js | 21 ++++++----- 6 files changed, 66 insertions(+), 64 deletions(-) diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js index d5c6e55f..d25a1bc4 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js @@ -1,42 +1,44 @@ import React from 'react' import FontAwesome from 'react-fontawesome' -import './ContactSection.sass' +import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' +import './ContactSection.sass' + const ContactSection = () => ( - -
-
+ + + - -
-
- TU Delft -
-
-
-
+ + + + + TU Delft + + + + A project by the   @Large Research Group . -
-
-
-
+ + + +
Disclaimer: @@ -47,8 +49,8 @@ const ContactSection = () => ( license ). Sorry for the inconvenience. -
-
+ +
) diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js index 9d4832d9..3a8960d9 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js @@ -1,15 +1,16 @@ +import React from 'react' import classNames from 'classnames' +import { Container } from 'reactstrap' import PropTypes from 'prop-types' -import React from 'react' import './ContentSection.sass' -const ContentSection = ({ name, title, children }) => ( -
-
+const ContentSection = ({ name, title, children, className }) => ( +
+

{title}

{children} -
-
+ + ) ContentSection.propTypes = { diff --git a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js index a799272a..bc6ee83b 100644 --- a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js @@ -1,18 +1,19 @@ import React from 'react' +import { Container, Row, Col } from 'reactstrap' const IntroSection = () => (
-
-
-
+ + +

The datacenter (DC) industry...

  • Is worth over $15 bn, and growing
  • Has many hard-to-grasp concepts
  • Needs to become accessible to many
-
-
+ + ( Image source

-
-
+ +

OpenDC provides...

  • Collaborative online DC modeling
  • Diverse and effective DC simulation
  • Exploratory DC performance feedback
-
-
-
+ + +
) diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js index 263590d5..33aab17f 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js @@ -1,4 +1,3 @@ -import classNames from 'classnames' import React from 'react' import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' @@ -7,20 +6,12 @@ import './ScreenshotSection.sass' const ScreenshotSection = ({ name, title, imageUrl, caption, imageIsRight, children }) => ( - + {children} {caption} - {caption} +
{caption}
diff --git a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js index e5ed9683..1624b4d2 100644 --- a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js @@ -1,29 +1,35 @@ import React from 'react' +import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' const Stakeholder = ({ name, title, subtitle }) => ( -
- +

{title}

{subtitle}

-
+ ) const StakeholderSection = () => ( -
+ -
+
) diff --git a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js index c6013c71..efd77edf 100644 --- a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js @@ -1,39 +1,40 @@ import React from 'react' import FontAwesome from 'react-fontawesome' +import { ListGroup, ListGroupItem } from 'reactstrap' import ContentSection from './ContentSection' const TechnologiesSection = () => ( -
    -
  • + + Browser JavaScript, React, Redux, Konva -
  • -
  • + + Server Python, Flask, FlaskSocketIO, OpenAPI -
  • -
  • + + Database MongoDB -
  • -
  • + + Simulator Kotlin -
  • -
+ +
) -- cgit v1.2.3 From c2c5dfe0119546935118ce5ae1803bf87f0b787c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 10 May 2021 17:31:43 +0200 Subject: ui: Update React dependencies This change updates the React dependencies to version 17, in order to keep up to date with React. --- opendc-web/opendc-web-ui/package.json | 13 +- opendc-web/opendc-web-ui/src/pages/App.js | 30 +- opendc-web/opendc-web-ui/src/pages/Home.js | 4 +- opendc-web/opendc-web-ui/src/pages/NotFound.js | 11 +- opendc-web/opendc-web-ui/src/pages/Profile.js | 35 +- opendc-web/opendc-web-ui/src/pages/Projects.js | 21 +- opendc-web/opendc-web-ui/src/util/hooks.js | 29 + opendc-web/opendc-web-ui/yarn.lock | 9147 +++++++++++++----------- 8 files changed, 4915 insertions(+), 4375 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/util/hooks.js diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 025f9584..d27a4756 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -24,23 +24,22 @@ "bootstrap": "4.5.3", "classnames": "~2.2.5", "husky": "~4.2.5", - "konva": "~6.0.0", + "konva": "~7.2.5", "lint-staged": "~10.2.2", "mathjs": "~7.1.0", "prettier": "~2.0.5", "prop-types": "~15.7.2", - "react": "~16.13.1", - "react-document-title": "~2.0.3", - "react-dom": "~16.13.1", + "react": "~17.0.2", + "react-dom": "~17.0.2", "react-fontawesome": "~1.7.1", "react-google-login": "~5.1.14", "react-hotkeys": "^2.0.0", - "react-konva": "~16.13.0-2", + "react-konva": "~17.0.2-0", "react-redux": "~7.2.0", "react-router-dom": "~5.1.2", - "react-scripts": "~3.4.1", + "react-scripts": "~4.0.3", "reactstrap": "^8.6.0", - "recharts": "~1.8.5", + "recharts": "~2.0.9", "redux": "~4.0.5", "redux-localstorage": "~0.4.1", "redux-logger": "~3.0.6", diff --git a/opendc-web/opendc-web-ui/src/pages/App.js b/opendc-web/opendc-web-ui/src/pages/App.js index 03e21cc2..ea62e8dc 100644 --- a/opendc-web/opendc-web-ui/src/pages/App.js +++ b/opendc-web/opendc-web-ui/src/pages/App.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types' import React, { useEffect } from 'react' -import DocumentTitle from 'react-document-title' import { HotKeys } from 'react-hotkeys' import { useDispatch, useSelector } from 'react-redux' import { openPortfolioSucceeded } from '../actions/portfolios' @@ -23,6 +22,7 @@ import NewPortfolioModal from '../containers/modals/NewPortfolioModal' import NewScenarioModal from '../containers/modals/NewScenarioModal' import PortfolioResultsContainer from '../containers/app/results/PortfolioResultsContainer' import KeymapConfiguration from '../shortcuts/keymap' +import { useDocumentTitle } from '../util/hooks' const App = ({ projectId, portfolioId, scenarioId }) => { const projectName = useSelector( @@ -76,21 +76,21 @@ const App = ({ projectId, portfolioId, scenarioId }) => {
) + useDocumentTitle(projectName ? projectName + ' - OpenDC' : 'Simulation - OpenDC') + return ( - - - - {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} - - - - - - - - - - + + + {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} + + + + + + + + + ) } diff --git a/opendc-web/opendc-web-ui/src/pages/Home.js b/opendc-web/opendc-web-ui/src/pages/Home.js index 6fc940c0..fb383426 100644 --- a/opendc-web/opendc-web-ui/src/pages/Home.js +++ b/opendc-web/opendc-web-ui/src/pages/Home.js @@ -1,5 +1,4 @@ import React from 'react' -import DocumentTitle from 'react-document-title' import ContactSection from '../components/home/ContactSection' import IntroSection from '../components/home/IntroSection' import JumbotronHeader from '../components/home/JumbotronHeader' @@ -10,8 +9,10 @@ import TeamSection from '../components/home/TeamSection' import TechnologiesSection from '../components/home/TechnologiesSection' import HomeNavbar from '../components/navigation/HomeNavbar' import './Home.sass' +import { useDocumentTitle } from '../util/hooks' function Home() { + useDocumentTitle('OpenDC') return (
@@ -24,7 +25,6 @@ function Home() { -
) diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.js b/opendc-web/opendc-web-ui/src/pages/NotFound.js index 72be7342..b933ffa5 100644 --- a/opendc-web/opendc-web-ui/src/pages/NotFound.js +++ b/opendc-web/opendc-web-ui/src/pages/NotFound.js @@ -1,14 +1,15 @@ import React from 'react' -import DocumentTitle from 'react-document-title' import TerminalWindow from '../components/not-found/TerminalWindow' import './NotFound.sass' +import { useDocumentTitle } from '../util/hooks' -const NotFound = () => ( - +const NotFound = () => { + useDocumentTitle('Page Not Found - OpenDC') + return (
-
-) + ) +} export default NotFound diff --git a/opendc-web/opendc-web-ui/src/pages/Profile.js b/opendc-web/opendc-web-ui/src/pages/Profile.js index 1e817037..ea781686 100644 --- a/opendc-web/opendc-web-ui/src/pages/Profile.js +++ b/opendc-web/opendc-web-ui/src/pages/Profile.js @@ -1,35 +1,30 @@ import React from 'react' -import DocumentTitle from 'react-document-title' import { useDispatch } from 'react-redux' import { openDeleteProfileModal } from '../actions/modals/profile' import DeleteProfileModal from '../containers/modals/DeleteProfileModal' import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' +import { useDocumentTitle } from '../util/hooks' const Profile = () => { const dispatch = useDispatch() const onDelete = () => dispatch(openDeleteProfileModal()) + useDocumentTitle('My Profile - OpenDC') return ( - -
- -
- -

- This does not delete your Google account, but simply disconnects it from the OpenDC platform and - deletes any project info that is associated with you (projects you own and any authorizations - you may have on other projects). -

-
- +
+ +
+ +

+ This does not delete your Google account, but simply disconnects it from the OpenDC platform and + deletes any project info that is associated with you (projects you own and any authorizations you + may have on other projects). +

- + +
) } diff --git a/opendc-web/opendc-web-ui/src/pages/Projects.js b/opendc-web/opendc-web-ui/src/pages/Projects.js index f759073f..5e642a03 100644 --- a/opendc-web/opendc-web-ui/src/pages/Projects.js +++ b/opendc-web/opendc-web-ui/src/pages/Projects.js @@ -1,5 +1,4 @@ import React, { useEffect } from 'react' -import DocumentTitle from 'react-document-title' import { useDispatch } from 'react-redux' import { fetchAuthorizationsOfCurrentUser } from '../actions/users' import ProjectFilterPanel from '../components/projects/FilterPanel' @@ -7,24 +6,24 @@ import NewProjectModal from '../containers/modals/NewProjectModal' import NewProjectButtonContainer from '../containers/projects/NewProjectButtonContainer' import VisibleProjectList from '../containers/projects/VisibleProjectAuthList' import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' +import { useDocumentTitle } from '../util/hooks' function Projects() { const dispatch = useDispatch() useEffect(() => dispatch(fetchAuthorizationsOfCurrentUser())) + useDocumentTitle('My Projects - OpenDC') return ( - -
- -
- - - -
- +
+ +
+ + +
- + +
) } diff --git a/opendc-web/opendc-web-ui/src/util/hooks.js b/opendc-web/opendc-web-ui/src/util/hooks.js new file mode 100644 index 00000000..7780a778 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/util/hooks.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useEffect } from 'react' + +export function useDocumentTitle(title) { + useEffect(() => { + document.title = title + }, [title]) +} diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 0cdb4358..c29cea71 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -2,1018 +2,1106 @@ # yarn lockfile v1 -"@babel/code-frame@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" - integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== - dependencies: - "@babel/highlight" "^7.8.3" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.3", "@babel/code-frame@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.3.tgz#324bcfd8d35cd3d47dae18cde63d752086435e9a" - integrity sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg== - dependencies: - "@babel/highlight" "^7.10.3" - -"@babel/compat-data@^7.10.1", "@babel/compat-data@^7.10.3", "@babel/compat-data@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.3.tgz#9af3e033f36e8e2d6e47570db91e64a846f5d382" - integrity sha512-BDIfJ9uNZuI0LajPfoYV28lX8kyCPMHY6uY4WH1lJdcicmAfxCK5ASzaeV0D/wsUaRH/cLk+amuxtC37sZ8TUg== - dependencies: - browserslist "^4.12.0" - invariant "^2.2.4" - semver "^5.5.0" - -"@babel/core@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" - integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.9.0" - "@babel/helper-module-transforms" "^7.9.0" - "@babel/helpers" "^7.9.0" - "@babel/parser" "^7.9.0" - "@babel/template" "^7.8.6" - "@babel/traverse" "^7.9.0" - "@babel/types" "^7.9.0" +"@babel/code-frame@7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.5.5": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" + integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== + +"@babel/core@7.12.3": + version "7.12.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" + integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.12.1" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.1" + "@babel/parser" "^7.12.3" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" json5 "^2.1.2" - lodash "^4.17.13" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.4.5": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.3.tgz#73b0e8ddeec1e3fdd7a2de587a60e17c440ec77e" - integrity sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w== - dependencies: - "@babel/code-frame" "^7.10.3" - "@babel/generator" "^7.10.3" - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helpers" "^7.10.1" - "@babel/parser" "^7.10.3" - "@babel/template" "^7.10.3" - "@babel/traverse" "^7.10.3" - "@babel/types" "^7.10.3" +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5", "@babel/core@^7.8.4": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88" + integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helpers" "^7.14.0" + "@babel/parser" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" + gensync "^1.0.0-beta.2" json5 "^2.1.2" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" + semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.10.3", "@babel/generator@^7.4.0", "@babel/generator@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.3.tgz#32b9a0d963a71d7a54f5f6c15659c3dbc2a523a5" - integrity sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA== +"@babel/generator@^7.12.1", "@babel/generator@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" + integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== dependencies: - "@babel/types" "^7.10.3" + "@babel/types" "^7.14.1" jsesc "^2.5.1" - lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz#f6d08acc6f70bbd59b436262553fb2e259a1a268" - integrity sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw== +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.12.13" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.3.tgz#4e9012d6701bef0030348d7f9c808209bd3e8687" - integrity sha512-lo4XXRnBlU6eRM92FkiZxpo1xFLmv3VsPFk61zJKMm7XYJfwqXHsYJTY6agoc4a3L8QPw1HqWehO18coZgbT6A== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/helper-explode-assignable-expression" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-builder-react-jsx-experimental@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz#9a7d58ad184d3ac3bafb1a452cec2bad7e4a0bc8" - integrity sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ== +"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" + integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-module-imports" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/compat-data" "^7.13.15" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" -"@babel/helper-builder-react-jsx@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.3.tgz#62c4b7bb381153a0a5f8d83189b94b9fb5384fc5" - integrity sha512-vkxmuFvmovtqTZknyMGj9+uQAZzz5Z9mrbnkJnPkaYGfKTaSsYcjQdXP0lgrWLVh8wU6bCjOmXOpx+kqUi+S5Q== +"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c" + integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/types" "^7.10.3" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" -"@babel/helper-compilation-targets@^7.10.2", "@babel/helper-compilation-targets@^7.8.7": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz#a17d9723b6e2c750299d2a14d4637c76936d8285" - integrity sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA== +"@babel/helper-create-regexp-features-plugin@^7.12.13": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" + integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== dependencies: - "@babel/compat-data" "^7.10.1" - browserslist "^4.12.0" - invariant "^2.2.4" - levenary "^1.1.1" - semver "^5.5.0" + "@babel/helper-annotate-as-pure" "^7.12.13" + regexpu-core "^4.7.1" -"@babel/helper-create-class-features-plugin@^7.10.1", "@babel/helper-create-class-features-plugin@^7.10.3", "@babel/helper-create-class-features-plugin@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.3.tgz#2783daa6866822e3d5ed119163b50f0fc3ae4b35" - integrity sha512-iRT9VwqtdFmv7UheJWthGc/h2s7MqoweBF9RUj77NFZsg9VfISvBTum3k6coAhJ8RWv2tj3yUjA03HxPd0vfpQ== - dependencies: - "@babel/helper-function-name" "^7.10.3" - "@babel/helper-member-expression-to-functions" "^7.10.3" - "@babel/helper-optimise-call-expression" "^7.10.3" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" - -"@babel/helper-create-regexp-features-plugin@^7.10.1", "@babel/helper-create-regexp-features-plugin@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz#1b8feeab1594cbcfbf3ab5a3bbcabac0468efdbd" - integrity sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-regex" "^7.10.1" - regexpu-core "^4.7.0" - -"@babel/helper-define-map@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.3.tgz#d27120a5e57c84727b30944549b2dfeca62401a8" - integrity sha512-bxRzDi4Sin/k0drWCczppOhov1sBSdBvXJObM1NLHQzjhXhwRtn7aRWGvLJWCYbuu2qUk3EKs6Ci9C9ps8XokQ== - dependencies: - "@babel/helper-function-name" "^7.10.3" - "@babel/types" "^7.10.3" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.3.tgz#9dc14f0cfa2833ea830a9c8a1c742b6e7461b05e" - integrity sha512-0nKcR64XrOC3lsl+uhD15cwxPvaB6QKUDlD84OT9C3myRbhJqTMYir69/RWItUvHpharv0eJ/wk7fl34ONSwZw== - dependencies: - "@babel/traverse" "^7.10.3" - "@babel/types" "^7.10.3" - -"@babel/helper-function-name@^7.10.1", "@babel/helper-function-name@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz#79316cd75a9fa25ba9787ff54544307ed444f197" - integrity sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw== - dependencies: - "@babel/helper-get-function-arity" "^7.10.3" - "@babel/template" "^7.10.3" - "@babel/types" "^7.10.3" - -"@babel/helper-get-function-arity@^7.10.1", "@babel/helper-get-function-arity@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz#3a28f7b28ccc7719eacd9223b659fdf162e4c45e" - integrity sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg== - dependencies: - "@babel/types" "^7.10.3" - -"@babel/helper-hoist-variables@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.3.tgz#d554f52baf1657ffbd7e5137311abc993bb3f068" - integrity sha512-9JyafKoBt5h20Yv1+BXQMdcXXavozI1vt401KBiRc2qzUepbVnd7ogVNymY1xkQN9fekGwfxtotH2Yf5xsGzgg== - dependencies: - "@babel/types" "^7.10.3" - -"@babel/helper-member-expression-to-functions@^7.10.1", "@babel/helper-member-expression-to-functions@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz#bc3663ac81ac57c39148fef4c69bf48a77ba8dd6" - integrity sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw== - dependencies: - "@babel/types" "^7.10.3" - -"@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.10.3", "@babel/helper-module-imports@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz#766fa1d57608e53e5676f23ae498ec7a95e1b11a" - integrity sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w== - dependencies: - "@babel/types" "^7.10.3" - -"@babel/helper-module-transforms@^7.10.1", "@babel/helper-module-transforms@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz#24e2f08ee6832c60b157bb0936c86bef7210c622" - integrity sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg== - dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-simple-access" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.10.1", "@babel/helper-optimise-call-expression@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz#f53c4b6783093195b0f69330439908841660c530" - integrity sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg== - dependencies: - "@babel/types" "^7.10.3" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.10.3", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz#aac45cccf8bc1873b99a85f34bceef3beb5d3244" - integrity sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g== - -"@babel/helper-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.1.tgz#021cf1a7ba99822f993222a001cc3fec83255b96" - integrity sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g== - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.10.1", "@babel/helper-remap-async-to-generator@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.3.tgz#18564f8a6748be466970195b876e8bba3bccf442" - integrity sha512-sLB7666ARbJUGDO60ZormmhQOyqMX/shKBXZ7fy937s+3ID8gSrneMvKSSb+8xIM5V7Vn6uNVtOY1vIm26XLtA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-wrap-function" "^7.10.1" - "@babel/template" "^7.10.3" - "@babel/traverse" "^7.10.3" - "@babel/types" "^7.10.3" - -"@babel/helper-replace-supers@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz#ec6859d20c5d8087f6a2dc4e014db7228975f13d" - integrity sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" - -"@babel/helper-simple-access@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz#08fb7e22ace9eb8326f7e3920a1c2052f13d851e" - integrity sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw== - dependencies: - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" - -"@babel/helper-split-export-declaration@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f" - integrity sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g== - dependencies: - "@babel/types" "^7.10.1" - -"@babel/helper-validator-identifier@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz#60d9847f98c4cea1b279e005fdb7c28be5412d15" - integrity sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw== - -"@babel/helper-wrap-function@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9" - integrity sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ== - dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" - -"@babel/helpers@^7.10.1", "@babel/helpers@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.1.tgz#a6827b7cb975c9d9cef5fd61d919f60d8844a973" - integrity sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw== - dependencies: - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" - -"@babel/highlight@^7.10.3", "@babel/highlight@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.3.tgz#c633bb34adf07c5c13156692f5922c81ec53f28d" - integrity sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw== - dependencies: - "@babel/helper-validator-identifier" "^7.10.3" +"@babel/helper-define-polyfill-provider@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz#a640051772045fedaaecc6f0c6c69f02bdd34bf1" + integrity sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" + integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== + dependencies: + "@babel/types" "^7.13.0" + +"@babel/helper-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-hoist-variables@^7.13.0": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" + integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== + dependencies: + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" + +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" + integrity sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw== + dependencies: + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" + +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== + +"@babel/helper-remap-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" + integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-wrap-function" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" + integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.12" + +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + +"@babel/helper-wrap-function@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" + integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helpers@^7.12.1", "@babel/helpers@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" + integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== + dependencies: + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.10.3", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" - integrity sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.3", "@babel/parser@^7.14.0", "@babel/parser@^7.7.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" + integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== -"@babel/plugin-proposal-async-generator-functions@^7.10.3", "@babel/plugin-proposal-async-generator-functions@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.3.tgz#5a02453d46e5362e2073c7278beab2e53ad7d939" - integrity sha512-WUUWM7YTOudF4jZBAJIW9D7aViYC/Fn0Pln4RIHlQALyno3sXSjqmTA4Zy1TKC2D49RCR8Y/Pn4OIUtEypK3CA== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" + integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/helper-remap-async-to-generator" "^7.10.3" - "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" -"@babel/plugin-proposal-class-properties@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" - integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== +"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" + integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz#046bc7f6550bb08d9bd1d4f060f5f5a4f1087e01" - integrity sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw== +"@babel/plugin-proposal-class-properties@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" + integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-decorators@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz#2156860ab65c5abf068c3f67042184041066543e" - integrity sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-decorators" "^7.8.3" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-proposal-dynamic-import@^7.10.1", "@babel/plugin-proposal-dynamic-import@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz#e36979dc1dc3b73f6d6816fc4951da2363488ef0" - integrity sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA== +"@babel/plugin-proposal-class-static-block@^7.13.11": + version "7.13.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.13.11.tgz#6fcbba4a962702c17e5371a0c7b39afde186d703" + integrity sha512-fJTdFI4bfnMjvxJyNuaf8i9mVcZ0UhetaGEUHaHV9KEnibLugJkZAtXikR8KcYj+NYmI4DZMS8yQAyg+hvfSqg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-class-static-block" "^7.12.13" -"@babel/plugin-proposal-json-strings@^7.10.1", "@babel/plugin-proposal-json-strings@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz#b1e691ee24c651b5a5e32213222b2379734aff09" - integrity sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg== +"@babel/plugin-proposal-decorators@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz#59271439fed4145456c41067450543aee332d15f" + integrity sha512-knNIuusychgYN8fGJHONL0RbFxLGawhXOJNLBk75TniTsZZeA+wdkDuv6wp4lGwzQEKjZi6/WYtnb3udNPmQmQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.12.1" -"@babel/plugin-proposal-nullish-coalescing-operator@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" - integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== +"@babel/plugin-proposal-dynamic-import@^7.12.1", "@babel/plugin-proposal-dynamic-import@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" + integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz#02dca21673842ff2fe763ac253777f235e9bbf78" - integrity sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA== +"@babel/plugin-proposal-export-namespace-from@^7.12.1", "@babel/plugin-proposal-export-namespace-from@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" + integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" + integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" + integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" + integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-numeric-separator@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" - integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" + integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.10.1", "@babel/plugin-proposal-numeric-separator@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz#a9a38bc34f78bdfd981e791c27c6fdcec478c123" - integrity sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA== +"@babel/plugin-proposal-numeric-separator@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz#0e2c6774c4ce48be412119b4d693ac777f7685a6" + integrity sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-numeric-separator" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.10.3", "@babel/plugin-proposal-object-rest-spread@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.3.tgz#b8d0d22f70afa34ad84b7a200ff772f9b9fce474" - integrity sha512-ZZh5leCIlH9lni5bU/wB/UcjtcVLgR8gc+FAgW2OOY+m9h1II3ItTO1/cewNUcsIDZSYcSaz/rYVls+Fb0ExVQ== +"@babel/plugin-proposal-numeric-separator@^7.12.1", "@babel/plugin-proposal-numeric-separator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" + integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-optional-catch-binding@^7.10.1", "@babel/plugin-proposal-optional-catch-binding@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz#c9f86d99305f9fa531b568ff5ab8c964b8b223d2" - integrity sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" + integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/compat-data" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.13.0" -"@babel/plugin-proposal-optional-chaining@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" - integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1", "@babel/plugin-proposal-optional-catch-binding@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" + integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.10.3", "@babel/plugin-proposal-optional-chaining@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.3.tgz#9a726f94622b653c0a3a7a59cdce94730f526f7c" - integrity sha512-yyG3n9dJ1vZ6v5sfmIlMMZ8azQoqx/5/nZTSWX1td6L1H1bsjzA8TInDChpafCZiJkeOFzp/PtrfigAQXxI1Ng== +"@babel/plugin-proposal-optional-chaining@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz#cce122203fc8a32794296fc377c6dedaf4363797" + integrity sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-private-methods@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz#ed85e8058ab0fe309c3f448e5e1b73ca89cdb598" - integrity sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg== +"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" + integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" + integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-proposal-unicode-property-regex@^7.10.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz#dc04feb25e2dd70c12b05d680190e138fa2c0c6f" - integrity sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ== +"@babel/plugin-proposal-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636" + integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" -"@babel/plugin-syntax-async-generators@^7.8.0": +"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz#d5bc0645913df5b17ad7eda0fa2308330bde34c5" - integrity sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ== +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.1", "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c" + integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-decorators@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.1.tgz#16b869c4beafc9a442565147bda7ce0967bd4f13" - integrity sha512-a9OAbQhKOwSle1Vr0NJu/ISg1sPfdEkfRKWpgPuzhnWWzForou2gIeUIIwjAMHRekhhpJ7eulZlYs0H14Cbi+g== +"@babel/plugin-syntax-decorators@^7.12.1": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz#fac829bf3c7ef4a1bc916257b403e58c6bdaf648" + integrity sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-dynamic-import@^7.8.0": +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-flow@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.1.tgz#cd4bbca62fb402babacb174f64f8734310d742f0" - integrity sha512-b3pWVncLBYoPP60UOTc7NMlbtsHQ6ITim78KQejNHK6WJ2mzV5kCcg4mIWpasAfJEgwVTibwo2e+FU7UEIKQUg== +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-flow@^7.12.1": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz#5df9962503c0a9c918381c929d51d4d6949e7e86" + integrity sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-json-strings@^7.8.0": +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz#0ae371134a42b91d5418feb3c8c8d43e1565d2da" - integrity sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ== +"@babel/plugin-syntax-jsx@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz#044fb81ebad6698fe62c478875575bcbb9b70f15" + integrity sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.10.1", "@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz#25761ee7410bc8cf97327ba741ee94e4a61b7d99" - integrity sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg== +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": +"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0": +"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.10.1", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz#8b8733f8c57397b3eaa47ddba8841586dcaef362" - integrity sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ== +"@babel/plugin-syntax-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b" + integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-syntax-typescript@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.1.tgz#5e82bc27bb4202b93b949b029e699db536733810" - integrity sha512-X/d8glkrAtra7CaQGMiGs/OGa6XgUzqPcBXCIGFCpCqnfGlT0Wfbzo/B89xHhnInTaItPK8LALblVXcUOEh95Q== +"@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-arrow-functions@^7.10.1", "@babel/plugin-transform-arrow-functions@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz#cb5ee3a36f0863c06ead0b409b4cc43a889b295b" - integrity sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA== +"@babel/plugin-syntax-typescript@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" + integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-async-to-generator@^7.10.1", "@babel/plugin-transform-async-to-generator@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz#e5153eb1a3e028f79194ed8a7a4bf55f862b2062" - integrity sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg== +"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-remap-async-to-generator" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-block-scoped-functions@^7.10.1", "@babel/plugin-transform-block-scoped-functions@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz#146856e756d54b20fff14b819456b3e01820b85d" - integrity sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q== +"@babel/plugin-transform-async-to-generator@^7.12.1", "@babel/plugin-transform-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" + integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" -"@babel/plugin-transform-block-scoping@^7.10.1", "@babel/plugin-transform-block-scoping@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz#47092d89ca345811451cd0dc5d91605982705d5e" - integrity sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw== +"@babel/plugin-transform-block-scoped-functions@^7.12.1", "@babel/plugin-transform-block-scoped-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - lodash "^4.17.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-classes@^7.10.3", "@babel/plugin-transform-classes@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.3.tgz#8d9a656bc3d01f3ff69e1fccb354b0f9d72ac544" - integrity sha512-irEX0ChJLaZVC7FvvRoSIxJlmk0IczFLcwaRXUArBKYHCHbOhe57aG8q3uw/fJsoSXvZhjRX960hyeAGlVBXZw== +"@babel/plugin-transform-block-scoping@^7.12.1", "@babel/plugin-transform-block-scoping@^7.14.1": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz#ac1b3a8e3d8cbb31efc6b9be2f74eb9823b74ab2" + integrity sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-define-map" "^7.10.3" - "@babel/helper-function-name" "^7.10.3" - "@babel/helper-optimise-call-expression" "^7.10.3" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" + integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.10.3", "@babel/plugin-transform-computed-properties@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.3.tgz#d3aa6eef67cb967150f76faff20f0abbf553757b" - integrity sha512-GWzhaBOsdbjVFav96drOz7FzrcEW6AP5nax0gLIpstiFaI3LOb2tAg06TimaWU6YKOfUACK3FVrxPJ4GSc5TgA== +"@babel/plugin-transform-computed-properties@^7.12.1", "@babel/plugin-transform-computed-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-destructuring@^7.10.1", "@babel/plugin-transform-destructuring@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz#abd58e51337815ca3a22a336b85f62b998e71907" - integrity sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA== +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.13.17": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" + integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-dotall-regex@^7.10.1", "@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz#920b9fec2d78bb57ebb64a644d5c2ba67cc104ee" - integrity sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA== +"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-duplicate-keys@^7.10.1", "@babel/plugin-transform-duplicate-keys@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz#c900a793beb096bc9d4d0a9d0cde19518ffc83b9" - integrity sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA== +"@babel/plugin-transform-duplicate-keys@^7.12.1", "@babel/plugin-transform-duplicate-keys@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-exponentiation-operator@^7.10.1", "@babel/plugin-transform-exponentiation-operator@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz#279c3116756a60dd6e6f5e488ba7957db9c59eb3" - integrity sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA== +"@babel/plugin-transform-exponentiation-operator@^7.12.1", "@babel/plugin-transform-exponentiation-operator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-flow-strip-types@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz#8a3538aa40434e000b8f44a3c5c9ac7229bd2392" - integrity sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg== +"@babel/plugin-transform-flow-strip-types@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.1.tgz#8430decfa7eb2aea5414ed4a3fa6e1652b7d77c4" + integrity sha512-8hAtkmsQb36yMmEtk2JZ9JnVyDSnDOdlB+0nEGzIDLuK4yR3JcEjfuFPYkdEPSh8Id+rAMeBEn+X0iVEyho6Hg== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-flow" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-flow" "^7.12.1" -"@babel/plugin-transform-for-of@^7.10.1", "@babel/plugin-transform-for-of@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz#ff01119784eb0ee32258e8646157ba2501fcfda5" - integrity sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w== +"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-function-name@^7.10.1", "@babel/plugin-transform-function-name@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz#4ed46fd6e1d8fde2a2ec7b03c66d853d2c92427d" - integrity sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw== +"@babel/plugin-transform-function-name@^7.12.1", "@babel/plugin-transform-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-literals@^7.10.1", "@babel/plugin-transform-literals@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz#5794f8da82846b22e4e6631ea1658bce708eb46a" - integrity sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw== +"@babel/plugin-transform-literals@^7.12.1", "@babel/plugin-transform-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-member-expression-literals@^7.10.1", "@babel/plugin-transform-member-expression-literals@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz#90347cba31bca6f394b3f7bd95d2bbfd9fce2f39" - integrity sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA== +"@babel/plugin-transform-member-expression-literals@^7.12.1", "@babel/plugin-transform-member-expression-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-modules-amd@^7.10.1", "@babel/plugin-transform-modules-amd@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz#65950e8e05797ebd2fe532b96e19fc5482a1d52a" - integrity sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw== +"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz#589494b5b290ff76cf7f59c798011f6d77026553" + integrity sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.10.1", "@babel/plugin-transform-modules-commonjs@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz#d5ff4b4413ed97ffded99961056e1fb980fb9301" - integrity sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg== +"@babel/plugin-transform-modules-commonjs@^7.12.1", "@babel/plugin-transform-modules-commonjs@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" + integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-simple-access" "^7.10.1" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.13.12" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.10.3", "@babel/plugin-transform-modules-systemjs@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.3.tgz#004ae727b122b7b146b150d50cba5ffbff4ac56b" - integrity sha512-GWXWQMmE1GH4ALc7YXW56BTh/AlzvDWhUNn9ArFF0+Cz5G8esYlVbXfdyHa1xaD1j+GnBoCeoQNlwtZTVdiG/A== +"@babel/plugin-transform-modules-systemjs@^7.12.1", "@babel/plugin-transform-modules-systemjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" + integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== dependencies: - "@babel/helper-hoist-variables" "^7.10.3" - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-hoist-variables" "^7.13.0" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.10.1", "@babel/plugin-transform-modules-umd@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz#ea080911ffc6eb21840a5197a39ede4ee67b1595" - integrity sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA== +"@babel/plugin-transform-modules-umd@^7.12.1", "@babel/plugin-transform-modules-umd@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" + integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.10.3", "@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.3.tgz#a4f8444d1c5a46f35834a410285f2c901c007ca6" - integrity sha512-I3EH+RMFyVi8Iy/LekQm948Z4Lz4yKT7rK+vuCAeRm0kTa6Z5W7xuhRxDNJv0FPya/her6AUgrDITb70YHtTvA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1", "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" -"@babel/plugin-transform-new-target@^7.10.1", "@babel/plugin-transform-new-target@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz#6ee41a5e648da7632e22b6fb54012e87f612f324" - integrity sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw== +"@babel/plugin-transform-new-target@^7.12.1", "@babel/plugin-transform-new-target@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-object-super@^7.10.1", "@babel/plugin-transform-object-super@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz#2e3016b0adbf262983bf0d5121d676a5ed9c4fde" - integrity sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw== +"@babel/plugin-transform-object-super@^7.12.1", "@babel/plugin-transform-object-super@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.10.1", "@babel/plugin-transform-parameters@^7.8.7": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz#b25938a3c5fae0354144a720b07b32766f683ddd" - integrity sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg== +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" + integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== dependencies: - "@babel/helper-get-function-arity" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-property-literals@^7.10.1", "@babel/plugin-transform-property-literals@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz#cffc7315219230ed81dc53e4625bf86815b6050d" - integrity sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA== +"@babel/plugin-transform-property-literals@^7.12.1", "@babel/plugin-transform-property-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-constant-elements@^7.0.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.10.1.tgz#c7f117a54657cba3f9d32012e050fc89982df9e1" - integrity sha512-V4os6bkWt/jbrzfyVcZn2ZpuHZkvj3vyBU0U/dtS8SZuMS7Rfx5oknTrtfyXJ2/QZk8gX7Yls5Z921ItNpE30Q== +"@babel/plugin-transform-react-constant-elements@^7.12.1": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.13.13.tgz#0208b1d942bf939cd4f7aa5b255d42602aa4a920" + integrity sha512-SNJU53VM/SjQL0bZhyU+f4kJQz7bQQajnrZRSaU21hruG/NWY41AEM9AWXeXX90pYr/C2yAmTgI6yW3LlLrAUQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-react-display-name@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz#70ded987c91609f78353dd76d2fb2a0bb991e8e5" - integrity sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A== +"@babel/plugin-transform-react-display-name@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" + integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-display-name@^7.10.1", "@babel/plugin-transform-react-display-name@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.3.tgz#e3c246e1b4f3e52cc7633e237ad9194c0ec482e7" - integrity sha512-dOV44bnSW5KZ6kYF6xSHBth7TFiHHZReYXH/JH3XnFNV+soEL1F5d8JT7AJ3ZBncd19Qul7SN4YpBnyWOnQ8KA== +"@babel/plugin-transform-react-display-name@^7.12.1", "@babel/plugin-transform-react-display-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" + integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-jsx-development@^7.10.1", "@babel/plugin-transform-react-jsx-development@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz#1ac6300d8b28ef381ee48e6fec430cc38047b7f3" - integrity sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg== +"@babel/plugin-transform-react-jsx-development@^7.12.1", "@babel/plugin-transform-react-jsx-development@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz#f510c0fa7cd7234153539f9a362ced41a5ca1447" + integrity sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ== dependencies: - "@babel/helper-builder-react-jsx-experimental" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/plugin-transform-react-jsx" "^7.12.17" -"@babel/plugin-transform-react-jsx-self@^7.10.1", "@babel/plugin-transform-react-jsx-self@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz#22143e14388d72eb88649606bb9e46f421bc3821" - integrity sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA== +"@babel/plugin-transform-react-jsx-self@^7.12.1": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz#422d99d122d592acab9c35ea22a6cfd9bf189f60" + integrity sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-jsx-source@^7.10.1", "@babel/plugin-transform-react-jsx-source@^7.9.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz#30db3d4ee3cdebbb26a82a9703673714777a4273" - integrity sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA== +"@babel/plugin-transform-react-jsx-source@^7.12.1": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.13.tgz#051d76126bee5c9a6aa3ba37be2f6c1698856bcb" + integrity sha512-O5JJi6fyfih0WfDgIJXksSPhGP/G0fQpfxYy87sDc+1sFmsCS6wr3aAn+whbzkhbjtq4VMqLRaSzR6IsshIC0Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-jsx@^7.10.1", "@babel/plugin-transform-react-jsx@^7.9.1": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.3.tgz#c07ad86b7c159287c89b643f201f59536231048e" - integrity sha512-Y21E3rZmWICRJnvbGVmDLDZ8HfNDIwjGF3DXYHx1le0v0mIHCs0Gv5SavyW5Z/jgAHLaAoJPiwt+Dr7/zZKcOQ== +"@babel/plugin-transform-react-jsx@^7.12.1", "@babel/plugin-transform-react-jsx@^7.12.17", "@babel/plugin-transform-react-jsx@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz#1df5dfaf0f4b784b43e96da6f28d630e775f68b3" + integrity sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA== dependencies: - "@babel/helper-builder-react-jsx" "^7.10.3" - "@babel/helper-builder-react-jsx-experimental" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-jsx" "^7.12.13" + "@babel/types" "^7.13.12" -"@babel/plugin-transform-react-pure-annotations@^7.10.1": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.3.tgz#97840981673fcb0df2cc33fb25b56cc421f7deef" - integrity sha512-n/fWYGqvTl7OLZs/QcWaKMFdADPvC3V6jYuEOpPyvz97onsW9TXn196fHnHW1ZgkO20/rxLOgKnEtN1q9jkgqA== +"@babel/plugin-transform-react-pure-annotations@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" + integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.10.3", "@babel/plugin-transform-regenerator@^7.8.7": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.3.tgz#6ec680f140a5ceefd291c221cb7131f6d7e8cb6d" - integrity sha512-H5kNeW0u8mbk0qa1jVIVTeJJL6/TJ81ltD4oyPx0P499DhMJrTmmIFCmJ3QloGpQG8K9symccB7S7SJpCKLwtw== +"@babel/plugin-transform-regenerator@^7.12.1", "@babel/plugin-transform-regenerator@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" + integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.10.1", "@babel/plugin-transform-reserved-words@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz#0fc1027312b4d1c3276a57890c8ae3bcc0b64a86" - integrity sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ== +"@babel/plugin-transform-reserved-words@^7.12.1", "@babel/plugin-transform-reserved-words@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-runtime@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b" - integrity sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw== +"@babel/plugin-transform-runtime@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz#04b792057eb460389ff6a4198e377614ea1e7ba5" + integrity sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg== dependencies: - "@babel/helper-module-imports" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.10.1", "@babel/plugin-transform-shorthand-properties@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz#e8b54f238a1ccbae482c4dce946180ae7b3143f3" - integrity sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g== +"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-spread@^7.10.1", "@babel/plugin-transform-spread@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz#0c6d618a0c4461a274418460a28c9ccf5239a7c8" - integrity sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw== +"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.10.1", "@babel/plugin-transform-sticky-regex@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz#90fc89b7526228bed9842cff3588270a7a393b00" - integrity sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA== +"@babel/plugin-transform-sticky-regex@^7.12.1", "@babel/plugin-transform-sticky-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-regex" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-template-literals@^7.10.3", "@babel/plugin-transform-template-literals@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.3.tgz#69d39b3d44b31e7b4864173322565894ce939b25" - integrity sha512-yaBn9OpxQra/bk0/CaA4wr41O0/Whkg6nqjqApcinxM7pro51ojhX6fv1pimAnVjVfDy14K0ULoRL70CA9jWWA== +"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-typeof-symbol@^7.10.1", "@babel/plugin-transform-typeof-symbol@^7.8.4": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz#60c0239b69965d166b80a84de7315c1bc7e0bb0e" - integrity sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g== +"@babel/plugin-transform-typeof-symbol@^7.12.1", "@babel/plugin-transform-typeof-symbol@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-typescript@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.10.3.tgz#b3b35fb34ef0bd628b4b8329b0e5f985369201d4" - integrity sha512-qU9Lu7oQyh3PGMQncNjQm8RWkzw6LqsWZQlZPQMgrGt6s3YiBIaQ+3CQV/FA/icGS5XlSWZGwo/l8ErTyelS0Q== +"@babel/plugin-transform-typescript@^7.12.1": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" + integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.3" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/plugin-syntax-typescript" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-typescript" "^7.12.13" -"@babel/plugin-transform-unicode-escapes@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz#add0f8483dab60570d9e03cecef6c023aa8c9940" - integrity sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw== +"@babel/plugin-transform-unicode-escapes@^7.12.1", "@babel/plugin-transform-unicode-escapes@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-unicode-regex@^7.10.1", "@babel/plugin-transform-unicode-regex@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz#6b58f2aea7b68df37ac5025d9c88752443a6b43f" - integrity sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw== +"@babel/plugin-transform-unicode-regex@^7.12.1", "@babel/plugin-transform-unicode-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/preset-env@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8" - integrity sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ== - dependencies: - "@babel/compat-data" "^7.9.0" - "@babel/helper-compilation-targets" "^7.8.7" - "@babel/helper-module-imports" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-proposal-async-generator-functions" "^7.8.3" - "@babel/plugin-proposal-dynamic-import" "^7.8.3" - "@babel/plugin-proposal-json-strings" "^7.8.3" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-proposal-numeric-separator" "^7.8.3" - "@babel/plugin-proposal-object-rest-spread" "^7.9.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" - "@babel/plugin-proposal-optional-chaining" "^7.9.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" +"@babel/preset-env@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.1.tgz#9c7e5ca82a19efc865384bb4989148d2ee5d7ac2" + integrity sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg== + dependencies: + "@babel/compat-data" "^7.12.1" + "@babel/helper-compilation-targets" "^7.12.1" + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-option" "^7.12.1" + "@babel/plugin-proposal-async-generator-functions" "^7.12.1" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-dynamic-import" "^7.12.1" + "@babel/plugin-proposal-export-namespace-from" "^7.12.1" + "@babel/plugin-proposal-json-strings" "^7.12.1" + "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-numeric-separator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.1" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.12.1" "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - "@babel/plugin-transform-arrow-functions" "^7.8.3" - "@babel/plugin-transform-async-to-generator" "^7.8.3" - "@babel/plugin-transform-block-scoped-functions" "^7.8.3" - "@babel/plugin-transform-block-scoping" "^7.8.3" - "@babel/plugin-transform-classes" "^7.9.0" - "@babel/plugin-transform-computed-properties" "^7.8.3" - "@babel/plugin-transform-destructuring" "^7.8.3" - "@babel/plugin-transform-dotall-regex" "^7.8.3" - "@babel/plugin-transform-duplicate-keys" "^7.8.3" - "@babel/plugin-transform-exponentiation-operator" "^7.8.3" - "@babel/plugin-transform-for-of" "^7.9.0" - "@babel/plugin-transform-function-name" "^7.8.3" - "@babel/plugin-transform-literals" "^7.8.3" - "@babel/plugin-transform-member-expression-literals" "^7.8.3" - "@babel/plugin-transform-modules-amd" "^7.9.0" - "@babel/plugin-transform-modules-commonjs" "^7.9.0" - "@babel/plugin-transform-modules-systemjs" "^7.9.0" - "@babel/plugin-transform-modules-umd" "^7.9.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" - "@babel/plugin-transform-new-target" "^7.8.3" - "@babel/plugin-transform-object-super" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.8.7" - "@babel/plugin-transform-property-literals" "^7.8.3" - "@babel/plugin-transform-regenerator" "^7.8.7" - "@babel/plugin-transform-reserved-words" "^7.8.3" - "@babel/plugin-transform-shorthand-properties" "^7.8.3" - "@babel/plugin-transform-spread" "^7.8.3" - "@babel/plugin-transform-sticky-regex" "^7.8.3" - "@babel/plugin-transform-template-literals" "^7.8.3" - "@babel/plugin-transform-typeof-symbol" "^7.8.4" - "@babel/plugin-transform-unicode-regex" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.12.1" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-async-to-generator" "^7.12.1" + "@babel/plugin-transform-block-scoped-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-computed-properties" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-dotall-regex" "^7.12.1" + "@babel/plugin-transform-duplicate-keys" "^7.12.1" + "@babel/plugin-transform-exponentiation-operator" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-function-name" "^7.12.1" + "@babel/plugin-transform-literals" "^7.12.1" + "@babel/plugin-transform-member-expression-literals" "^7.12.1" + "@babel/plugin-transform-modules-amd" "^7.12.1" + "@babel/plugin-transform-modules-commonjs" "^7.12.1" + "@babel/plugin-transform-modules-systemjs" "^7.12.1" + "@babel/plugin-transform-modules-umd" "^7.12.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" + "@babel/plugin-transform-new-target" "^7.12.1" + "@babel/plugin-transform-object-super" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-property-literals" "^7.12.1" + "@babel/plugin-transform-regenerator" "^7.12.1" + "@babel/plugin-transform-reserved-words" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-sticky-regex" "^7.12.1" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/plugin-transform-typeof-symbol" "^7.12.1" + "@babel/plugin-transform-unicode-escapes" "^7.12.1" + "@babel/plugin-transform-unicode-regex" "^7.12.1" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.9.0" - browserslist "^4.9.1" + "@babel/types" "^7.12.1" core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" semver "^5.5.0" -"@babel/preset-env@^7.4.5": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.3.tgz#3e58c9861bbd93b6a679987c7e4bd365c56c80c9" - integrity sha512-jHaSUgiewTmly88bJtMHbOd1bJf2ocYxb5BWKSDQIP5tmgFuS/n0gl+nhSrYDhT33m0vPxp+rP8oYYgPgMNQlg== - dependencies: - "@babel/compat-data" "^7.10.3" - "@babel/helper-compilation-targets" "^7.10.2" - "@babel/helper-module-imports" "^7.10.3" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/plugin-proposal-async-generator-functions" "^7.10.3" - "@babel/plugin-proposal-class-properties" "^7.10.1" - "@babel/plugin-proposal-dynamic-import" "^7.10.1" - "@babel/plugin-proposal-json-strings" "^7.10.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.1" - "@babel/plugin-proposal-numeric-separator" "^7.10.1" - "@babel/plugin-proposal-object-rest-spread" "^7.10.3" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.1" - "@babel/plugin-proposal-optional-chaining" "^7.10.3" - "@babel/plugin-proposal-private-methods" "^7.10.1" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.1" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.1" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.1" - "@babel/plugin-transform-arrow-functions" "^7.10.1" - "@babel/plugin-transform-async-to-generator" "^7.10.1" - "@babel/plugin-transform-block-scoped-functions" "^7.10.1" - "@babel/plugin-transform-block-scoping" "^7.10.1" - "@babel/plugin-transform-classes" "^7.10.3" - "@babel/plugin-transform-computed-properties" "^7.10.3" - "@babel/plugin-transform-destructuring" "^7.10.1" - "@babel/plugin-transform-dotall-regex" "^7.10.1" - "@babel/plugin-transform-duplicate-keys" "^7.10.1" - "@babel/plugin-transform-exponentiation-operator" "^7.10.1" - "@babel/plugin-transform-for-of" "^7.10.1" - "@babel/plugin-transform-function-name" "^7.10.1" - "@babel/plugin-transform-literals" "^7.10.1" - "@babel/plugin-transform-member-expression-literals" "^7.10.1" - "@babel/plugin-transform-modules-amd" "^7.10.1" - "@babel/plugin-transform-modules-commonjs" "^7.10.1" - "@babel/plugin-transform-modules-systemjs" "^7.10.3" - "@babel/plugin-transform-modules-umd" "^7.10.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.3" - "@babel/plugin-transform-new-target" "^7.10.1" - "@babel/plugin-transform-object-super" "^7.10.1" - "@babel/plugin-transform-parameters" "^7.10.1" - "@babel/plugin-transform-property-literals" "^7.10.1" - "@babel/plugin-transform-regenerator" "^7.10.3" - "@babel/plugin-transform-reserved-words" "^7.10.1" - "@babel/plugin-transform-shorthand-properties" "^7.10.1" - "@babel/plugin-transform-spread" "^7.10.1" - "@babel/plugin-transform-sticky-regex" "^7.10.1" - "@babel/plugin-transform-template-literals" "^7.10.3" - "@babel/plugin-transform-typeof-symbol" "^7.10.1" - "@babel/plugin-transform-unicode-escapes" "^7.10.1" - "@babel/plugin-transform-unicode-regex" "^7.10.1" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.10.3" - browserslist "^4.12.0" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" - semver "^5.5.0" +"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.8.4": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.1.tgz#b55914e2e68885ea03f69600b2d3537e54574a93" + integrity sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ== + dependencies: + "@babel/compat-data" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-async-generator-functions" "^7.13.15" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@babel/plugin-proposal-class-static-block" "^7.13.11" + "@babel/plugin-proposal-dynamic-import" "^7.13.8" + "@babel/plugin-proposal-export-namespace-from" "^7.12.13" + "@babel/plugin-proposal-json-strings" "^7.13.8" + "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" + "@babel/plugin-proposal-numeric-separator" "^7.12.13" + "@babel/plugin-proposal-object-rest-spread" "^7.13.8" + "@babel/plugin-proposal-optional-catch-binding" "^7.13.8" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-private-methods" "^7.13.0" + "@babel/plugin-proposal-private-property-in-object" "^7.14.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + "@babel/plugin-syntax-top-level-await" "^7.12.13" + "@babel/plugin-transform-arrow-functions" "^7.13.0" + "@babel/plugin-transform-async-to-generator" "^7.13.0" + "@babel/plugin-transform-block-scoped-functions" "^7.12.13" + "@babel/plugin-transform-block-scoping" "^7.14.1" + "@babel/plugin-transform-classes" "^7.13.0" + "@babel/plugin-transform-computed-properties" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.13.17" + "@babel/plugin-transform-dotall-regex" "^7.12.13" + "@babel/plugin-transform-duplicate-keys" "^7.12.13" + "@babel/plugin-transform-exponentiation-operator" "^7.12.13" + "@babel/plugin-transform-for-of" "^7.13.0" + "@babel/plugin-transform-function-name" "^7.12.13" + "@babel/plugin-transform-literals" "^7.12.13" + "@babel/plugin-transform-member-expression-literals" "^7.12.13" + "@babel/plugin-transform-modules-amd" "^7.14.0" + "@babel/plugin-transform-modules-commonjs" "^7.14.0" + "@babel/plugin-transform-modules-systemjs" "^7.13.8" + "@babel/plugin-transform-modules-umd" "^7.14.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" + "@babel/plugin-transform-new-target" "^7.12.13" + "@babel/plugin-transform-object-super" "^7.12.13" + "@babel/plugin-transform-parameters" "^7.13.0" + "@babel/plugin-transform-property-literals" "^7.12.13" + "@babel/plugin-transform-regenerator" "^7.13.15" + "@babel/plugin-transform-reserved-words" "^7.12.13" + "@babel/plugin-transform-shorthand-properties" "^7.12.13" + "@babel/plugin-transform-spread" "^7.13.0" + "@babel/plugin-transform-sticky-regex" "^7.12.13" + "@babel/plugin-transform-template-literals" "^7.13.0" + "@babel/plugin-transform-typeof-symbol" "^7.12.13" + "@babel/plugin-transform-unicode-escapes" "^7.12.13" + "@babel/plugin-transform-unicode-regex" "^7.12.13" + "@babel/preset-modules" "^0.1.4" + "@babel/types" "^7.14.1" + babel-plugin-polyfill-corejs2 "^0.2.0" + babel-plugin-polyfill-corejs3 "^0.2.0" + babel-plugin-polyfill-regenerator "^0.2.0" + core-js-compat "^3.9.0" + semver "^6.3.0" -"@babel/preset-modules@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" - integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== +"@babel/preset-modules@^0.1.3", "@babel/preset-modules@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -1021,101 +1109,97 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@7.9.1": - version "7.9.1" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.9.1.tgz#b346403c36d58c3bb544148272a0cefd9c28677a" - integrity sha512-aJBYF23MPj0RNdp/4bHnAP0NVqqZRr9kl0NAOP4nJCex6OYVio59+dnQzsAWFuogdLyeaKA1hmfUIVZkY5J+TQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-transform-react-display-name" "^7.8.3" - "@babel/plugin-transform-react-jsx" "^7.9.1" - "@babel/plugin-transform-react-jsx-development" "^7.9.0" - "@babel/plugin-transform-react-jsx-self" "^7.9.0" - "@babel/plugin-transform-react-jsx-source" "^7.9.0" - -"@babel/preset-react@^7.0.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.1.tgz#e2ab8ae9a363ec307b936589f07ed753192de041" - integrity sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-transform-react-display-name" "^7.10.1" - "@babel/plugin-transform-react-jsx" "^7.10.1" - "@babel/plugin-transform-react-jsx-development" "^7.10.1" - "@babel/plugin-transform-react-jsx-self" "^7.10.1" - "@babel/plugin-transform-react-jsx-source" "^7.10.1" - "@babel/plugin-transform-react-pure-annotations" "^7.10.1" - -"@babel/preset-typescript@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz#87705a72b1f0d59df21c179f7c3d2ef4b16ce192" - integrity sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg== +"@babel/preset-react@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.1.tgz#7f022b13f55b6dd82f00f16d1c599ae62985358c" + integrity sha512-euCExymHCi0qB9u5fKw7rvlw7AZSjw/NaB9h7EkdTt5+yHRrXdiRTh7fkG3uBPpJg82CqLfp1LHLqWGSCrab+g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.12.1" + "@babel/plugin-transform-react-jsx" "^7.12.1" + "@babel/plugin-transform-react-jsx-development" "^7.12.1" + "@babel/plugin-transform-react-jsx-self" "^7.12.1" + "@babel/plugin-transform-react-jsx-source" "^7.12.1" + "@babel/plugin-transform-react-pure-annotations" "^7.12.1" + +"@babel/preset-react@^7.12.5": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.13.13.tgz#fa6895a96c50763fe693f9148568458d5a839761" + integrity sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-transform-react-display-name" "^7.12.13" + "@babel/plugin-transform-react-jsx" "^7.13.12" + "@babel/plugin-transform-react-jsx-development" "^7.12.17" + "@babel/plugin-transform-react-pure-annotations" "^7.12.1" + +"@babel/preset-typescript@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.1.tgz#86480b483bb97f75036e8864fe404cc782cc311b" + integrity sha512-hNK/DhmoJPsksdHuI/RVrcEws7GN5eamhi28JkO52MqIxU8Z0QpmiSOQxZHWOHV7I3P4UjHV97ay4TcamMA6Kw== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-transform-typescript" "^7.9.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-typescript" "^7.12.1" -"@babel/runtime-corejs3@^7.8.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.10.3.tgz#931ed6941d3954924a7aa967ee440e60c507b91a" - integrity sha512-HA7RPj5xvJxQl429r5Cxr2trJwOfPjKiqhCXcdQPSqO2G0RHPZpXu4fkYmBaTKCp2c/jRaMK9GB/lN+7zvvFPw== +"@babel/runtime-corejs3@^7.10.2": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz#6bf5fbc0b961f8e3202888cb2cd0fb7a0a9a3f66" + integrity sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg== dependencies: core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.0.tgz#337eda67401f5b066a6f205a3113d4ac18ba495b" - integrity sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.3.tgz#670d002655a7c366540c67f6fd3342cd09500364" - integrity sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.2.0": +"@babel/runtime@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740" integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.1", "@babel/template@^7.10.3", "@babel/template@^7.4.0", "@babel/template@^7.8.6": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.3.tgz#4d13bc8e30bf95b0ce9d175d30306f42a2c9a7b8" - integrity sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA== - dependencies: - "@babel/code-frame" "^7.10.3" - "@babel/parser" "^7.10.3" - "@babel/types" "^7.10.3" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.10.3", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.3.tgz#0b01731794aa7b77b214bcd96661f18281155d7e" - integrity sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug== - dependencies: - "@babel/code-frame" "^7.10.3" - "@babel/generator" "^7.10.3" - "@babel/helper-function-name" "^7.10.3" - "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/parser" "^7.10.3" - "@babel/types" "^7.10.3" +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.7.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.0.tgz#cea0dc8ae7e2b1dec65f512f39f3483e8cc95aef" + integrity sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.0" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.14.0" + "@babel/types" "^7.14.0" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.10.1", "@babel/types@^7.10.3", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.3.tgz#6535e3b79fea86a6b09e012ea8528f935099de8e" - integrity sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA== +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.6", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" + integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== dependencies: - "@babel/helper-validator-identifier" "^7.10.3" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1134,6 +1218,21 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== +"@eslint/eslintrc@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" + integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -1149,7 +1248,7 @@ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== -"@hapi/joi@^15.0.0": +"@hapi/joi@^15.1.0": version "15.1.1" resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== @@ -1166,166 +1265,241 @@ dependencies: "@hapi/hoek" "^8.3.0" -"@jest/console@^24.7.1", "@jest/console@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" - integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== +"@hypnosphi/create-react-context@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6" + integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A== dependencies: - "@jest/source-map" "^24.9.0" - chalk "^2.0.1" - slash "^2.0.0" + gud "^1.0.0" + warning "^4.0.3" -"@jest/core@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" - integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.9.0" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-resolve-dependencies "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - jest-watcher "^24.9.0" - micromatch "^3.1.10" - p-each-series "^1.0.0" - realpath-native "^1.1.0" - rimraf "^2.5.4" - slash "^2.0.0" - strip-ansi "^5.0.0" +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" -"@jest/environment@^24.3.0", "@jest/environment@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" - integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" + integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== dependencies: - "@jest/fake-timers" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^26.6.2" + jest-util "^26.6.2" + slash "^3.0.0" -"@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" - integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== +"@jest/core@^26.6.0", "@jest/core@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" + integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== dependencies: - "@jest/types" "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" + "@jest/console" "^26.6.2" + "@jest/reporters" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-changed-files "^26.6.2" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-resolve-dependencies "^26.6.3" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + jest-watcher "^26.6.2" + micromatch "^4.0.2" + p-each-series "^2.1.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" -"@jest/reporters@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" - integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" +"@jest/environment@^26.6.0", "@jest/environment@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" + integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== + dependencies: + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + +"@jest/fake-timers@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" + integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== + dependencies: + "@jest/types" "^26.6.2" + "@sinonjs/fake-timers" "^6.0.1" + "@types/node" "*" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-util "^26.6.2" + +"@jest/globals@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" + integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/types" "^26.6.2" + expect "^26.6.2" + +"@jest/reporters@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" + integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.2.6" - jest-haste-map "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - node-notifier "^5.4.2" - slash "^2.0.0" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^26.6.2" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + slash "^3.0.0" source-map "^0.6.0" - string-length "^2.0.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^7.0.0" + optionalDependencies: + node-notifier "^8.0.0" -"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" - integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== +"@jest/source-map@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" + integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== dependencies: callsites "^3.0.0" - graceful-fs "^4.1.15" + graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" - integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== +"@jest/test-result@^26.6.0", "@jest/test-result@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" + integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== dependencies: - "@jest/console" "^24.9.0" - "@jest/types" "^24.9.0" + "@jest/console" "^26.6.2" + "@jest/types" "^26.6.2" "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" - integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== +"@jest/test-sequencer@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" + integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== dependencies: - "@jest/test-result" "^24.9.0" - jest-haste-map "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" + "@jest/test-result" "^26.6.2" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" -"@jest/transform@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" - integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.9.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.9.0" - jest-regex-util "^24.9.0" - jest-util "^24.9.0" - micromatch "^3.1.10" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" pirates "^4.0.1" - realpath-native "^1.1.0" - slash "^2.0.0" + slash "^3.0.0" source-map "^0.6.1" - write-file-atomic "2.4.1" + write-file-atomic "^3.0.0" -"@jest/types@^24.3.0", "@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== +"@jest/types@^26.6.0", "@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== +"@nodelib/fs.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" + "@nodelib/fs.stat" "2.0.4" + run-parallel "^1.1.9" -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + dependencies: + "@nodelib/fs.scandir" "2.1.4" + fastq "^1.6.0" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@pmmmwh/react-refresh-webpack-plugin@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766" + integrity sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ== + dependencies: + ansi-html "^0.0.7" + error-stack-parser "^2.0.6" + html-entities "^1.2.1" + native-url "^0.2.6" + schema-utils "^2.6.5" + source-map "^0.7.3" "@redux-saga/core@^1.1.3": version "1.1.3" @@ -1371,188 +1545,243 @@ resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204" integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg== -"@sentry/browser@5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.27.3.tgz#02e78a4502ee99988d3cbb0075a11ec44b503871" - integrity sha512-vczS+XTW4Nk2A7TIpAw8IVFHpp+NK6mV9euBG2I61Bs2QbQY9yKLfbjiln/yH2Q8X4THX6MKa0GuiPoCEeq3uw== +"@rollup/plugin-node-resolve@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca" + integrity sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q== + dependencies: + "@rollup/pluginutils" "^3.0.8" + "@types/resolve" "0.0.8" + builtin-modules "^3.1.0" + is-module "^1.0.0" + resolve "^1.14.2" + +"@rollup/plugin-replace@^2.3.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" + integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + magic-string "^0.25.7" + +"@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@sentry/browser@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.30.0.tgz#c28f49d551db3172080caef9f18791a7fd39e3b3" + integrity sha512-rOb58ZNVJWh1VuMuBG1mL9r54nZqKeaIlwSlvzJfc89vyfd7n6tQ1UXMN383QBz/MS5H5z44Hy5eE+7pCrYAfw== dependencies: - "@sentry/core" "5.27.3" - "@sentry/types" "5.27.3" - "@sentry/utils" "5.27.3" + "@sentry/core" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" tslib "^1.9.3" -"@sentry/core@5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.27.3.tgz#d7a175b71596b7eb4b2e8b4cd1858a60d95813bb" - integrity sha512-yqepQO88jSt5hy0awpk61AxI4oHB09LjVbUEk4nJDg+1YXuND23cuZvH+Sp2jCZX2vrsw2tefwflToYfA8/U2w== +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== dependencies: - "@sentry/hub" "5.27.3" - "@sentry/minimal" "5.27.3" - "@sentry/types" "5.27.3" - "@sentry/utils" "5.27.3" + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" tslib "^1.9.3" -"@sentry/hub@5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.27.3.tgz#f509c2fd38f500afef6030504e82510dbd0649d6" - integrity sha512-icEH3hr6NVQkpowXZcPOs9IgJZP5lMKtvud4mVioSpkd+NxtRdKrGEX4eF2TCviOJc9Md0mV4K+aL5Au7hxggQ== +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== dependencies: - "@sentry/types" "5.27.3" - "@sentry/utils" "5.27.3" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" tslib "^1.9.3" -"@sentry/minimal@5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.27.3.tgz#c9263bdd6270bfeae64137177448911dff568e53" - integrity sha512-ng01cM0rsE1RMjqVTpPLN0ZVkTo0I675usM1krkpQe8ddW6tfQ6EJWpt02/BrpQZRQzTtfWp6/RyB1KFXg6icg== +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== dependencies: - "@sentry/hub" "5.27.3" - "@sentry/types" "5.27.3" + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" tslib "^1.9.3" "@sentry/react@^5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.27.3.tgz#aefff1cb2249a4e7f123c7467d1da205d5c02e92" - integrity sha512-p7E+djSUVKz02HoRVDX+zamjV8+RL4bqoPnS9JQESweB0sRTYlpvi+CqWLYWNWnamWQWOl97hOw/lLDpo4kUSA== - dependencies: - "@sentry/browser" "5.27.3" - "@sentry/minimal" "5.27.3" - "@sentry/types" "5.27.3" - "@sentry/utils" "5.27.3" + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.30.0.tgz#320e05f766b6a26faefa8d76d1101fd50c69f541" + integrity sha512-dvn4mqCgbeEuUXEGp5P9PaW5j4GWTFUSdx/yG8f9IxNZv5zM+7otjog9ukrubFZvlxVxD/PrIxK0MhadfFY/Dw== + dependencies: + "@sentry/browser" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" hoist-non-react-statics "^3.3.2" tslib "^1.9.3" "@sentry/tracing@^5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.27.3.tgz#787e57a2f7071e375f4fad0f3c3a5ff3381928e7" - integrity sha512-UWrHMdGxPfx1u558CWm1tptc2z0BuqCHVe2+BNN7POahq5BkpbGqaotyPQTBHbfmcs6QGfsMG57ou8HQFrBxyA== - dependencies: - "@sentry/hub" "5.27.3" - "@sentry/minimal" "5.27.3" - "@sentry/types" "5.27.3" - "@sentry/utils" "5.27.3" + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" tslib "^1.9.3" -"@sentry/types@5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.27.3.tgz#d377508769bc658d672c287166c7f6c5db45660c" - integrity sha512-PkWhMArFMxBb1g3HtMEL8Ea9PYae2MU0z9CMIWiqzerFy2ZpKG98IU3pt8ic4JkmKQdwB8hDiZpRPMHhW0WYwQ== +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== -"@sentry/utils@5.27.3": - version "5.27.3" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.27.3.tgz#1fc45dfad1f1e4398bee58684d8947666d8d3003" - integrity sha512-R9WvFrRBALZvCzu/9BsuXBCfkNxz4MwdBNSXaBsJo4afQw1ljkjIc9DpHzlL9S9goIwXo81Buwmr5gGDO6aH+Q== +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== dependencies: - "@sentry/types" "5.27.3" + "@sentry/types" "5.30.0" tslib "^1.9.3" -"@svgr/babel-plugin-add-jsx-attribute@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" - integrity sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig== +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" -"@svgr/babel-plugin-remove-jsx-attribute@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz#297550b9a8c0c7337bea12bdfc8a80bb66f85abc" - integrity sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ== +"@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" -"@svgr/babel-plugin-remove-jsx-empty-expression@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz#c196302f3e68eab6a05e98af9ca8570bc13131c7" - integrity sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w== +"@surma/rollup-plugin-off-main-thread@^1.1.1": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58" + integrity sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A== + dependencies: + ejs "^2.6.1" + magic-string "^0.25.0" -"@svgr/babel-plugin-replace-jsx-attribute-value@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165" - integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w== +"@svgr/babel-plugin-add-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" + integrity sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg== -"@svgr/babel-plugin-svg-dynamic-title@^4.3.3": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz#2cdedd747e5b1b29ed4c241e46256aac8110dd93" - integrity sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w== +"@svgr/babel-plugin-remove-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz#6b2c770c95c874654fd5e1d5ef475b78a0a962ef" + integrity sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg== -"@svgr/babel-plugin-svg-em-dimensions@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz#9a94791c9a288108d20a9d2cc64cac820f141391" - integrity sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w== +"@svgr/babel-plugin-remove-jsx-empty-expression@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz#25621a8915ed7ad70da6cea3d0a6dbc2ea933efd" + integrity sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA== -"@svgr/babel-plugin-transform-react-native-svg@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz#151487322843359a1ca86b21a3815fd21a88b717" - integrity sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw== +"@svgr/babel-plugin-replace-jsx-attribute-value@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz#0b221fc57f9fcd10e91fe219e2cd0dd03145a897" + integrity sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ== -"@svgr/babel-plugin-transform-svg-component@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697" - integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw== - -"@svgr/babel-preset@^4.3.3": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.3.tgz#a75d8c2f202ac0e5774e6bfc165d028b39a1316c" - integrity sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0" - "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0" - "@svgr/babel-plugin-svg-dynamic-title" "^4.3.3" - "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0" - "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0" - "@svgr/babel-plugin-transform-svg-component" "^4.2.0" - -"@svgr/core@^4.3.3": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.3.tgz#b37b89d5b757dc66e8c74156d00c368338d24293" - integrity sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w== - dependencies: - "@svgr/plugin-jsx" "^4.3.3" - camelcase "^5.3.1" - cosmiconfig "^5.2.1" +"@svgr/babel-plugin-svg-dynamic-title@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz#139b546dd0c3186b6e5db4fefc26cb0baea729d7" + integrity sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg== -"@svgr/hast-util-to-babel-ast@^4.3.2": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz#1d5a082f7b929ef8f1f578950238f630e14532b8" - integrity sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg== +"@svgr/babel-plugin-svg-em-dimensions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz#6543f69526632a133ce5cabab965deeaea2234a0" + integrity sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw== + +"@svgr/babel-plugin-transform-react-native-svg@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz#00bf9a7a73f1cad3948cdab1f8dfb774750f8c80" + integrity sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q== + +"@svgr/babel-plugin-transform-svg-component@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz#583a5e2a193e214da2f3afeb0b9e8d3250126b4a" + integrity sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ== + +"@svgr/babel-preset@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-5.5.0.tgz#8af54f3e0a8add7b1e2b0fcd5a882c55393df327" + integrity sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^5.0.1" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^5.0.1" + "@svgr/babel-plugin-svg-dynamic-title" "^5.4.0" + "@svgr/babel-plugin-svg-em-dimensions" "^5.4.0" + "@svgr/babel-plugin-transform-react-native-svg" "^5.4.0" + "@svgr/babel-plugin-transform-svg-component" "^5.5.0" + +"@svgr/core@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-5.5.0.tgz#82e826b8715d71083120fe8f2492ec7d7874a579" + integrity sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ== dependencies: - "@babel/types" "^7.4.4" + "@svgr/plugin-jsx" "^5.5.0" + camelcase "^6.2.0" + cosmiconfig "^7.0.0" + +"@svgr/hast-util-to-babel-ast@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz#5ee52a9c2533f73e63f8f22b779f93cd432a5461" + integrity sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ== + dependencies: + "@babel/types" "^7.12.6" -"@svgr/plugin-jsx@^4.3.3": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz#e2ba913dbdfbe85252a34db101abc7ebd50992fa" - integrity sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w== +"@svgr/plugin-jsx@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz#1aa8cd798a1db7173ac043466d7b52236b369000" + integrity sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA== dependencies: - "@babel/core" "^7.4.5" - "@svgr/babel-preset" "^4.3.3" - "@svgr/hast-util-to-babel-ast" "^4.3.2" - svg-parser "^2.0.0" + "@babel/core" "^7.12.3" + "@svgr/babel-preset" "^5.5.0" + "@svgr/hast-util-to-babel-ast" "^5.5.0" + svg-parser "^2.0.2" -"@svgr/plugin-svgo@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz#daac0a3d872e3f55935c6588dd370336865e9e32" - integrity sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w== +"@svgr/plugin-svgo@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz#02da55d85320549324e201c7b2e53bf431fcc246" + integrity sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ== dependencies: - cosmiconfig "^5.2.1" - merge-deep "^3.0.2" + cosmiconfig "^7.0.0" + deepmerge "^4.2.2" svgo "^1.2.2" -"@svgr/webpack@4.3.3": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.3.tgz#13cc2423bf3dff2d494f16b17eb7eacb86895017" - integrity sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg== - dependencies: - "@babel/core" "^7.4.5" - "@babel/plugin-transform-react-constant-elements" "^7.0.0" - "@babel/preset-env" "^7.4.5" - "@babel/preset-react" "^7.0.0" - "@svgr/core" "^4.3.3" - "@svgr/plugin-jsx" "^4.3.3" - "@svgr/plugin-svgo" "^4.3.1" - loader-utils "^1.2.3" +"@svgr/webpack@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-5.5.0.tgz#aae858ee579f5fa8ce6c3166ef56c6a1b381b640" + integrity sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g== + dependencies: + "@babel/core" "^7.12.3" + "@babel/plugin-transform-react-constant-elements" "^7.12.1" + "@babel/preset-env" "^7.12.1" + "@babel/preset-react" "^7.12.5" + "@svgr/core" "^5.5.0" + "@svgr/plugin-jsx" "^5.5.0" + "@svgr/plugin-svgo" "^5.5.0" + loader-utils "^2.0.0" + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== -"@types/babel__core@^7.1.0": - version "7.1.9" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d" - integrity sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw== +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": + version "7.1.14" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" + integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1561,46 +1790,98 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.1" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" - integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" + integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" - integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + version "7.4.0" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" + integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.12" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.12.tgz#22f49a028e69465390f87bb103ebd61bd086b8f5" - integrity sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA== +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" + integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== dependencies: "@babel/types" "^7.3.0" -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/d3-path@^1": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" + integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" - integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/d3-scale@^3.0.0": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.2.2.tgz#5e28d0b1c599328aaec6094219f10a2570be6d74" + integrity sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ== + dependencies: + "@types/d3-time" "*" + +"@types/d3-shape@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.0.0.tgz#61aa065726f3c2641aedc59c3603475ab11aeb2f" + integrity sha512-NLzD02m5PiD1KLEDjLN+MtqEcFYn4ZL9+Rqc9ZwARK1cpKZXd91zBETbe6wpBB6Ia0D0VZbpmbW3+BsGPGnCpA== + dependencies: + "@types/d3-path" "^1" + +"@types/d3-time@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.0.0.tgz#831dd093db91f16b83ba980e194bb8e4bcef44d6" + integrity sha512-Abz8bTzy8UWDeYs9pCa3D37i29EWDjNTjemdk0ei1ApYVNqulYlGUKip/jLOpogkPSsPz/GvZCYiC7MFlEk0iQ== + +"@types/eslint@^7.2.6": + version "7.2.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.10.tgz#4b7a9368d46c0f8cd5408c23288a59aa2394d917" + integrity sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "0.0.47" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" + integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== "@types/glob@^7.1.1": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987" - integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA== + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== dependencies: "@types/minimatch" "*" "@types/node" "*" -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/html-minifier-terser@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" + integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== @@ -1612,34 +1893,48 @@ dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" - integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== dependencies: - "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" + integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== "@types/node@*": - version "14.0.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.14.tgz#24a0b5959f16ac141aeb0c5b3cd7a15b7c64cbce" - integrity sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ== + version "15.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" + integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/prettier@^2.0.0": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" + integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== + "@types/prop-types@*": version "15.7.3" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" @@ -1650,223 +1945,352 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/react-redux@^7.1.16": + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" + integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react@*": - version "16.9.41" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.41.tgz#925137ee4d2ff406a0ecf29e8e9237390844002e" - integrity sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug== + version "17.0.5" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.5.tgz#3d887570c4489011f75a3fc8f965bf87d09a1bea" + integrity sha512-bj4biDB9ZJmGAYTWSKJly6bMr4BLUiBrx9ujiJEoP9XIDY9CTaPGxE5QWN/1WjpPLzYF7/jRNnV2nNxNe970sw== dependencies: "@types/prop-types" "*" - csstype "^2.2.0" + "@types/scheduler" "*" + csstype "^3.0.2" -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/resize-observer-browser@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz#36d897708172ac2380cd486da7a3daf1161c1e23" + integrity sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ== + +"@types/resolve@0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/stack-utils@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" + integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + +"@types/tapable@^1", "@types/tapable@^1.0.5": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.7.tgz#545158342f949e8fd3bfd813224971ecddc3fac4" + integrity sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ== + +"@types/uglify-js@*": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.0.tgz#1cad8df1fb0b143c5aba08de5712ea9d1ff71124" + integrity sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q== + dependencies: + source-map "^0.6.1" "@types/uuid@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== +"@types/webpack-sources@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.0.tgz#8882b0bd62d1e0ce62f183d0d01b72e6e82e8c10" + integrity sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.41.8": + version "4.41.28" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.28.tgz#0069a2159b7ad4d83d0b5801942c17d54133897b" + integrity sha512-Nn84RAiJjKRfPFFCVR8LC4ueTtTdfWAMZ03THIzZWRJB+rX24BD3LqPSFnbMscWauEsT4segAsylPDIaZyZyLQ== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + "@types/yargs-parser@*": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" - integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + version "20.2.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" + integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== -"@types/yargs@^13.0.0": - version "13.0.9" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.9.tgz#44028e974343c7afcf3960f1a2b1099c39a7b5e1" - integrity sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg== +"@types/yargs@^15.0.0": + version "15.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" + integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^2.10.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" - integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ== +"@typescript-eslint/eslint-plugin@^4.5.0": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.1.tgz#6bcdbaa4548553ab861b4e5f34936ead1349a543" + integrity sha512-kVTAghWDDhsvQ602tHBc6WmQkdaYbkcTwZu+7l24jtJiYvm9l+/y/b2BZANEezxPDiX5MK2ZecE+9BFi/YJryw== dependencies: - "@typescript-eslint/experimental-utils" "2.34.0" + "@typescript-eslint/experimental-utils" "4.22.1" + "@typescript-eslint/scope-manager" "4.22.1" + debug "^4.1.1" functional-red-black-tree "^1.0.1" + lodash "^4.17.15" regexpp "^3.0.0" + semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" - integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== +"@typescript-eslint/experimental-utils@4.22.1", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.1.tgz#3938a5c89b27dc9a39b5de63a62ab1623ab27497" + integrity sha512-svYlHecSMCQGDO2qN1v477ax/IDQwWhc7PRBiwAdAMJE7GXk5stF4Z9R/8wbRkuX/5e9dHqbIWxjeOjckK3wLQ== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.34.0" + "@typescript-eslint/scope-manager" "4.22.1" + "@typescript-eslint/types" "4.22.1" + "@typescript-eslint/typescript-estree" "4.22.1" eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@^2.10.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" - integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA== +"@typescript-eslint/experimental-utils@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686" + integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw== dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.34.0" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-visitor-keys "^1.1.0" + "@types/json-schema" "^7.0.3" + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/typescript-estree" "3.10.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" -"@typescript-eslint/typescript-estree@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" - integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== +"@typescript-eslint/parser@^4.5.0": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.22.1.tgz#a95bda0fd01d994a15fc3e99dc984294f25c19cc" + integrity sha512-l+sUJFInWhuMxA6rtirzjooh8cM/AATAe3amvIkqKFeMzkn85V+eLzb1RyuXkHak4dLfYzOmF6DXPyflJvjQnw== dependencies: + "@typescript-eslint/scope-manager" "4.22.1" + "@typescript-eslint/types" "4.22.1" + "@typescript-eslint/typescript-estree" "4.22.1" + debug "^4.1.1" + +"@typescript-eslint/scope-manager@4.22.1": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.22.1.tgz#5bb357f94f9cd8b94e6be43dd637eb73b8f355b4" + integrity sha512-d5bAiPBiessSmNi8Amq/RuLslvcumxLmyhf1/Xa9IuaoFJ0YtshlJKxhlbY7l2JdEk3wS0EnmnfeJWSvADOe0g== + dependencies: + "@typescript-eslint/types" "4.22.1" + "@typescript-eslint/visitor-keys" "4.22.1" + +"@typescript-eslint/types@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" + integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== + +"@typescript-eslint/types@4.22.1": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.22.1.tgz#bf99c6cec0b4a23d53a61894816927f2adad856a" + integrity sha512-2HTkbkdAeI3OOcWbqA8hWf/7z9c6gkmnWNGz0dKSLYLWywUlkOAQ2XcjhlKLj5xBFDf8FgAOF5aQbnLRvgNbCw== + +"@typescript-eslint/typescript-estree@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" + integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w== + dependencies: + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/visitor-keys" "3.10.1" debug "^4.1.1" - eslint-visitor-keys "^1.1.0" glob "^7.1.6" is-glob "^4.0.1" lodash "^4.17.15" semver "^7.3.2" tsutils "^3.17.1" -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@typescript-eslint/typescript-estree@4.22.1": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.1.tgz#dca379eead8cdfd4edc04805e83af6d148c164f9" + integrity sha512-p3We0pAPacT+onSGM+sPR+M9CblVqdA9F1JEdIqRVlxK5Qth4ochXQgIyb9daBomyQKAXbygxp1aXQRV0GC79A== + dependencies: + "@typescript-eslint/types" "4.22.1" + "@typescript-eslint/visitor-keys" "4.22.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" + integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ== + dependencies: + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/visitor-keys@4.22.1": + version "4.22.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.1.tgz#6045ae25a11662c671f90b3a403d682dfca0b7a6" + integrity sha512-WPkOrIRm+WCLZxXQHCi+WG8T2MMTUFR70rWjdWYddLT7cEfb2P4a3O/J2U1FBVsSFTocXLCoXWY6MZGejeStvQ== + dependencies: + "@typescript-eslint/types" "4.22.1" + eslint-visitor-keys "^2.0.0" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -1879,10 +2303,10 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" @@ -1892,54 +2316,51 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" -acorn-globals@^4.1.0, acorn-globals@^4.3.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" + acorn "^7.1.1" + acorn-walk "^7.1.1" -acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" - integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^5.5.3: - version "5.7.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" - integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^6.0.1, acorn@^6.0.4, acorn@^6.2.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== +acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" - integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== +acorn@^8.1.0: + version "8.2.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" + integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -adjust-sourcemap-loader@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz#6471143af75ec02334b219f54bc7970c52fb29a4" - integrity sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA== +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== dependencies: - assert "1.4.1" - camelcase "5.0.0" - loader-utils "1.2.3" - object-path "0.11.4" - regex-parser "2.2.10" + loader-utils "^2.0.0" + regex-parser "^2.2.11" after@0.8.2: version "0.8.2" @@ -1947,9 +2368,9 @@ after@0.8.2: integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= aggregate-error@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" - integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" indent-string "^4.0.0" @@ -1959,44 +2380,54 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.5.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.0.tgz#5c894537098785926d71e696114a53ce768ed773" - integrity sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw== +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" - integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.1: + version "8.3.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.3.0.tgz#25ee7348e32cdc4a1dbb38256bf6bdc451dd577c" + integrity sha512-RYE7B5An83d7eWnDR8kbdaIFqmKCNsP16ay1hDbJEU+sa0e3H9SebskCt0Uufem6cfAVu7Col6ubcn/W+Sm8/Q== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -ansi-colors@^3.0.0, ansi-colors@^3.2.1: +ansi-colors@^3.0.0: version "3.2.4" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - type-fest "^0.11.0" + type-fest "^0.21.3" -ansi-html@0.0.7: +ansi-html@0.0.7, ansi-html@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= @@ -2006,12 +2437,7 @@ ansi-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.0.0, ansi-regex@^4.1.0: +ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -2021,11 +2447,6 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -2034,11 +2455,10 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: - "@types/color-name" "^1.1.1" color-convert "^2.0.1" anymatch@^2.0.0: @@ -2049,10 +2469,10 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@^3.0.3, anymatch@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -2074,13 +2494,13 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -aria-query@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" - integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== dependencies: - ast-types-flow "0.0.7" - commander "^2.11.0" + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" arity-n@^1.0.4: version "1.0.4" @@ -2102,11 +2522,6 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -2117,13 +2532,15 @@ array-flatten@^2.1.0: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-includes@^3.0.3, array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== +array-includes@^3.1.1, array-includes@^3.1.2, array-includes@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.1.1" is-string "^1.0.5" array-union@^1.0.1: @@ -2133,6 +2550,11 @@ array-union@^1.0.1: dependencies: array-uniq "^1.0.1" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -2143,37 +2565,49 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== +array.prototype.flat@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.1" + +array.prototype.flatmap@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" + integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + function-bind "^1.1.1" arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" inherits "^2.0.1" minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" asn1@~0.2.3: version "0.2.4" @@ -2187,13 +2621,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= - dependencies: - util "0.10.3" - assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -2207,16 +2634,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types-flow@0.0.7, ast-types-flow@^0.0.7: +ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -2244,19 +2666,24 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.6.1: - version "9.8.4" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.4.tgz#736f1012673a70fa3464671d78d41abd54512863" - integrity sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A== + version "9.8.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" + integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== dependencies: browserslist "^4.12.0" - caniuse-lite "^1.0.30001087" - colorette "^1.2.0" + caniuse-lite "^1.0.30001109" + colorette "^1.2.1" normalize-range "^0.1.2" num2fraction "^1.2.2" postcss "^7.0.32" @@ -2268,25 +2695,21 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" - integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +axe-core@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.2.0.tgz#6594db4ee62f78be79e32a7295d21b099b60668d" + integrity sha512-1uIESzroqpaTzt9uX48HO+6gfnKu3RwvWdCcWSrX4csMInJfCo1yvKPNXCwXFRpJqRW25tiASb6No0YH57PXqg== -axobject-query@^2.0.2: +axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-code-frame@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-eslint@10.1.0: +babel-eslint@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== @@ -2305,18 +2728,19 @@ babel-extract-comments@^1.0.0: dependencies: babylon "^6.18.0" -babel-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" - integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== - dependencies: - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.9.0" - chalk "^2.4.2" - slash "^2.0.0" +babel-jest@^26.6.0, babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== + dependencies: + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/babel__core" "^7.1.7" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" babel-loader@8.1.0: version "8.1.0" @@ -2336,21 +2760,25 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-istanbul@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" - integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - find-up "^3.0.0" - istanbul-lib-instrument "^3.3.0" - test-exclude "^5.2.3" - -babel-plugin-jest-hoist@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" - integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== - dependencies: + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" babel-plugin-macros@2.8.0: @@ -2362,10 +2790,34 @@ babel-plugin-macros@2.8.0: cosmiconfig "^6.0.0" resolve "^1.12.0" -babel-plugin-named-asset-import@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz#c9750a1b38d85112c9e166bf3ef7c5dbc605f4be" - integrity sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA== +babel-plugin-named-asset-import@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd" + integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw== + +babel-plugin-polyfill-corejs2@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz#686775bf9a5aa757e10520903675e3889caeedc4" + integrity sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.0" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz#f4b4bb7b19329827df36ff56f6e6d367026cb7a2" + integrity sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.0" + core-js-compat "^3.9.1" + +babel-plugin-polyfill-regenerator@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz#853f5f5716f4691d98c84f8069c7636ea8da7ab8" + integrity sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.0" babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" @@ -2385,32 +2837,50 @@ babel-plugin-transform-react-remove-prop-types@0.4.24: resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== -babel-preset-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" - integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.9.0" - -babel-preset-react-app@^9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz#54775d976588a8a6d1a99201a702befecaf48030" - integrity sha512-k58RtQOKH21NyKtzptoAvtAODuAJJs3ZhqBMl456/GnXEQ/0La92pNmwgWoMn5pBTrsvk3YYXdY7zpY4e3UIxA== - dependencies: - "@babel/core" "7.9.0" - "@babel/plugin-proposal-class-properties" "7.8.3" - "@babel/plugin-proposal-decorators" "7.8.3" - "@babel/plugin-proposal-nullish-coalescing-operator" "7.8.3" - "@babel/plugin-proposal-numeric-separator" "7.8.3" - "@babel/plugin-proposal-optional-chaining" "7.9.0" - "@babel/plugin-transform-flow-strip-types" "7.9.0" - "@babel/plugin-transform-react-display-name" "7.8.3" - "@babel/plugin-transform-runtime" "7.9.0" - "@babel/preset-env" "7.9.0" - "@babel/preset-react" "7.9.1" - "@babel/preset-typescript" "7.9.0" - "@babel/runtime" "7.9.0" +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== + dependencies: + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" + +babel-preset-react-app@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.0.0.tgz#689b60edc705f8a70ce87f47ab0e560a317d7045" + integrity sha512-itL2z8v16khpuKutx5IH8UdCdSTuzrOhRFTEdIhveZ2i1iBKDrVE0ATa4sFVy+02GLucZNVBWtoarXBy0Msdpg== + dependencies: + "@babel/core" "7.12.3" + "@babel/plugin-proposal-class-properties" "7.12.1" + "@babel/plugin-proposal-decorators" "7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "7.12.1" + "@babel/plugin-proposal-numeric-separator" "7.12.1" + "@babel/plugin-proposal-optional-chaining" "7.12.1" + "@babel/plugin-transform-flow-strip-types" "7.12.1" + "@babel/plugin-transform-react-display-name" "7.12.1" + "@babel/plugin-transform-runtime" "7.12.1" + "@babel/preset-env" "7.12.1" + "@babel/preset-react" "7.12.1" + "@babel/preset-typescript" "7.12.1" + "@babel/runtime" "7.12.1" babel-plugin-macros "2.8.0" babel-plugin-transform-react-remove-prop-types "0.4.24" @@ -2432,25 +2902,20 @@ backo2@1.0.2: resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= -balanced-match@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" - integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= - balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" - integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" @@ -2477,12 +2942,15 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -better-assert@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" - integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= +bfj@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2" + integrity sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw== dependencies: - callsite "1.0.0" + bluebird "^3.5.5" + check-types "^11.1.1" + hoopy "^0.1.4" + tryer "^1.0.1" big.js@^5.2.2: version "5.2.2" @@ -2495,9 +2963,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bindings@^1.5.0: version "1.5.0" @@ -2516,15 +2984,15 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" - integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== body-parser@1.19.0: version "1.19.0" @@ -2595,7 +3063,7 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.0.1: +brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= @@ -2605,13 +3073,6 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -2644,23 +3105,23 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.0.tgz#545d0b1b07e6b2c99211082bf1b12cce7a0b0e11" - integrity sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA== + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== dependencies: bn.js "^5.1.1" browserify-rsa "^4.0.1" create-hash "^1.2.0" create-hmac "^1.1.7" - elliptic "^6.5.2" + elliptic "^6.5.3" inherits "^2.0.4" parse-asn1 "^5.1.5" readable-stream "^3.6.0" @@ -2673,25 +3134,26 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@4.10.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" - integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== +browserslist@4.14.2: + version "4.14.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" + integrity sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== dependencies: - caniuse-lite "^1.0.30001035" - electron-to-chromium "^1.3.378" - node-releases "^1.1.52" - pkg-up "^3.1.0" + caniuse-lite "^1.0.30001125" + electron-to-chromium "^1.3.564" + escalade "^3.0.2" + node-releases "^1.1.61" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.6.2, browserslist@^4.6.4, browserslist@^4.8.5, browserslist@^4.9.1: - version "4.12.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.2.tgz#76653d7e4c57caa8a1a28513e2f4e197dc11a711" - integrity sha512-MfZaeYqR8StRZdstAK9hCKDd2StvePCYp5rHzQCPicUjfFliDgmuaBNPHYUTpAywBN8+Wc/d7NYVFkO0aqaBUw== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.6.2, browserslist@^4.6.4: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: - caniuse-lite "^1.0.30001088" - electron-to-chromium "^1.3.483" - escalade "^3.0.1" - node-releases "^1.1.58" + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" bser@2.1.1: version "2.1.1" @@ -2724,6 +3186,11 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +builtin-modules@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -2760,28 +3227,27 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" - integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== +cacache@^15.0.5: + version "15.0.6" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" + integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== dependencies: - chownr "^1.1.2" - figgy-pudding "^3.5.1" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" fs-minipass "^2.0.0" glob "^7.1.4" - graceful-fs "^4.2.2" infer-owner "^1.0.4" - lru-cache "^5.1.1" - minipass "^3.0.0" + lru-cache "^6.0.0" + minipass "^3.1.1" minipass-collect "^1.0.2" minipass-flush "^1.0.5" minipass-pipeline "^1.2.2" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - p-map "^3.0.0" + mkdirp "^1.0.3" + p-map "^4.0.0" promise-inflight "^1.0.1" - rimraf "^2.7.1" - ssri "^7.0.0" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" unique-filename "^1.1.1" cache-base@^1.0.1: @@ -2799,10 +3265,13 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" caller-callsite@^2.0.0: version "2.0.0" @@ -2816,12 +3285,7 @@ caller-path@^2.0.0: resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= dependencies: - caller-callsite "^2.0.0" - -callsite@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" - integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + caller-callsite "^2.0.0" callsites@^2.0.0: version "2.0.0" @@ -2834,23 +3298,23 @@ callsites@^3.0.0: integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camel-case@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" - integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== dependencies: - pascal-case "^3.1.1" - tslib "^1.10.0" - -camelcase@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" - integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + pascal-case "^3.1.2" + tslib "^2.0.3" camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0, camelcase@^6.1.0, camelcase@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -2861,10 +3325,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001087, caniuse-lite@^1.0.30001088: - version "1.0.30001090" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001090.tgz#ff7766332f60e80fea4903f30d360622e5551850" - integrity sha512-QzPRKDCyp7RhjczTPZaqK3CjPA5Ht2UnXhZhCI4f7QiB5JK6KEuZBxIzyWnB3wO4hgAj4GMRxAhuiacfw0Psjg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001219: + version "1.0.30001228" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" + integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== capture-exit@^2.0.0: version "2.0.0" @@ -2883,7 +3347,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2892,39 +3356,25 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4. escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +check-types@^11.1.1: + version "11.1.2" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f" + integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ== -"chokidar@>=3.0.0 <4.0.0": +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -2958,32 +3408,20 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.3.0, chokidar@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8" - integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.4.0" - optionalDependencies: - fsevents "~2.1.2" - -chownr@^1.1.1, chownr@^1.1.2: +chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^2.0.0: version "2.0.0" @@ -2998,6 +3436,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +cjs-module-lexer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" + integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -3008,7 +3451,12 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.3, classnames@^2.2.5, classnames@~2.2.5: +classnames@^2.2.3, classnames@^2.2.5: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + +classnames@~2.2.5: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== @@ -3032,7 +3480,7 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-truncate@2.1.0, cli-truncate@^2.1.0: +cli-truncate@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== @@ -3040,20 +3488,6 @@ cli-truncate@2.1.0, cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -3063,25 +3497,14 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" -clone-deep@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" - integrity sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY= - dependencies: - for-own "^0.1.3" - is-plain-object "^2.0.1" - kind-of "^3.0.2" - lazy-cache "^1.0.3" - shallow-clone "^0.1.2" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" co@^4.6.0: version "4.6.0" @@ -3097,10 +3520,10 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== collection-visit@^1.0.0: version "1.0.0" @@ -3134,26 +3557,26 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== +color-string@^1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" color@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== dependencies: color-convert "^1.9.1" - color-string "^1.5.2" + color-string "^1.5.4" -colorette@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.0.tgz#45306add826d196e8c87236ac05d797f25982e63" - integrity sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw== +colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" @@ -3162,7 +3585,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.11.0, commander@^2.20.0: +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -3172,10 +3595,10 @@ commander@^4.1.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== +commander@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== common-tags@^1.8.0: version "1.8.0" @@ -3193,20 +3616,15 @@ compare-versions@^3.6.0: integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== complex.js@^2.0.11: - version "2.0.11" - resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.11.tgz#09a873fbf15ffd8c18c9c2201ccef425c32b8bf1" - integrity sha512-6IArJLApNtdg1P1dFtn3dnyzoZBEF0MwMnrfF1exSBRpZYoy4yieMkpZhQDC0uwctw48vii0CFVyHfpgZ/DfGw== + version "2.0.12" + resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.12.tgz#fa4df97d8928e5f7b6a86b35bdeecc3a3eda8a22" + integrity sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw== component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= -component-emitter@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= - component-emitter@^1.2.1, component-emitter@~1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -3264,10 +3682,10 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" -confusing-browser-globals@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" - integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== +confusing-browser-globals@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" + integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== connect-history-api-fallback@^1.6.0: version "1.6.0" @@ -3301,7 +3719,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.7.0: +convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -3340,35 +3758,35 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== +core-js-compat@^3.6.2, core-js-compat@^3.9.0, core-js-compat@^3.9.1: + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.12.1.tgz#2c302c4708505fa7072b0adb5156d26f7801a18b" + integrity sha512-i6h5qODpw6EsHAoIdQhKoZdWn+dGBF3dSS8m5tif36RlWvW3A6+yu2S16QHUo3CrkzrnEskMAt9f8FxmY9fhWQ== dependencies: - browserslist "^4.8.5" + browserslist "^4.16.6" semver "7.0.0" core-js-pure@^3.0.0: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" - integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.12.1.tgz#934da8b9b7221e2a2443dc71dfa5bd77a7ea00b8" + integrity sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ== -core-js@^2.4.0, core-js@^2.6.10: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== +core-js@^2.4.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-js@^3.5.0: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== +core-js@^3.6.5: + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" + integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.0.0, cosmiconfig@^5.2.1: +cosmiconfig@^5.0.0: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== @@ -3389,13 +3807,24 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" - elliptic "^6.0.0" + elliptic "^6.5.3" create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" @@ -3420,24 +3849,16 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" -create-react-context@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" - integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== - dependencies: - gud "^1.0.0" - warning "^4.0.3" - -cross-spawn@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" - integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== +cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -3448,15 +3869,6 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -3474,6 +3886,11 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + css-blank-pseudo@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" @@ -3502,23 +3919,23 @@ css-has-pseudo@^0.10.0: postcss "^7.0.6" postcss-selector-parser "^5.0.0-rc.4" -css-loader@3.4.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.2.tgz#d3fdb3358b43f233b78501c5ed7b1c6da6133202" - integrity sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA== +css-loader@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.3.0.tgz#c888af64b2a5b2e85462c72c0f4a85c7e2e0821e" + integrity sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg== dependencies: - camelcase "^5.3.1" + camelcase "^6.0.0" cssesc "^3.0.0" icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.23" + loader-utils "^2.0.0" + postcss "^7.0.32" postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.1.1" + postcss-modules-local-by-default "^3.0.3" + postcss-modules-scope "^2.2.0" postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.2" - schema-utils "^2.6.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.1" + semver "^7.3.2" css-prefers-color-scheme@^3.1.1: version "3.1.1" @@ -3532,17 +3949,7 @@ css-select-base-adapter@^0.1.1: resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-select@^2.0.0: +css-select@^2.0.0, css-select@^2.0.2: version "2.1.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== @@ -3560,23 +3967,23 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-tree@1.0.0-alpha.39: - version "1.0.0-alpha.39" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" - integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== +css-tree@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== dependencies: - mdn-data "2.0.6" + mdn-data "2.0.14" source-map "^0.6.1" -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== +css-unit-converter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" + integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== css-what@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" - integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== css@^2.0.0: version "2.2.4" @@ -3603,10 +4010,10 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== +cssnano-preset-default@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" + integrity sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ== dependencies: css-declaration-sorter "^4.0.1" cssnano-util-raw-cache "^4.0.1" @@ -3636,7 +4043,7 @@ cssnano-preset-default@^4.0.7: postcss-ordered-values "^4.1.2" postcss-reduce-initial "^4.0.3" postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" + postcss-svgo "^4.0.3" postcss-unique-selectors "^4.0.1" cssnano-util-get-arguments@^4.0.0: @@ -3662,106 +4069,109 @@ cssnano-util-same-parent@^4.0.0: integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + version "4.1.11" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.11.tgz#c7b5f5b81da269cb1fd982cb960c1200910c9a99" + integrity sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g== dependencies: cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" + cssnano-preset-default "^4.0.8" is-resolvable "^1.0.0" postcss "^7.0.0" csso@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" - integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: - css-tree "1.0.0-alpha.39" + css-tree "^1.1.2" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4: +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^1.0.0, cssstyle@^1.1.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: - cssom "0.3.x" + cssom "~0.3.6" -csstype@^2.2.0: - version "2.6.10" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" - integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== +csstype@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -d3-array@^1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== - -d3-collection@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" - integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== +d3-array@2, d3-array@^2.3.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" -d3-color@1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" - integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== +"d3-color@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== -d3-format@1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.4.tgz#356925f28d0fd7c7983bfad593726fce46844030" - integrity sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw== +"d3-format@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" + integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== -d3-interpolate@1, d3-interpolate@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" - integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== +"d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== dependencies: - d3-color "1" + d3-color "1 - 2" -d3-path@1: - version "1.0.9" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" - integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== +"d3-path@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" + integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== -d3-scale@^2.1.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f" - integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw== +d3-scale@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== dependencies: - d3-array "^1.2.0" - d3-collection "1" - d3-format "1" - d3-interpolate "1" - d3-time "1" - d3-time-format "2" + d3-array "^2.3.0" + d3-format "1 - 2" + d3-interpolate "1.2.0 - 2" + d3-time "^2.1.1" + d3-time-format "2 - 3" -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== +d3-shape@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" + integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== dependencies: - d3-path "1" + d3-path "1 - 2" -d3-time-format@2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.2.3.tgz#0c9a12ee28342b2037e5ea1cf0b9eb4dd75f29cb" - integrity sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA== +"d3-time-format@2 - 3": + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" + integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== dependencies: - d3-time "1" + d3-time "1 - 2" -d3-time@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" - integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== +"d3-time@1 - 2", d3-time@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== + dependencies: + d3-array "2" d@1, d@^1.0.1: version "1.0.1" @@ -3771,10 +4181,10 @@ d@1, d@^1.0.1: es5-ext "^0.10.50" type "^1.0.1" -damerau-levenshtein@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791" - integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug== +damerau-levenshtein@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" + integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== dashdash@^1.12.0: version "1.14.1" @@ -3783,14 +4193,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^1.0.0, data-urls@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" @@ -3799,19 +4209,19 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@^3.1.1, debug@^3.2.5: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== +debug@^3.1.1, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: - ms "^2.1.1" + ms "2.1.2" debug@~3.1.0: version "3.1.0" @@ -3826,14 +4236,14 @@ decamelize@^1.2.0: integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decimal.js-light@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.0.tgz#ca7faf504c799326df94b0ab920424fdfc125348" - integrity sha512-b3VJCbd2hwUpeRGG3Toob+CRo8W22xplipNhP3tN7TSVB/cyMX71P1vM2Xjc9H74uV6dS2hDDmo/rHq8L87Upg== + version "2.5.1" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== -decimal.js@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" - integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== +decimal.js@^10.2.0, decimal.js@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" + integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== decode-uri-component@^0.2.0: version "0.2.0" @@ -3862,11 +4272,16 @@ deep-equal@^1.0.1, deep-equal@^1.1.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + default-gateway@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" @@ -3940,15 +4355,15 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + version "2.0.5" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" + integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== detect-port-alt@1.1.6: version "1.1.6" @@ -3958,10 +4373,10 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== diffie-hellman@^5.0.0: version "5.0.3" @@ -3972,13 +4387,12 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" -dir-glob@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" - integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: - arrify "^1.0.1" - path-type "^3.0.0" + path-type "^4.0.0" dns-equal@^1.0.0: version "1.0.0" @@ -4055,16 +4469,16 @@ domelementtype@1, domelementtype@^1.3.1: integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: - webidl-conversions "^4.0.2" + webidl-conversions "^5.0.0" domhandler@^2.3.0: version "2.4.2" @@ -4073,14 +4487,6 @@ domhandler@^2.3.0: dependencies: domelementtype "1" -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - domutils@^1.5.1, domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" @@ -4089,18 +4495,18 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" -dot-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" - integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== dependencies: - no-case "^3.0.3" - tslib "^1.10.0" + no-case "^3.0.4" + tslib "^2.0.3" dot-prop@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" - integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: is-obj "^2.0.0" @@ -4115,9 +4521,9 @@ dotenv@8.2.0: integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== duplexer@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" @@ -4142,25 +4548,35 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.483: - version "1.3.483" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.483.tgz#9269e7cfc1c8e72709824da171cbe47ca5e3ca9e" - integrity sha512-+05RF8S9rk8S0G8eBCqBRBaRq7+UN3lDs2DAvnG8SBSgQO3hjy0+qt4CmRk5eiuGbTcaicgXfPmBi31a+BD3lg== +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + +electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.723: + version "1.3.727" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz#857e310ca00f0b75da4e1db6ff0e073cc4a91ddf" + integrity sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg== -elliptic@^6.0.0, elliptic@^6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" + bn.js "^4.11.9" + brorand "^1.1.0" hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" -emoji-regex@^7.0.1, emoji-regex@^7.0.2: +emittery@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" + integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== + +emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== @@ -4170,6 +4586,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.0.0: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -4193,48 +4614,48 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: once "^1.4.0" engine.io-client@~3.4.0: - version "3.4.3" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.3.tgz#192d09865403e3097e3575ebfeb3861c4d01a66c" - integrity sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw== + version "3.4.4" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.4.tgz#77d8003f502b0782dd792b073a4d2cf7ca5ab967" + integrity sha512-iU4CRr38Fecj8HoZEnFtm2EiKGbYZcPn3cHxqNGl/tmdWRf60KhK+9vE0JeSjgnlS/0oynEfLgKbT9ALpim0sQ== dependencies: component-emitter "~1.3.0" component-inherit "0.0.3" - debug "~4.1.0" + debug "~3.1.0" engine.io-parser "~2.2.0" has-cors "1.1.0" indexof "0.0.1" - parseqs "0.0.5" - parseuri "0.0.5" + parseqs "0.0.6" + parseuri "0.0.6" ws "~6.1.0" xmlhttprequest-ssl "~1.5.4" yeast "0.1.2" engine.io-parser@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" - integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + version "2.2.1" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.1.tgz#57ce5611d9370ee94f99641b589f94c97e4f5da7" + integrity sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg== dependencies: after "0.8.2" arraybuffer.slice "~0.0.7" - base64-arraybuffer "0.1.5" + base64-arraybuffer "0.1.4" blob "0.0.5" has-binary2 "~1.0.2" -enhanced-resolve@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d" - integrity sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ== +enhanced-resolve@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" tapable "^1.0.0" -enquirer@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.5.tgz#3ab2b838df0a9d8ab9e7dff235b0e8712ef92381" - integrity sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA== +enquirer@^2.3.5, enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: - ansi-colors "^3.2.1" + ansi-colors "^4.1.1" entities@^1.1.1: version "1.1.2" @@ -4242,14 +4663,14 @@ entities@^1.1.1: integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== entities@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" - integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -4260,22 +4681,34 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== +error-stack-parser@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + dependencies: + stackframe "^1.1.1" + +es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + get-intrinsic "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.2" + is-string "^1.0.5" + object-inspect "^1.9.0" object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -4312,10 +4745,10 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3: d "^1.0.1" ext "^1.1.2" -escalade@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.1.tgz#52568a77443f6927cd0ab9c73129137533c965ed" - integrity sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA== +escalade@^3.0.2, escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@~1.0.3: version "1.0.3" @@ -4327,36 +4760,36 @@ escape-latex@^1.2.0: resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== -escape-string-regexp@2.0.0: +escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^1.11.0, escodegen@^1.9.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: esprima "^4.0.1" - estraverse "^4.2.0" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" -eslint-config-react-app@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df" - integrity sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ== +eslint-config-react-app@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz#ccff9fc8e36b322902844cbd79197982be355a0e" + integrity sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A== dependencies: - confusing-browser-globals "^1.0.9" + confusing-browser-globals "^1.0.10" -eslint-import-resolver-node@^0.3.2: +eslint-import-resolver-node@^0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== @@ -4364,18 +4797,7 @@ eslint-import-resolver-node@^0.3.2: debug "^2.6.9" resolve "^1.13.1" -eslint-loader@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-3.0.3.tgz#e018e3d2722381d982b1201adb56819c73b480ca" - integrity sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw== - dependencies: - fs-extra "^8.1.0" - loader-fs-cache "^1.0.2" - loader-utils "^1.2.3" - object-hash "^2.0.1" - schema-utils "^2.6.1" - -eslint-module-utils@^2.4.1: +eslint-module-utils@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== @@ -4383,68 +4805,86 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-flowtype@4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz#82b2bd6f21770e0e5deede0228e456cb35308451" - integrity sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ== +eslint-plugin-flowtype@^5.2.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.7.2.tgz#482a42fe5d15ee614652ed256d37543d584d7bc0" + integrity sha512-7Oq/N0+3nijBnYWQYzz/Mp/7ZCpwxYvClRyW/PLAmimY9uLCBvoXsNsERcJdkKceyOjgRbFhhxs058KTrne9Mg== dependencies: lodash "^4.17.15" + string-natural-compare "^3.0.1" -eslint-plugin-import@2.20.1: - version "2.20.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" - integrity sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== +eslint-plugin-import@^2.22.1: + version "2.22.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" + integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" + array-includes "^3.1.1" + array.prototype.flat "^1.2.3" contains-path "^0.1.0" debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.1" + eslint-import-resolver-node "^0.3.4" + eslint-module-utils "^2.6.0" has "^1.0.3" minimatch "^3.0.4" - object.values "^1.1.0" + object.values "^1.1.1" read-pkg-up "^2.0.0" - resolve "^1.12.0" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" -eslint-plugin-jsx-a11y@6.2.3: - version "6.2.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa" - integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg== +eslint-plugin-jest@^24.1.0: + version "24.3.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz#5f0ca019183c3188c5ad3af8e80b41de6c8e9173" + integrity sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg== + dependencies: + "@typescript-eslint/experimental-utils" "^4.0.1" + +eslint-plugin-jsx-a11y@^6.3.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" + integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== dependencies: - "@babel/runtime" "^7.4.5" - aria-query "^3.0.0" - array-includes "^3.0.3" + "@babel/runtime" "^7.11.2" + aria-query "^4.2.2" + array-includes "^3.1.1" ast-types-flow "^0.0.7" - axobject-query "^2.0.2" - damerau-levenshtein "^1.0.4" - emoji-regex "^7.0.2" + axe-core "^4.0.2" + axobject-query "^2.2.0" + damerau-levenshtein "^1.0.6" + emoji-regex "^9.0.0" has "^1.0.3" - jsx-ast-utils "^2.2.1" + jsx-ast-utils "^3.1.0" + language-tags "^1.0.5" -eslint-plugin-react-hooks@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" - integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== +eslint-plugin-react-hooks@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" + integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== -eslint-plugin-react@7.19.0: - version "7.19.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666" - integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ== +eslint-plugin-react@^7.21.5: + version "7.23.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz#2d2291b0f95c03728b55869f01102290e792d494" + integrity sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw== dependencies: - array-includes "^3.1.1" + array-includes "^3.1.3" + array.prototype.flatmap "^1.2.4" doctrine "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.2.3" - object.entries "^1.1.1" - object.fromentries "^2.0.2" - object.values "^1.1.1" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.0.4" + object.entries "^1.1.3" + object.fromentries "^2.0.4" + object.values "^1.1.3" prop-types "^15.7.2" - resolve "^1.15.1" - semver "^6.3.0" - string.prototype.matchall "^4.0.2" - xregexp "^4.3.0" + resolve "^2.0.0-next.3" + string.prototype.matchall "^4.0.4" + +eslint-plugin-testing-library@^3.9.2: + version "3.10.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz#609ec2b0369da7cf2e6d9edff5da153cc31d87bd" + integrity sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA== + dependencies: + "@typescript-eslint/experimental-utils" "^3.10.1" eslint-scope@^4.0.3: version "4.0.3" @@ -4454,113 +4894,133 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== +eslint-scope@^5.0.0, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^2.0.0: +eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint@^6.6.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-webpack-plugin@^2.5.2: + version "2.5.4" + resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-2.5.4.tgz#473b84932f1a8e2c2b8e66a402d0497bf440b986" + integrity sha512-7rYh0m76KyKSDE+B+2PUQrlNS4HJ51t3WKpkJg6vo2jFMbEPTG99cBV0Dm7LXSHucN4WGCG65wQcRiTFrj7iWw== dependencies: - "@babel/code-frame" "^7.0.0" + "@types/eslint" "^7.2.6" + arrify "^2.0.1" + jest-worker "^26.6.2" + micromatch "^4.0.2" + normalize-path "^3.0.0" + schema-utils "^3.0.0" + +eslint@^7.11.0: + version "7.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.26.0.tgz#d416fdcdcb3236cd8f282065312813f8c13982f6" + integrity sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.1" ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" + chalk "^4.0.0" + cross-spawn "^7.0.2" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" + file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" - globals "^12.1.0" + globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" + levn "^0.4.1" + lodash "^4.17.21" minimatch "^3.0.4" - mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.3" + optionator "^0.9.1" progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.4" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" - integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== esutils@^2.0.2: version "2.0.3" @@ -4572,20 +5032,20 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -eventemitter3@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== +eventemitter3@^4.0.0, eventemitter3@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" - integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf" + integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg== dependencies: original "^1.0.0" @@ -4598,9 +5058,9 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: safe-buffer "^5.1.1" exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== execa@^1.0.0: version "1.0.0" @@ -4615,10 +5075,10 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.2.tgz#ad87fb7b2d9d564f70d2b62d511bee41d5cbb240" - integrity sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q== +execa@^4.0.0, execa@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -4648,17 +5108,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" - integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== +expect@^26.6.0, expect@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" + integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== dependencies: - "@jest/types" "^24.9.0" - ansi-styles "^3.2.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.9.0" + "@jest/types" "^26.6.2" + ansi-styles "^4.0.0" + jest-get-type "^26.3.0" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" express@^4.17.1: version "4.17.1" @@ -4723,15 +5183,6 @@ extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -4761,36 +5212,41 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^2.0.2: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" +fast-equals@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.2.tgz#f4029b437d9e8184b807233bdbcd371e3bc73cf7" + integrity sha512-ehHsR38w6sqy5E0QrWQxclb+zl3ulNsgCVWt1cMoZ6QBFgtkr4lKZWpQP1kfEFn6bWnm78pmiDGak+zUvQ2/DQ== + +fast-glob@^3.1.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= +fastq@^1.6.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== dependencies: - websocket-driver ">=0.5.1" + reusify "^1.0.4" -faye-websocket@~0.11.1: +faye-websocket@^0.11.3: version "0.11.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== @@ -4809,27 +5265,27 @@ figgy-pudding@^3.5.1: resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== -figures@^3.0.0, figures@^3.2.0: +figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: - flat-cache "^2.0.1" + flat-cache "^3.0.4" -file-loader@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" - integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== +file-loader@6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.1.1.tgz#a6f29dfb3f5933a1c350b2dbaa20ac5be0539baa" + integrity sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw== dependencies: - loader-utils "^1.2.3" - schema-utils "^2.5.0" + loader-utils "^2.0.0" + schema-utils "^3.0.0" file-saver@^1.3.3: version "1.3.8" @@ -4841,10 +5297,10 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filesize@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.0.1.tgz#f850b509909c7c86f7e450ea19006c31c2ed3d2f" - integrity sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg== +filesize@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" + integrity sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg== fill-range@^4.0.0: version "4.0.0" @@ -4876,15 +5332,6 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -4894,7 +5341,7 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.2.0: +find-cache-dir@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== @@ -4903,7 +5350,7 @@ find-cache-dir@^3.2.0: make-dir "^3.0.2" pkg-dir "^4.1.0" -find-up@4.1.0, find-up@^4.0.0: +find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -4911,14 +5358,6 @@ find-up@4.1.0, find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -4940,19 +5379,18 @@ find-versions@^3.2.0: dependencies: semver-regex "^2.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + flatted "^3.1.0" + rimraf "^3.0.2" -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== flatten@^1.0.2: version "1.0.3" @@ -4968,40 +5406,27 @@ flush-write-stream@^1.0.0: readable-stream "^2.3.6" follow-redirects@^1.0.0: - version "1.12.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6" - integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg== - -for-in@^0.1.3: - version "0.1.8" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" - integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== -for-in@^1.0.1, for-in@^1.0.2: +for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= - dependencies: - for-in "^1.0.1" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -fork-ts-checker-webpack-plugin@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" - integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ== +fork-ts-checker-webpack-plugin@4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" + integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== dependencies: - babel-code-frame "^6.22.0" + "@babel/code-frame" "^7.5.5" chalk "^2.4.1" - chokidar "^3.3.0" micromatch "^3.1.10" minimatch "^3.0.4" semver "^5.6.0" @@ -5023,9 +5448,9 @@ forwarded@~0.1.2: integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fraction.js@^4.0.12: - version "4.0.12" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.12.tgz#0526d47c65a5fb4854df78bc77f7bec708d7b8c3" - integrity sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA== + version "4.0.13" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" + integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== fragment-cache@^0.2.1: version "0.2.1" @@ -5047,15 +5472,6 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" -fs-extra@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -5074,6 +5490,16 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -5096,11 +5522,6 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" - integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== - fsevents@^1.2.7: version "1.2.13" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" @@ -5109,12 +5530,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -fsevents@~2.3.1: +fsevents@^2.1.2, fsevents@^2.1.3, fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -5129,26 +5545,35 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -5157,9 +5582,9 @@ get-stream@^4.0.0: pump "^3.0.0" get-stream@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" - integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" @@ -5183,22 +5608,17 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -5235,18 +5655,36 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -globby@8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" - integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== +globals@^13.6.0: + version "13.8.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.8.0.tgz#3e20f504810ce87a8d72e55aecf8435b50f4c1b3" + integrity sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q== dependencies: - array-union "^1.0.1" - dir-glob "2.0.0" - fast-glob "^2.0.2" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" + type-fest "^0.20.2" + +globby@11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" + integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +globby@^11.0.1: + version "11.0.3" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" + integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" globby@^6.1.0: version "6.1.0" @@ -5259,10 +5697,10 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== growly@^1.3.0: version "1.3.0" @@ -5293,24 +5731,22 @@ har-schema@^2.0.0: integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: - ajv "^6.5.5" + ajv "^6.12.3" har-schema "^2.0.0" harmony-reflect@^1.4.6: - version "1.6.1" - resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" - integrity sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA== + version "1.6.2" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== has-binary2@~1.0.2: version "1.0.3" @@ -5334,10 +5770,10 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has-value@^0.3.1: version "0.3.1" @@ -5416,7 +5852,7 @@ history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -hmac-drbg@^1.0.0: +hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= @@ -5425,17 +5861,22 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: react-is "^16.7.0" +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hpack.js@^2.1.6: version "2.1.6" @@ -5457,22 +5898,17 @@ hsla-regex@^1.0.0: resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== dependencies: - whatwg-encoding "^1.0.1" + whatwg-encoding "^1.0.5" -html-entities@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" - integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== +html-entities@^1.2.1, html-entities@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== html-escaper@^2.0.0: version "2.0.2" @@ -5492,11 +5928,14 @@ html-minifier-terser@^5.0.1: relateurl "^0.2.7" terser "^4.6.3" -html-webpack-plugin@4.0.0-beta.11: - version "4.0.0-beta.11" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz#3059a69144b5aecef97708196ca32f9e68677715" - integrity sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg== +html-webpack-plugin@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c" + integrity sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw== dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" html-minifier-terser "^5.0.1" loader-utils "^1.2.3" lodash "^4.17.15" @@ -5504,7 +5943,7 @@ html-webpack-plugin@4.0.0-beta.11: tapable "^1.1.3" util.promisify "1.0.0" -htmlparser2@^3.3.0: +htmlparser2@^3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== @@ -5554,9 +5993,9 @@ http-errors@~1.7.2: toidentifier "1.0.0" http-parser-js@>=0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" - integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ== + version "0.5.3" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" + integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== http-proxy-middleware@0.19.1: version "0.19.1" @@ -5612,7 +6051,7 @@ husky@~4.2.5: slash "^3.0.0" which-pm-runs "^1.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5634,29 +6073,29 @@ identity-obj-proxy@3.0.0: harmony-reflect "^1.4.6" ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== - ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -immer@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" - integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg== +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +immer@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" + integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== import-cwd@^2.0.0: version "2.1.0" @@ -5673,10 +6112,10 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -5696,6 +6135,14 @@ import-local@^2.0.0: pkg-dir "^3.0.0" resolve-cwd "^2.0.0" +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -5745,47 +6192,9 @@ inherits@2.0.3: integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" - integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^2.4.2" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.2.0" - rxjs "^6.5.3" - string-width "^4.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - -inquirer@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.2.0.tgz#63ce99d823090de7eb420e4bb05e6f3449aa389a" - integrity sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^3.0.0" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.5.3" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== internal-ip@^4.3.0: version "4.3.0" @@ -5795,26 +6204,19 @@ internal-ip@^4.3.0: default-gateway "^4.2.0" ipaddr.js "^1.9.0" -internal-slot@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3" - integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g== +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== dependencies: - es-abstract "^1.17.0-next.1" + get-intrinsic "^1.1.0" has "^1.0.3" - side-channel "^1.0.2" - -invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" + side-channel "^1.0.4" -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== ip-regex@^2.1.0: version "2.1.0" @@ -5856,9 +6258,11 @@ is-accessor-descriptor@^1.0.0: kind-of "^6.0.0" is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" @@ -5870,6 +6274,11 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -5884,15 +6293,22 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^1.0.2, is-buffer@^1.1.5: +is-boolean-object@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + dependencies: + call-bind "^1.0.2" + +is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" - integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-ci@^2.0.0: version "2.0.0" @@ -5913,6 +6329,13 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" +is-core-module@^2.0.0, is-core-module@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -5928,9 +6351,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-descriptor@^0.1.0: version "0.1.6" @@ -5956,9 +6379,9 @@ is-directory@^0.3.1: integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= is-docker@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" - integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" @@ -5977,13 +6400,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -6013,6 +6429,21 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-object@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -6059,19 +6490,25 @@ is-plain-obj@^1.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" - integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== +is-potential-custom-element-name@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-regex@^1.0.4, is-regex@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== dependencies: - has-symbols "^1.0.1" + call-bind "^1.0.2" + has-symbols "^1.0.2" is-regexp@^1.0.0: version "1.0.0" @@ -6099,29 +6536,27 @@ is-stream@^2.0.0: integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== - dependencies: - html-comment-regex "^1.1.0" + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.1" + has-symbols "^1.0.2" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -6132,7 +6567,7 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.1.1: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -6176,420 +6611,462 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" +istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" -istanbul-lib-report@^2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" -istanbul-lib-source-maps@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" + istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== dependencies: html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" javascript-natural-sort@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k= -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== +jest-changed-files@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" + integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" + "@jest/types" "^26.6.2" + execa "^4.0.0" + throat "^5.0.0" -jest-cli@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" - integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== +jest-circus@26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-26.6.0.tgz#7d9647b2e7f921181869faae1f90a2629fd70705" + integrity sha512-L2/Y9szN6FJPWFK8kzWXwfp+FOR7xq0cUL4lIsdbIdwz3Vh6P1nrpcqOleSzr28zOtSHQNV9Z7Tl+KkuK7t5Ng== dependencies: - "@jest/core" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@babel/traverse" "^7.1.0" + "@jest/environment" "^26.6.0" + "@jest/test-result" "^26.6.0" + "@jest/types" "^26.6.0" + "@types/babel__traverse" "^7.0.4" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^26.6.0" + is-generator-fn "^2.0.0" + jest-each "^26.6.0" + jest-matcher-utils "^26.6.0" + jest-message-util "^26.6.0" + jest-runner "^26.6.0" + jest-runtime "^26.6.0" + jest-snapshot "^26.6.0" + jest-util "^26.6.0" + pretty-format "^26.6.0" + stack-utils "^2.0.2" + throat "^5.0.0" + +jest-cli@^26.6.0: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" + integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== + dependencies: + "@jest/core" "^26.6.3" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + chalk "^4.0.0" exit "^0.1.2" - import-local "^2.0.0" + graceful-fs "^4.2.4" + import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" + jest-config "^26.6.3" + jest-util "^26.6.2" + jest-validate "^26.6.2" prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^13.3.0" + yargs "^15.4.1" -jest-config@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" - integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== +jest-config@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" + integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.9.0" - "@jest/types" "^24.9.0" - babel-jest "^24.9.0" - chalk "^2.0.1" + "@jest/test-sequencer" "^26.6.3" + "@jest/types" "^26.6.2" + babel-jest "^26.6.3" + chalk "^4.0.0" + deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^24.9.0" - jest-environment-node "^24.9.0" - jest-get-type "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - micromatch "^3.1.10" - pretty-format "^24.9.0" - realpath-native "^1.1.0" - -jest-diff@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-docblock@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" - integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== - dependencies: - detect-newline "^2.1.0" - -jest-each@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" - integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== - dependencies: - "@jest/types" "^24.9.0" - chalk "^2.0.1" - jest-get-type "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" + graceful-fs "^4.2.4" + jest-environment-jsdom "^26.6.2" + jest-environment-node "^26.6.2" + jest-get-type "^26.3.0" + jest-jasmine2 "^26.6.3" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + micromatch "^4.0.2" + pretty-format "^26.6.2" -jest-environment-jsdom-fourteen@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" - integrity sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q== +jest-diff@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== dependencies: - "@jest/environment" "^24.3.0" - "@jest/fake-timers" "^24.3.0" - "@jest/types" "^24.3.0" - jest-mock "^24.0.0" - jest-util "^24.0.0" - jsdom "^14.1.0" + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" -jest-environment-jsdom@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" - integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== +jest-docblock@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" + integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - jsdom "^11.5.1" + detect-newline "^3.0.0" -jest-environment-node@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" - integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== +jest-each@^26.6.0, jest-each@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" + integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" + "@jest/types" "^26.6.2" + chalk "^4.0.0" + jest-get-type "^26.3.0" + jest-util "^26.6.2" + pretty-format "^26.6.2" + +jest-environment-jsdom@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" + integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + jest-util "^26.6.2" + jsdom "^16.4.0" + +jest-environment-node@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" + integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + jest-util "^26.6.2" -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" - integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== dependencies: - "@jest/types" "^24.9.0" - anymatch "^2.0.0" + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.9.0" - micromatch "^3.1.10" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" optionalDependencies: - fsevents "^1.2.7" + fsevents "^2.1.2" -jest-jasmine2@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" - integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== +jest-jasmine2@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" + integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@jest/environment" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" co "^4.6.0" - expect "^24.9.0" + expect "^26.6.2" is-generator-fn "^2.0.0" - jest-each "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - throat "^4.0.0" - -jest-leak-detector@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" - integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== - dependencies: - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-matcher-utils@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" - integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + jest-each "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + pretty-format "^26.6.2" + throat "^5.0.0" + +jest-leak-detector@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" + integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== + dependencies: + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-matcher-utils@^26.6.0, jest-matcher-utils@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" + integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== dependencies: - chalk "^2.0.1" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" + chalk "^4.0.0" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" -jest-message-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" - integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== +jest-message-util@^26.6.0, jest-message-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" + integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" + "@jest/types" "^26.6.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.2" + pretty-format "^26.6.2" + slash "^3.0.0" + stack-utils "^2.0.2" -jest-mock@^24.0.0, jest-mock@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" - integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== +jest-mock@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" + integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== dependencies: - "@jest/types" "^24.9.0" + "@jest/types" "^26.6.2" + "@types/node" "*" -jest-pnp-resolver@^1.2.1: +jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" - integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-resolve-dependencies@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" - integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== +jest-resolve-dependencies@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" + integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== dependencies: - "@jest/types" "^24.9.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.9.0" + "@jest/types" "^26.6.2" + jest-regex-util "^26.0.0" + jest-snapshot "^26.6.2" -jest-resolve@24.9.0, jest-resolve@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" - integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== +jest-resolve@26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.0.tgz#070fe7159af87b03e50f52ea5e17ee95bbee40e1" + integrity sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ== + dependencies: + "@jest/types" "^26.6.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + jest-pnp-resolver "^1.2.2" + jest-util "^26.6.0" + read-pkg-up "^7.0.1" + resolve "^1.17.0" + slash "^3.0.0" + +jest-resolve@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" + integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== dependencies: - "@jest/types" "^24.9.0" - browser-resolve "^1.11.3" - chalk "^2.0.1" - jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" + "@jest/types" "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + jest-pnp-resolver "^1.2.2" + jest-util "^26.6.2" + read-pkg-up "^7.0.1" + resolve "^1.18.1" + slash "^3.0.0" -jest-runner@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" - integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== +jest-runner@^26.6.0, jest-runner@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" + integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.4.2" + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.7.1" exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-docblock "^24.3.0" - jest-haste-map "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-leak-detector "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" + graceful-fs "^4.2.4" + jest-config "^26.6.3" + jest-docblock "^26.0.0" + jest-haste-map "^26.6.2" + jest-leak-detector "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" + jest-runtime "^26.6.3" + jest-util "^26.6.2" + jest-worker "^26.6.2" source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" - integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - chalk "^2.0.1" + throat "^5.0.0" + +jest-runtime@^26.6.0, jest-runtime@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" + integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/globals" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + cjs-module-lexer "^0.6.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^13.3.0" + graceful-fs "^4.2.4" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^15.4.1" -jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" -jest-snapshot@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" - integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== +jest-snapshot@^26.6.0, jest-snapshot@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" + integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - expect "^24.9.0" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - mkdirp "^0.5.1" + "@jest/types" "^26.6.2" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.0.0" + chalk "^4.0.0" + expect "^26.6.2" + graceful-fs "^4.2.4" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + jest-haste-map "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" natural-compare "^1.4.0" - pretty-format "^24.9.0" - semver "^6.2.0" + pretty-format "^26.6.2" + semver "^7.3.2" -jest-util@^24.0.0, jest-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" - integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== - dependencies: - "@jest/console" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/source-map" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" +jest-util@^26.6.0, jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" + micromatch "^4.0.2" -jest-validate@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== +jest-validate@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" + integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" + "@jest/types" "^26.6.2" + camelcase "^6.0.0" + chalk "^4.0.0" + jest-get-type "^26.3.0" leven "^3.1.0" - pretty-format "^24.9.0" + pretty-format "^26.6.2" -jest-watch-typeahead@0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" - integrity sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q== +jest-watch-typeahead@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.6.1.tgz#45221b86bb6710b7e97baaa1640ae24a07785e63" + integrity sha512-ITVnHhj3Jd/QkqQcTqZfRgjfyRhDFM/auzgVo2RKvSwi18YMvh0WvXDJFoFED6c7jd/5jxtu4kSOb9PTu2cPVg== dependencies: - ansi-escapes "^4.2.1" - chalk "^2.4.1" - jest-regex-util "^24.9.0" - jest-watcher "^24.3.0" + ansi-escapes "^4.3.1" + chalk "^4.0.0" + jest-regex-util "^26.0.0" + jest-watcher "^26.3.0" slash "^3.0.0" - string-length "^3.1.0" - strip-ansi "^5.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" -jest-watcher@^24.3.0, jest-watcher@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" - integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== - dependencies: - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.9.0" - string-length "^2.0.0" - -jest-worker@^24.6.0, jest-worker@^24.9.0: +jest-watcher@^26.3.0, jest-watcher@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" + integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== + dependencies: + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^26.6.2" + string-length "^4.0.1" + +jest-worker@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== @@ -6597,36 +7074,33 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest-worker@^25.1.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" - integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== +jest-worker@^26.5.0, jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: + "@types/node" "*" merge-stream "^2.0.0" supports-color "^7.0.0" -jest@24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" - integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== +jest@26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.0.tgz#546b25a1d8c888569dbbe93cae131748086a4a25" + integrity sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA== dependencies: - import-local "^2.0.0" - jest-cli "^24.9.0" + "@jest/core" "^26.6.0" + import-local "^3.0.2" + jest-cli "^26.6.0" "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -6636,68 +7110,36 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" - xml-name-validator "^3.0.0" - -jsdom@^14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.1.0.tgz#916463b6094956b0a6c1782c94e380cd30e1981b" - integrity sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng== - dependencies: - abab "^2.0.0" - acorn "^6.0.4" - acorn-globals "^4.3.0" - array-equal "^1.0.0" - cssom "^0.3.4" - cssstyle "^1.1.1" - data-urls "^1.1.0" - domexception "^1.0.1" - escodegen "^1.11.0" - html-encoding-sniffer "^1.0.2" - nwsapi "^2.1.3" - parse5 "5.1.0" - pn "^1.1.0" - request "^2.88.0" - request-promise-native "^1.0.5" - saxes "^3.1.9" - symbol-tree "^3.2.2" - tough-cookie "^2.5.0" - w3c-hr-time "^1.0.1" - w3c-xmlserializer "^1.1.2" - webidl-conversions "^4.0.2" +jsdom@^16.4.0: + version "16.5.3" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" + integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== + dependencies: + abab "^2.0.5" + acorn "^8.1.0" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" + nwsapi "^2.2.0" + parse5 "6.0.1" + request "^2.88.2" + request-promise-native "^1.0.9" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^7.0.0" - ws "^6.1.2" + whatwg-url "^8.5.0" + ws "^7.4.4" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -6715,11 +7157,21 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -6730,19 +7182,12 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json3@^3.3.2: +json3@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== @@ -6755,9 +7200,9 @@ json5@^1.0.1: minimist "^1.2.0" json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" @@ -6768,10 +7213,14 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" jsprim@^1.2.2: version "1.4.1" @@ -6783,26 +7232,19 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: - version "2.4.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz#1114a4c1209481db06c690c2b4f488cc665f657e" - integrity sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w== +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" + integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== dependencies: - array-includes "^3.1.1" - object.assign "^4.1.0" + array-includes "^3.1.2" + object.assign "^4.1.2" killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== -kind-of@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" - integrity sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU= - dependencies: - is-buffer "^1.0.2" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -6832,10 +7274,27 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -konva@~6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/konva/-/konva-6.0.0.tgz#9b3d13a4622f353c4ce736fbf1fa4b6483240649" - integrity sha512-YTwmtz3KzbzdC0KDRHWLzuk0KXB4NUdaQqytrxacXE1C39V6wCk7Nnu0wgq+GdGbG6m8A1qiEU9TSJ19qdIzDw== +klona@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" + integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + +konva@~7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/konva/-/konva-7.2.5.tgz#9b4ac3a353e6be66e3e69123bf2a0cbc61efeb26" + integrity sha512-yk/li8rUF+09QNlOdkwbEId+QvfATMe/aMGVouWW1oFoUVTYWHsQuIAE6lWy11DK8mLJEJijkNAXC5K+NVlMew== + +language-subtag-registry@~0.3.2: + version "0.3.21" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" + integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== + +language-tags@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= + dependencies: + language-subtag-registry "~0.3.2" last-call-webpack-plugin@^3.0.0: version "3.0.0" @@ -6845,41 +7304,20 @@ last-call-webpack-plugin@^3.0.0: lodash "^4.17.5" webpack-sources "^1.1.0" -lazy-cache@^0.2.3: - version "0.2.7" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" - integrity sha1-f+3fLctu23fRHvHRF6tf/fCrG2U= - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: - leven "^3.1.0" + prelude-ls "^1.2.1" + type-check "~0.4.0" -levn@^0.3.0, levn@~0.3.0: +levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= @@ -6893,19 +7331,19 @@ lines-and-columns@^1.1.6: integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= lint-staged@~10.2.2: - version "10.2.11" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.11.tgz#713c80877f2dc8b609b05bc59020234e766c9720" - integrity sha512-LRRrSogzbixYaZItE2APaS4l2eJMjjf5MbclRZpLJtcQJShcvUzKXsNeZgsLIZ0H0+fg2tL4B59fU9wHIHtFIA== + version "10.2.13" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.13.tgz#b9c504683470edfc464b7d3fe3845a5a1efcd814" + integrity sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA== dependencies: - chalk "^4.0.0" - cli-truncate "2.1.0" - commander "^5.1.0" - cosmiconfig "^6.0.0" + chalk "^4.1.0" + cli-truncate "^2.1.0" + commander "^6.0.0" + cosmiconfig "^7.0.0" debug "^4.1.1" dedent "^0.7.0" - enquirer "^2.3.5" - execa "^4.0.1" - listr2 "^2.1.0" + enquirer "^2.3.6" + execa "^4.0.3" + listr2 "^2.6.0" log-symbols "^4.0.0" micromatch "^4.0.2" normalize-path "^3.0.0" @@ -6913,18 +7351,18 @@ lint-staged@~10.2.2: string-argv "0.3.1" stringify-object "^3.3.0" -listr2@^2.1.0: - version "2.1.8" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.1.8.tgz#8af7ebc70cdbe866ddbb6c80909142bd45758f1f" - integrity sha512-Op+hheiChfAphkJ5qUxZtHgyjlX9iNnAeFS/S134xw7mVSg0YVrQo1IY4/K+ElY6XgOPg2Ij4z07urUXR+YEew== +listr2@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" + integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== dependencies: - chalk "^4.0.0" + chalk "^4.1.0" cli-truncate "^2.1.0" figures "^3.2.0" indent-string "^4.0.0" log-update "^4.0.0" p-map "^4.0.0" - rxjs "^6.5.5" + rxjs "^6.6.2" through "^2.3.8" load-json-file@^2.0.0: @@ -6937,24 +7375,6 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -loader-fs-cache@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" - integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA== - dependencies: - find-cache-dir "^0.1.1" - mkdirp "^0.5.1" - loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" @@ -6969,6 +7389,15 @@ loader-utils@1.2.3: emojis-list "^2.0.0" json5 "^1.0.1" +loader-utils@2.0.0, loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" @@ -7006,6 +7435,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -7016,12 +7450,7 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - -lodash.template@^4.4.0, lodash.template@^4.5.0: +lodash.template@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== @@ -7041,27 +7470,28 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -lodash@~4.17.4: - version "4.17.19" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" - integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== +"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: - chalk "^4.0.0" + chalk "^4.1.0" + is-unicode-supported "^0.1.0" log-update@^4.0.0: version "4.0.0" @@ -7073,10 +7503,10 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loglevel@^1.6.6: - version "1.6.8" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" - integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== +loglevel@^1.6.8: + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" @@ -7085,12 +7515,12 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3 dependencies: js-tokens "^3.0.0 || ^4.0.0" -lower-case@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" - integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== dependencies: - tslib "^1.10.0" + tslib "^2.0.3" lru-cache@^5.1.1: version "5.1.1" @@ -7099,7 +7529,21 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -make-dir@^2.0.0, make-dir@^2.1.0: +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.25.0, magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +make-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -7107,7 +7551,7 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.2: +make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -7121,18 +7565,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -7145,11 +7577,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -math-expression-evaluator@^1.2.14: - version "1.2.22" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.22.tgz#c14dcb3d8b4d150e5dcea9c68c8dad80309b0d5e" - integrity sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ== - mathjs@~7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-7.1.0.tgz#83226e336b8b258b046a139865373e667db94afb" @@ -7173,30 +7600,21 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== -mdn-data@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" - integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -7213,15 +7631,6 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -merge-deep@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.2.tgz#f39fa100a4f1bd34ff29f7d2bf4508fbb8d83ad2" - integrity sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA== - dependencies: - arr-union "^3.1.0" - clone-deep "^0.2.4" - kind-of "^3.0.2" - merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -7232,7 +7641,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3: +merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -7267,12 +7676,12 @@ micromatch@^3.1.10, micromatch@^3.1.4: to-regex "^3.0.2" micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: braces "^3.0.1" - picomatch "^2.0.5" + picomatch "^2.2.3" miller-rabin@^4.0.0: version "4.0.1" @@ -7282,17 +7691,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.47.0, "mime-db@>= 1.43.0 < 2": + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== dependencies: - mime-db "1.44.0" + mime-db "1.47.0" mime@1.6.0: version "1.6.0" @@ -7300,11 +7709,11 @@ mime@1.6.0: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.4: - version "2.4.6" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" - integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== -mimic-fn@^2.0.0, mimic-fn@^2.1.0: +mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -7317,10 +7726,10 @@ mini-create-react-context@^0.3.0: "@babel/runtime" "^7.12.1" tiny-warning "^1.0.3" -mini-css-extract-plugin@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" - integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A== +mini-css-extract-plugin@0.11.3: + version "0.11.3" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz#15b0910a7f32e62ffde4a7430cfefbd700724ea6" + integrity sha512-n9BA8LonkOkW1/zn+IbLPQmovsL0wMb9yx75fMJQZf2X1Zoec9yTZtyMePcyu19wPkmFbzZZA6fLTotpFhQsOA== dependencies: loader-utils "^1.1.0" normalize-url "1.9.1" @@ -7332,7 +7741,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: +minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= @@ -7364,9 +7773,9 @@ minipass-flush@^1.0.5: minipass "^3.0.0" minipass-pipeline@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz#55f7839307d74859d6e8ada9c3ebe72cec216a34" - integrity sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ== + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" @@ -7377,6 +7786,14 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -7401,21 +7818,18 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mixin-object@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" - integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= - dependencies: - for-in "^0.1.3" - is-extendable "^0.1.1" - -mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -7438,11 +7852,16 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -7456,15 +7875,15 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - nan@^2.12.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + +nanoid@^3.1.22: + version "3.1.22" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" + integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== nanomatch@^1.2.9: version "1.2.13" @@ -7483,6 +7902,13 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +native-url@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.2.6.tgz#ca1258f5ace169c716ff44eccbddb674e10399ae" + integrity sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA== + dependencies: + querystring "^0.2.0" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -7493,10 +7919,10 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.5.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== next-tick@~1.0.0: version "1.0.0" @@ -7508,18 +7934,18 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -no-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" - integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== dependencies: - lower-case "^2.0.1" - tslib "^1.10.0" + lower-case "^2.0.2" + tslib "^2.0.3" -node-forge@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" - integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-int64@^0.4.0: version "0.4.0" @@ -7560,23 +7986,24 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== +node-notifier@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" + integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== dependencies: growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" + is-wsl "^2.2.0" + semver "^7.3.2" shellwords "^0.1.1" - which "^1.3.0" + uuid "^8.3.0" + which "^2.0.2" -node-releases@^1.1.52, node-releases@^1.1.58: - version "1.1.58" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.58.tgz#8ee20eef30fa60e52755fcc0942def5a734fe935" - integrity sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg== +node-releases@^1.1.61, node-releases@^1.1.71: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== -normalize-package-data@^2.3.2: +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -7632,7 +8059,7 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -nth-check@^1.0.2, nth-check@~1.0.1: +nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== @@ -7644,12 +8071,7 @@ num2fraction@^1.2.2: resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -nwsapi@^2.0.7, nwsapi@^2.1.3: +nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -7664,11 +8086,6 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-component@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" - integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= - object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -7678,34 +8095,24 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-hash@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" - integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== - -object-inspect@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== +object-inspect@^1.9.0: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== object-is@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" - integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.5" -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-path@0.11.4: - version "0.11.4" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -7713,42 +8120,44 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" -object.entries@^1.1.0, object.entries@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add" - integrity sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA== +object.entries@^1.1.0, object.entries@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" + integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.5" + es-abstract "^1.18.0-next.1" has "^1.0.3" -object.fromentries@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" - integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== +object.fromentries@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8" + integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" + es-abstract "^1.18.0-next.2" has "^1.0.3" object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + version "2.1.2" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" + integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.2" object.pick@^1.3.0: version "1.3.0" @@ -7757,14 +8166,14 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== +object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" + integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" + es-abstract "^1.18.0-next.2" has "^1.0.3" obuf@^1.0.0, obuf@^1.1.2: @@ -7792,16 +8201,16 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: wrappy "1" onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" open@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/open/-/open-7.0.4.tgz#c28a9d315e5c98340bf979fdcb2e58664aa10d83" - integrity sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ== + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== dependencies: is-docker "^2.0.0" is-wsl "^2.1.1" @@ -7818,15 +8227,15 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -optimize-css-assets-webpack-plugin@5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" - integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA== +optimize-css-assets-webpack-plugin@5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" + integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A== dependencies: cssnano "^4.1.10" last-call-webpack-plugin "^3.0.0" -optionator@^0.8.1, optionator@^0.8.3: +optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -7838,6 +8247,18 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + original@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" @@ -7850,42 +8271,16 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" +p-each-series@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -7893,13 +8288,20 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.2: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -7926,24 +8328,12 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: - aggregate-error "^3.0.0" - -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + aggregate-error "^3.0.0" p-retry@^3.0.1: version "3.0.1" @@ -7977,12 +8367,12 @@ parallel-transform@^1.1.0: readable-stream "^2.1.5" param-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" - integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== dependencies: - dot-case "^3.0.3" - tslib "^1.10.0" + dot-case "^3.0.4" + tslib "^2.0.3" parent-module@^1.0.0: version "1.0.1" @@ -7992,13 +8382,12 @@ parent-module@^1.0.0: callsites "^3.0.0" parse-asn1@^5.0.0, parse-asn1@^5.1.5: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: - asn1.js "^4.0.0" + asn1.js "^5.2.0" browserify-aes "^1.0.0" - create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" safe-buffer "^5.1.1" @@ -8019,51 +8408,42 @@ parse-json@^4.0.0: json-parse-better-errors "^1.0.1" parse-json@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" - integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" + json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== - -parse5@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parseqs@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" - integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= - dependencies: - better-assert "~1.0.0" +parseqs@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5" + integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w== -parseuri@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" - integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= - dependencies: - better-assert "~1.0.0" +parseuri@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a" + integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow== parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascal-case@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" - integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== dependencies: - no-case "^3.0.3" - tslib "^1.10.0" + no-case "^3.0.4" + tslib "^2.0.3" pascalcase@^0.1.1: version "0.1.1" @@ -8080,13 +8460,6 @@ path-dirname@^1.0.0: resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -8141,22 +8514,15 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -8169,21 +8535,16 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -8208,13 +8569,6 @@ pirates@^4.0.1: dependencies: node-modules-regexp "^1.0.0" -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -8236,7 +8590,7 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-up@3.1.0, pkg-up@^3.1.0: +pkg-up@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== @@ -8250,11 +8604,6 @@ please-upgrade-node@^3.2.0: dependencies: semver-compare "^1.0.0" -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -8267,14 +8616,14 @@ popper.js@^1.14.4: resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== -portfinder@^1.0.25: - version "1.0.26" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" - integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== +portfinder@^1.0.26: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== dependencies: async "^2.6.2" debug "^3.1.1" - mkdirp "^0.5.1" + mkdirp "^0.5.5" posix-character-classes@^0.1.0: version "0.1.1" @@ -8297,9 +8646,9 @@ postcss-browser-comments@^3.0.0: postcss "^7" postcss-calc@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" - integrity sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ== + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" + integrity sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg== dependencies: postcss "^7.0.27" postcss-selector-parser "^6.0.2" @@ -8441,12 +8790,12 @@ postcss-env-function@^2.0.2: postcss "^7.0.2" postcss-values-parser "^2.0.0" -postcss-flexbugs-fixes@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz#e094a9df1783e2200b7b19f875dcad3b3aff8b20" - integrity sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA== +postcss-flexbugs-fixes@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== dependencies: - postcss "^7.0.0" + postcss "^7.0.26" postcss-focus-visible@^4.0.0: version "4.0.0" @@ -8463,9 +8812,9 @@ postcss-focus-within@^3.0.0: postcss "^7.0.2" postcss-font-variant@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" - integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" + integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== dependencies: postcss "^7.0.2" @@ -8485,11 +8834,10 @@ postcss-image-set-function@^3.0.1: postcss-values-parser "^2.0.0" postcss-initial@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" - integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" + integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== dependencies: - lodash.template "^4.5.0" postcss "^7.0.2" postcss-lab-function@^2.0.1: @@ -8502,9 +8850,9 @@ postcss-lab-function@^2.0.1: postcss-values-parser "^2.0.0" postcss-load-config@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" - integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" + integrity sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw== dependencies: cosmiconfig "^5.0.0" import-cwd "^2.0.0" @@ -8602,17 +8950,17 @@ postcss-modules-extract-imports@^2.0.0: dependencies: postcss "^7.0.5" -postcss-modules-local-by-default@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" - integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== +postcss-modules-local-by-default@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== dependencies: icss-utils "^4.1.1" - postcss "^7.0.16" + postcss "^7.0.32" postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.0" + postcss-value-parser "^4.1.0" -postcss-modules-scope@^2.1.1: +postcss-modules-scope@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== @@ -8836,12 +9184,12 @@ postcss-replace-overflow-wrap@^3.0.0: dependencies: postcss "^7.0.2" -postcss-safe-parser@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz#8756d9e4c36fdce2c72b091bbc8ca176ab1fcdea" - integrity sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ== +postcss-safe-parser@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-5.0.2.tgz#459dd27df6bc2ba64608824ba39e45dacf5e852d" + integrity sha512-jDUfCPJbKOABhwpUKcqCVbbXiloe/QXMcbJ6Iipf3sDIihEzTqRCeMBfRaOHxhBuTYqtASrI1KJWxzztZU4qUQ== dependencies: - postcss "^7.0.0" + postcss "^8.1.0" postcss-selector-matches@^4.0.0: version "4.0.0" @@ -8852,9 +9200,9 @@ postcss-selector-matches@^4.0.0: postcss "^7.0.2" postcss-selector-not@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" - integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== dependencies: balanced-match "^1.0.0" postcss "^7.0.2" @@ -8878,20 +9226,18 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: uniq "^1.0.1" postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz#042d74e137db83e6f294712096cb413f5aa612c4" + integrity sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg== dependencies: cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" + util-deprecate "^1.0.2" -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== +postcss-svgo@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e" + integrity sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw== dependencies: - is-svg "^3.0.0" postcss "^7.0.0" postcss-value-parser "^3.0.0" svgo "^1.0.0" @@ -8905,12 +9251,12 @@ postcss-unique-selectors@^4.0.1: postcss "^7.0.0" uniqs "^2.0.0" -postcss-value-parser@^3.0.0: +postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== @@ -8933,15 +9279,29 @@ postcss@7.0.21: source-map "^0.6.1" supports-color "^6.1.0" -postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.32" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" - integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== +postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.35" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" + integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== dependencies: chalk "^2.4.2" source-map "^0.6.1" supports-color "^6.1.0" +postcss@^8.1.0: + version "8.2.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.14.tgz#dcf313eb8247b3ce8078d048c0e8262ca565ad2b" + integrity sha512-+jD0ZijcvyCqPQo/m/CW0UcARpdFylq04of+Q7RKX6f/Tu+dvpUI/9Sp81+i6/vJThnOBX09Quw0ZLOVwpzX3w== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.22" + source-map "^0.6.1" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -8957,33 +9317,28 @@ prettier@~2.0.5: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== -pretty-bytes@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" - integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== +pretty-bytes@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== pretty-error@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" - integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + version "2.1.2" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" + integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== dependencies: - renderkid "^2.0.1" - utila "~0.4" + lodash "^4.17.20" + renderkid "^2.0.4" -pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== +pretty-format@^26.6.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" - -private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" process-nextick-args@~2.0.0: version "2.0.1" @@ -9005,20 +9360,28 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise@^8.0.3: +promise@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== dependencies: asap "~2.0.6" +prompts@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7" + integrity sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + prompts@^2.0.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" - integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== + version "2.4.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" + integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== dependencies: kleur "^3.0.3" - sisteransi "^1.0.4" + sisteransi "^1.0.5" prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: version "15.7.2" @@ -9042,7 +9405,7 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -9132,10 +9495,20 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= +querystring@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== + querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== raf@^3.4.0, raf@^3.4.1: version "3.4.1" @@ -9174,70 +9547,61 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -react-app-polyfill@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz#890f8d7f2842ce6073f030b117de9130a5f385f0" - integrity sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g== +react-app-polyfill@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz#a0bea50f078b8a082970a9d853dc34b6dcc6a3cf" + integrity sha512-0sF4ny9v/B7s6aoehwze9vJNWcmCemAUYBVasscVr92+UYiEqDXOxfKjXN685mDaMRNF3WdhHQs76oTODMocFA== dependencies: - core-js "^3.5.0" + core-js "^3.6.5" object-assign "^4.1.1" - promise "^8.0.3" + promise "^8.1.0" raf "^3.4.1" - regenerator-runtime "^0.13.3" - whatwg-fetch "^3.0.0" + regenerator-runtime "^0.13.7" + whatwg-fetch "^3.4.1" -react-dev-utils@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" - integrity sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ== +react-dev-utils@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a" + integrity sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A== dependencies: - "@babel/code-frame" "7.8.3" + "@babel/code-frame" "7.10.4" address "1.1.2" - browserslist "4.10.0" + browserslist "4.14.2" chalk "2.4.2" - cross-spawn "7.0.1" + cross-spawn "7.0.3" detect-port-alt "1.1.6" escape-string-regexp "2.0.0" - filesize "6.0.1" + filesize "6.1.0" find-up "4.1.0" - fork-ts-checker-webpack-plugin "3.1.1" + fork-ts-checker-webpack-plugin "4.1.6" global-modules "2.0.0" - globby "8.0.2" + globby "11.0.1" gzip-size "5.1.1" - immer "1.10.0" - inquirer "7.0.4" + immer "8.0.1" is-root "2.1.0" - loader-utils "1.2.3" + loader-utils "2.0.0" open "^7.0.2" pkg-up "3.1.0" - react-error-overlay "^6.0.7" + prompts "2.4.0" + react-error-overlay "^6.0.9" recursive-readdir "2.2.2" shell-quote "1.7.2" strip-ansi "6.0.0" text-table "0.2.0" -react-document-title@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/react-document-title/-/react-document-title-2.0.3.tgz#bbf922a0d71412fc948245e4283b2412df70f2b9" - integrity sha1-u/kioNcUEvyUgkXkKDskEt9w8rk= - dependencies: - prop-types "^15.5.6" - react-side-effect "^1.0.2" - -react-dom@~16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" - integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== +react-dom@~17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.19.1" + scheduler "^0.20.2" -react-error-overlay@^6.0.7: - version "6.0.7" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108" - integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA== +react-error-overlay@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" + integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== react-fontawesome@~1.7.1: version "1.7.1" @@ -9247,9 +9611,9 @@ react-fontawesome@~1.7.1: prop-types "^15.5.6" react-google-login@~5.1.14: - version "5.1.20" - resolved "https://registry.yarnpkg.com/react-google-login/-/react-google-login-5.1.20.tgz#06afbf5fd9013455ae3bfba93054630df203542d" - integrity sha512-/5vDx8Hy7Wo1fO1VC/0e5D6/ZGWgIgvcscI8mYZUQ653QOFf0c4GhTnKkebX5uE7m5rAB/2bzzZIUlIesGqWig== + version "5.1.25" + resolved "https://registry.yarnpkg.com/react-google-login/-/react-google-login-5.1.25.tgz#6bf5b4c8ce4e9e64a4c80eb14b80c9c6bd07bf9b" + integrity sha512-N7SZkjTEX9NsC3hywXs68SPJWAHo6M19Bs1OIFPirG0yomGF7KnbKjSqoiIfxz1V7fKAt8bkfBAzogwnGWYTeQ== dependencies: "@types/react" "*" prop-types "^15.6.0" @@ -9261,18 +9625,28 @@ react-hotkeys@^2.0.0: dependencies: prop-types "^15.6.1" -react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: +react-is@16.10.2: + version "16.10.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab" + integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA== + +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-konva@~16.13.0-2: - version "16.13.0-3" - resolved "https://registry.yarnpkg.com/react-konva/-/react-konva-16.13.0-3.tgz#9ef1e813c8b2dd61b54b26151ccbdeed52b89a80" - integrity sha512-U9az1RidQD4c64oZoHiiv6GU6h2ggHO30nZDqfQWuBTH+Bl2wij6Z0NgbUyVyN1IpKIgXRiEKMS9idlxhAzTXQ== +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-konva@~17.0.2-0: + version "17.0.2-0" + resolved "https://registry.yarnpkg.com/react-konva/-/react-konva-17.0.2-0.tgz#35b1cf1b0ff3ed63b7de16aa6c0744e496391374" + integrity sha512-zT//biPf2UqqE4OIaivY2NfnnYgsEscSFacO9sbiUVrhtaP9mV8YgKx48CA4XjlgvfjjZqAxY6JTTmjJlsVYPw== dependencies: - react-reconciler "^0.25.1" - scheduler "^0.19.1" + react-reconciler "~0.26.1" + scheduler "^0.20.1" react-lifecycles-compat@^3.0.4: version "3.0.4" @@ -9280,48 +9654,53 @@ react-lifecycles-compat@^3.0.4: integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== react-popper@^1.3.6: - version "1.3.7" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.7.tgz#f6a3471362ef1f0d10a4963673789de1baca2324" - integrity sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww== + version "1.3.11" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd" + integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg== dependencies: "@babel/runtime" "^7.1.2" - create-react-context "^0.3.0" + "@hypnosphi/create-react-context" "^0.3.1" deep-equal "^1.1.1" popper.js "^1.14.4" prop-types "^15.6.1" typed-styles "^0.0.7" warning "^4.0.2" -react-reconciler@^0.25.1: - version "0.25.1" - resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.25.1.tgz#f9814d59d115e1210762287ce987801529363aaa" - integrity sha512-R5UwsIvRcSs3w8n9k3tBoTtUHdVhu9u84EG7E5M0Jk9F5i6DA1pQzPfUZd6opYWGy56MJOtV3VADzy6DRwYDjw== +react-reconciler@~0.26.1: + version "0.26.2" + resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.26.2.tgz#bbad0e2d1309423f76cf3c3309ac6c96e05e9d91" + integrity sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.19.1" + scheduler "^0.20.2" react-redux@~7.2.0: - version "7.2.2" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.2.tgz#03862e803a30b6b9ef8582dadcc810947f74b736" - integrity sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA== + version "7.2.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" + integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== dependencies: "@babel/runtime" "^7.12.1" + "@types/react-redux" "^7.1.16" hoist-non-react-statics "^3.3.2" loose-envify "^1.4.0" prop-types "^15.7.2" react-is "^16.13.1" -react-resize-detector@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-2.3.0.tgz#57bad1ae26a28a62a2ddb678ba6ffdf8fa2b599c" - integrity sha512-oCAddEWWeFWYH5FAcHdBYcZjAw9fMzRUK9sWSx6WvSSOPVRxcHd5zTIGy/mOus+AhN/u6T4TMiWxvq79PywnJQ== +react-refresh@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" + integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== + +react-resize-detector@^6.6.3: + version "6.7.1" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-6.7.1.tgz#bbc8269ab814fa3b01f7d4e9c38805b877d08f18" + integrity sha512-54l8LWPBIRdtv0I/W/fMkmtgWX0mUIxKKAJKKimihNFueXtHuElDdXDyinQRmV7iku99AoyrSAhkCU/zjFG5+Q== dependencies: + "@types/resize-observer-browser" "^0.1.5" lodash.debounce "^4.0.8" lodash.throttle "^4.1.1" - prop-types "^15.6.0" - resize-observer-polyfill "^1.5.0" + resize-observer-polyfill "^1.5.1" react-router-dom@~5.1.2: version "5.1.2" @@ -9352,84 +9731,82 @@ react-router@5.1.2: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-scripts@~3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a" - integrity sha512-JpTdi/0Sfd31mZA6Ukx+lq5j1JoKItX7qqEK4OiACjVQletM1P38g49d9/D0yTxp9FrSF+xpJFStkGgKEIRjlQ== - dependencies: - "@babel/core" "7.9.0" - "@svgr/webpack" "4.3.3" - "@typescript-eslint/eslint-plugin" "^2.10.0" - "@typescript-eslint/parser" "^2.10.0" - babel-eslint "10.1.0" - babel-jest "^24.9.0" +react-scripts@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345" + integrity sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A== + dependencies: + "@babel/core" "7.12.3" + "@pmmmwh/react-refresh-webpack-plugin" "0.4.3" + "@svgr/webpack" "5.5.0" + "@typescript-eslint/eslint-plugin" "^4.5.0" + "@typescript-eslint/parser" "^4.5.0" + babel-eslint "^10.1.0" + babel-jest "^26.6.0" babel-loader "8.1.0" - babel-plugin-named-asset-import "^0.3.6" - babel-preset-react-app "^9.1.2" - camelcase "^5.3.1" + babel-plugin-named-asset-import "^0.3.7" + babel-preset-react-app "^10.0.0" + bfj "^7.0.2" + camelcase "^6.1.0" case-sensitive-paths-webpack-plugin "2.3.0" - css-loader "3.4.2" + css-loader "4.3.0" dotenv "8.2.0" dotenv-expand "5.1.0" - eslint "^6.6.0" - eslint-config-react-app "^5.2.1" - eslint-loader "3.0.3" - eslint-plugin-flowtype "4.6.0" - eslint-plugin-import "2.20.1" - eslint-plugin-jsx-a11y "6.2.3" - eslint-plugin-react "7.19.0" - eslint-plugin-react-hooks "^1.6.1" - file-loader "4.3.0" - fs-extra "^8.1.0" - html-webpack-plugin "4.0.0-beta.11" + eslint "^7.11.0" + eslint-config-react-app "^6.0.0" + eslint-plugin-flowtype "^5.2.0" + eslint-plugin-import "^2.22.1" + eslint-plugin-jest "^24.1.0" + eslint-plugin-jsx-a11y "^6.3.1" + eslint-plugin-react "^7.21.5" + eslint-plugin-react-hooks "^4.2.0" + eslint-plugin-testing-library "^3.9.2" + eslint-webpack-plugin "^2.5.2" + file-loader "6.1.1" + fs-extra "^9.0.1" + html-webpack-plugin "4.5.0" identity-obj-proxy "3.0.0" - jest "24.9.0" - jest-environment-jsdom-fourteen "1.0.1" - jest-resolve "24.9.0" - jest-watch-typeahead "0.4.2" - mini-css-extract-plugin "0.9.0" - optimize-css-assets-webpack-plugin "5.0.3" + jest "26.6.0" + jest-circus "26.6.0" + jest-resolve "26.6.0" + jest-watch-typeahead "0.6.1" + mini-css-extract-plugin "0.11.3" + optimize-css-assets-webpack-plugin "5.0.4" pnp-webpack-plugin "1.6.4" - postcss-flexbugs-fixes "4.1.0" + postcss-flexbugs-fixes "4.2.1" postcss-loader "3.0.0" postcss-normalize "8.0.1" postcss-preset-env "6.7.0" - postcss-safe-parser "4.0.1" - react-app-polyfill "^1.0.6" - react-dev-utils "^10.2.1" - resolve "1.15.0" - resolve-url-loader "3.1.1" - sass-loader "8.0.2" - semver "6.3.0" - style-loader "0.23.1" - terser-webpack-plugin "2.3.5" - ts-pnp "1.1.6" - url-loader "2.3.0" - webpack "4.42.0" - webpack-dev-server "3.10.3" + postcss-safe-parser "5.0.2" + prompts "2.4.0" + react-app-polyfill "^2.0.0" + react-dev-utils "^11.0.3" + react-refresh "^0.8.3" + resolve "1.18.1" + resolve-url-loader "^3.1.2" + sass-loader "^10.0.5" + semver "7.3.2" + style-loader "1.3.0" + terser-webpack-plugin "4.2.3" + ts-pnp "1.2.0" + url-loader "4.1.1" + webpack "4.44.2" + webpack-dev-server "3.11.1" webpack-manifest-plugin "2.2.0" - workbox-webpack-plugin "4.3.1" + workbox-webpack-plugin "5.1.4" optionalDependencies: - fsevents "2.1.2" - -react-side-effect@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.2.0.tgz#0e940c78faba0c73b9b0eba9cd3dda8dfb7e7dae" - integrity sha512-v1ht1aHg5k/thv56DRcjw+WtojuuDHFUgGfc+bFHOWsF4ZK6C2V57DO0Or0GPsg6+LSTE0M6Ry/gfzhzSwbc5w== - dependencies: - shallowequal "^1.0.1" + fsevents "^2.1.3" -react-smooth@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-1.0.5.tgz#94ae161d7951cdd893ccb7099d031d342cb762ad" - integrity sha512-eW057HT0lFgCKh8ilr0y2JaH2YbNcuEdFpxyg7Gf/qDKk9hqGMyXryZJ8iMGJEuKH0+wxS0ccSsBBB3W8yCn8w== +react-smooth@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91" + integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw== dependencies: - lodash "~4.17.4" - prop-types "^15.6.0" + fast-equals "^2.0.0" raf "^3.4.0" - react-transition-group "^2.5.0" + react-transition-group "2.9.0" -react-transition-group@^2.3.1, react-transition-group@^2.5.0: +react-transition-group@2.9.0, react-transition-group@^2.3.1: version "2.9.0" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== @@ -9439,21 +9816,20 @@ react-transition-group@^2.3.1, react-transition-group@^2.5.0: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" -react@~16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" - integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== +react@~17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" reactstrap@^8.6.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.6.0.tgz#baee0d12990c9fef3c82199fb05e84d9f0af1a26" - integrity sha512-03/UMbLPR6MhVStVUfCLuKh8xh4JOtNVkRxDB9/uHixN+cEQPOpSYa0K69YyK1/2YdZBs2qS6y0cQkK8NQKBHA== + version "8.9.0" + resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.9.0.tgz#bca4afa3f5cd18899ef9b33d877a141886d5abae" + integrity sha512-pmf33YjpNZk1IfrjqpWCUMq9hk6GzSnMWBAofTBNIRJQB1zQ0Au2kzv3lPUAFsBYgWEuI9iYa/xKXHaboSiMkQ== dependencies: - "@babel/runtime" "^7.2.0" + "@babel/runtime" "^7.12.5" classnames "^2.2.3" prop-types "^15.5.8" react-popper "^1.3.6" @@ -9467,13 +9843,14 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" read-pkg@^2.0.0: version "2.0.0" @@ -9484,14 +9861,15 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" @@ -9524,13 +9902,6 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== - dependencies: - picomatch "^2.2.1" - readdirp@~3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" @@ -9538,36 +9909,31 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" - -recharts-scale@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.3.tgz#040b4f638ed687a530357292ecac880578384b59" - integrity sha512-t8p5sccG9Blm7c1JQK/ak9O8o95WGhNXD7TXg/BW5bYbVlr6eCeRBNpgyigD4p6pSSMehC5nSvBUPj6F68rbFA== +recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== dependencies: decimal.js-light "^2.4.1" -recharts@~1.8.5: - version "1.8.5" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-1.8.5.tgz#ca94a3395550946334a802e35004ceb2583fdb12" - integrity sha512-tM9mprJbXVEBxjM7zHsIy6Cc41oO/pVYqyAsOHLxlJrbNBuLs0PHB3iys2M+RqCF0//k8nJtZF6X6swSkWY3tg== +recharts@~2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.0.9.tgz#048068eb01383291104548388712026948275f70" + integrity sha512-JNsXE80PuF3hugUCE7JqDOMSvu5xQLxtjOaqFKKZI2pCJ1PVJzhwDv4TWk0nO4AvADbeWzYEHbg8C5Hcrh42UA== dependencies: + "@types/d3-scale" "^3.0.0" + "@types/d3-shape" "^2.0.0" classnames "^2.2.5" - core-js "^2.6.10" - d3-interpolate "^1.3.0" - d3-scale "^2.1.0" - d3-shape "^1.2.0" - lodash "^4.17.5" - prop-types "^15.6.0" - react-resize-detector "^2.3.0" - react-smooth "^1.0.5" - recharts-scale "^0.4.2" - reduce-css-calc "^1.3.0" + d3-interpolate "^2.0.1" + d3-scale "^3.2.3" + d3-shape "^2.0.0" + eventemitter3 "^4.0.1" + lodash "^4.17.19" + react-is "16.10.2" + react-resize-detector "^6.6.3" + react-smooth "^2.0.0" + recharts-scale "^0.4.4" + reduce-css-calc "^2.1.8" recursive-readdir@2.2.2: version "2.2.2" @@ -9576,21 +9942,13 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" -reduce-css-calc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" - integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= - dependencies: - balanced-match "^0.4.2" - math-expression-evaluator "^1.2.14" - reduce-function-call "^1.0.1" - -reduce-function-call@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" - integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== +reduce-css-calc@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== dependencies: - balanced-match "^1.0.0" + css-unit-converter "^1.1.1" + postcss-value-parser "^3.3.0" redux-localstorage@~0.4.1: version "0.4.1" @@ -9616,7 +9974,14 @@ redux-thunk@~2.3.0: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== -redux@^4.0.4, redux@~4.0.5: +redux@^4.0.0, redux@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" + integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== + dependencies: + "@babel/runtime" "^7.9.2" + +redux@~4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== @@ -9632,32 +9997,26 @@ regenerate-unicode-properties@^8.2.0: regenerate "^1.4.0" regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.13.3: - version "0.13.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" - integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== - -regenerator-runtime@^0.13.4: +regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== regenerator-transform@^0.14.2: - version "0.14.4" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" - integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: "@babel/runtime" "^7.8.4" - private "^0.1.8" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -9667,33 +10026,28 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regex-parser@2.2.10: - version "2.2.10" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.10.tgz#9e66a8f73d89a107616e63b39d4deddfee912b37" - integrity sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA== +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpp@^3.0.0: +regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== -regexpu-core@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" - integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== +regexpu-core@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^8.2.0" @@ -9708,9 +10062,9 @@ regjsgen@^0.5.1: integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + version "0.6.9" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" + integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== dependencies: jsesc "~0.5.0" @@ -9724,44 +10078,44 @@ remove-trailing-separator@^1.0.1: resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= -renderkid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" - integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== +renderkid@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.5.tgz#483b1ac59c6601ab30a7a596a5965cabccfdd0a5" + integrity sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ== dependencies: - css-select "^1.1.0" + css-select "^2.0.2" dom-converter "^0.2" - htmlparser2 "^3.3.0" + htmlparser2 "^3.10.1" + lodash "^4.17.20" strip-ansi "^3.0.0" - utila "^0.4.0" repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== dependencies: - lodash "^4.17.15" + lodash "^4.17.19" -request-promise-native@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== +request-promise-native@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== dependencies: - request-promise-core "1.1.3" + request-promise-core "1.1.4" stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0, request@^2.88.0: +request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -9792,10 +10146,10 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== require-main-filename@^2.0.0: version "2.0.0" @@ -9807,7 +10161,7 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= -resize-observer-polyfill@^1.5.0: +resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== @@ -9819,6 +10173,13 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -9829,17 +10190,22 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-pathname@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve-url-loader@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz#28931895fa1eab9be0647d3b2958c100ae3c0bf0" - integrity sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ== +resolve-url-loader@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz#49ec68340f67d8d2ab6b401948d5def3ab2d0367" + integrity sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA== dependencies: - adjust-sourcemap-loader "2.0.0" + adjust-sourcemap-loader "3.0.0" camelcase "5.3.1" compose-function "3.0.3" convert-source-map "1.7.0" @@ -9855,23 +10221,28 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= +resolve@1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" + integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + dependencies: + is-core-module "^2.0.0" + path-parse "^1.0.6" -resolve@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5" - integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw== +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2, resolve@^1.8.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: + is-core-module "^2.2.0" path-parse "^1.0.6" -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.8.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== +resolve@^2.0.0-next.3: + version "2.0.0-next.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" + integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== dependencies: + is-core-module "^2.2.0" path-parse "^1.0.6" restore-cursor@^3.1.0: @@ -9892,6 +10263,11 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rework-visit@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" @@ -9915,20 +10291,20 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -9937,15 +10313,52 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup-plugin-babel@^4.3.3: + version "4.4.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz#d15bd259466a9d1accbdb2fe2fff17c52d030acb" + integrity sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + rollup-pluginutils "^2.8.1" + +rollup-plugin-terser@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz#8c650062c22a8426c64268548957463bf981b413" + integrity sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w== + dependencies: + "@babel/code-frame" "^7.5.5" + jest-worker "^24.9.0" + rollup-pluginutils "^2.8.2" + serialize-javascript "^4.0.0" + terser "^4.6.2" + +rollup-pluginutils@^2.8.1, rollup-pluginutils@^2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + +rollup@^1.31.1: + version "1.32.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.1.tgz#4480e52d9d9e2ae4b46ba0d9ddeaf3163940f9c4" + integrity sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A== + dependencies: + "@types/estree" "*" + "@types/node" "*" + acorn "^7.1.0" + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -run-async@^2.2.0, run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" @@ -9954,10 +10367,10 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^6.5.3, rxjs@^6.5.5: - version "6.5.5" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" - integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== +rxjs@^6.6.2: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" @@ -10003,16 +10416,16 @@ sanitize.css@^10.0.0: resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a" integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg== -sass-loader@8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d" - integrity sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ== +sass-loader@^10.0.5: + version "10.1.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" + integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw== dependencies: - clone-deep "^4.0.1" - loader-utils "^1.2.3" - neo-async "^2.6.1" - schema-utils "^2.6.1" - semver "^6.3.0" + klona "^2.0.4" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + semver "^7.3.2" sass@^1.32.12: version "1.32.12" @@ -10021,22 +10434,22 @@ sass@^1.32.12: dependencies: chokidar ">=3.0.0 <4.0.0" -sax@^1.2.4, sax@~1.2.4: +sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^3.1.9: - version "3.1.11" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" - integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: - xmlchars "^2.1.1" + xmlchars "^2.2.0" -scheduler@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" - integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== +scheduler@^0.20.1, scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -10050,14 +10463,23 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4, schema-utils@^2.6.5: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== +schema-utils@^2.6.5, schema-utils@^2.7.0, schema-utils@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" seed-random@^2.2.0: version "2.2.0" @@ -10069,12 +10491,12 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^1.10.7: - version "1.10.7" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" - integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== +selfsigned@^1.10.8: + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== dependencies: - node-forge "0.9.0" + node-forge "^0.10.0" semver-compare@^1.0.0: version "1.0.0" @@ -10091,21 +10513,28 @@ semver-regex@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^7.3.2: +semver@7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.2.1, semver@^7.3.2: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -10125,15 +10554,17 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" -serialize-javascript@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" - integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== dependencies: randombytes "^2.1.0" @@ -10198,28 +10629,6 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shallow-clone@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" - integrity sha1-WQnodLp3EG1zrEFM/sH/yofZcGA= - dependencies: - is-extendable "^0.1.1" - kind-of "^2.0.1" - lazy-cache "^0.2.3" - mixin-object "^2.0.1" - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shallowequal@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -10254,13 +10663,14 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -side-channel@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" - integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: - es-abstract "^1.17.0-next.1" - object-inspect "^1.7.0" + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" @@ -10274,35 +10684,16 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" -sisteransi@^1.0.4: +sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -10352,53 +10743,51 @@ snapdragon@^0.8.1: use "^3.1.0" socket.io-client@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" - integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.1.tgz#91a4038ef4d03c19967bb3c646fec6e0eaa78cff" + integrity sha512-YXmXn3pA8abPOY//JtYxou95Ihvzmg8U6kQyolArkIyLd0pgVhrfor/iMsox8cn07WCOOvvuJ6XKegzIucPutQ== dependencies: backo2 "1.0.2" - base64-arraybuffer "0.1.5" component-bind "1.0.0" - component-emitter "1.2.1" - debug "~4.1.0" + component-emitter "~1.3.0" + debug "~3.1.0" engine.io-client "~3.4.0" has-binary2 "~1.0.2" - has-cors "1.1.0" indexof "0.0.1" - object-component "0.0.3" - parseqs "0.0.5" - parseuri "0.0.5" + parseqs "0.0.6" + parseuri "0.0.6" socket.io-parser "~3.3.0" to-array "0.1.4" socket.io-parser@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" - integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + version "3.3.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.2.tgz#ef872009d0adcf704f2fbe830191a14752ad50b6" + integrity sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg== dependencies: - component-emitter "1.2.1" + component-emitter "~1.3.0" debug "~3.1.0" isarray "2.0.1" -sockjs-client@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" - integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== +sockjs-client@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.1.tgz#256908f6d5adfb94dabbdbd02c66362cca0f9ea6" + integrity sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ== dependencies: - debug "^3.2.5" + debug "^3.2.6" eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" + faye-websocket "^0.11.3" + inherits "^2.0.4" + json3 "^3.3.3" + url-parse "^1.5.1" -sockjs@0.3.19: - version "0.3.19" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" - integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== +sockjs@^0.3.21: + version "0.3.21" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" + integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== dependencies: - faye-websocket "^0.10.0" - uuid "^3.0.1" + faye-websocket "^0.11.3" + uuid "^3.4.0" + websocket-driver "^0.7.4" sort-keys@^1.0.0: version "1.1.2" @@ -10423,7 +10812,7 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.6, source-map-support@~0.5.12: +source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -10432,9 +10821,9 @@ source-map-support@^0.5.6, source-map-support@~0.5.12: source-map "^0.6.0" source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" @@ -10446,6 +10835,16 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +source-map@^0.7.3, source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -10468,9 +10867,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== spdy-transport@^3.0.0: version "3.0.0" @@ -10484,7 +10883,7 @@ spdy-transport@^3.0.0: readable-stream "^3.0.6" wbuf "^1.7.3" -spdy@^4.0.1: +spdy@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== @@ -10523,18 +10922,17 @@ sshpk@^1.7.0: tweetnacl "~0.14.0" ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== dependencies: figgy-pudding "^3.5.1" -ssri@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" - integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== +ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: - figgy-pudding "^3.5.1" minipass "^3.1.1" stable@^0.1.8: @@ -10542,10 +10940,17 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stack-utils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + dependencies: + escape-string-regexp "^2.0.0" + +stackframe@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== static-extend@^0.1.1: version "0.1.2" @@ -10607,38 +11012,18 @@ string-argv@0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= - dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" - -string-length@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" - integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== - dependencies: - astral-regex "^1.0.0" - strip-ansi "^5.2.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" -string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" +string-natural-compare@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" + integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" @@ -10650,41 +11035,42 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.matchall@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" - integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg== +string.prototype.matchall@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz#608f255e93e072107f5de066f81a2dfb78cf6b29" + integrity sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0" + es-abstract "^1.18.0-next.2" has-symbols "^1.0.1" - internal-slot "^1.0.2" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.2" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.3.1" + side-channel "^1.0.4" -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.5" -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.5" string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" @@ -10723,13 +11109,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -10742,6 +11121,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-comments@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-1.0.2.tgz#82b9c45e7f05873bee53f37168af930aa368679d" @@ -10760,18 +11144,18 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" - integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -style-loader@0.23.1: - version "0.23.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" - integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== +style-loader@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: - loader-utils "^1.1.0" - schema-utils "^1.0.0" + loader-utils "^2.0.0" + schema-utils "^2.7.0" stylehacks@^4.0.0: version "4.0.3" @@ -10782,11 +11166,6 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -10802,13 +11181,21 @@ supports-color@^6.1.0: has-flag "^3.0.0" supports-color@^7.0.0, supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== dependencies: has-flag "^4.0.0" + supports-color "^7.0.0" -svg-parser@^2.0.0: +svg-parser@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== @@ -10845,57 +11232,93 @@ symbol-observable@^1.2.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -symbol-tree@^3.2.2: +symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +table@^6.0.4: + version "6.7.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.0.tgz#26274751f0ee099c547f6cb91d3eff0d61d155b2" + integrity sha512-SAM+5p6V99gYiiy2gT5ArdzgM1dLDed0nkrWmG6Fry/bUS/m9x83BwpJUOf1Qj/x2qJd+thL6IkIx7qPGRxqBw== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -terser-webpack-plugin@2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz#5ad971acce5c517440ba873ea4f09687de2f4a81" - integrity sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w== - dependencies: - cacache "^13.0.1" - find-cache-dir "^3.2.0" - jest-worker "^25.1.0" - p-limit "^2.2.2" - schema-utils "^2.6.4" - serialize-javascript "^2.1.2" +tar@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +tempy@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8" + integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== + dependencies: + temp-dir "^1.0.0" + type-fest "^0.3.1" + unique-string "^1.0.0" + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +terser-webpack-plugin@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" + integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + jest-worker "^26.5.0" + p-limit "^3.0.2" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" source-map "^0.6.1" - terser "^4.4.3" + terser "^5.3.4" webpack-sources "^1.4.3" terser-webpack-plugin@^1.4.3: - version "1.4.4" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz#2c63544347324baafa9a56baaddf1634c8abfc2f" - integrity sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== dependencies: cacache "^12.0.2" find-cache-dir "^2.1.0" is-wsl "^1.1.0" schema-utils "^1.0.0" - serialize-javascript "^3.1.0" + serialize-javascript "^4.0.0" source-map "^0.6.1" terser "^4.1.2" webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser@^4.1.2, terser@^4.4.3, terser@^4.6.3: +terser@^4.1.2, terser@^4.6.2, terser@^4.6.3: version "4.8.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== @@ -10904,25 +11327,33 @@ terser@^4.1.2, terser@^4.4.3, terser@^4.6.3: source-map "~0.6.1" source-map-support "~0.5.12" -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== +terser@^5.3.4: + version "5.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" + integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== dependencies: - glob "^7.1.3" + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" text-table@0.2.0, text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +throat@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" + integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== through2@^2.0.0: version "2.0.5" @@ -10932,7 +11363,7 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6, through@^2.3.8: +through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -10943,9 +11374,9 @@ thunky@^1.0.2: integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" @@ -10969,13 +11400,6 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -11033,7 +11457,7 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -11041,37 +11465,56 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5 psl "^1.1.28" punycode "^2.1.1" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== dependencies: - punycode "^2.1.0" + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" -ts-pnp@1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.6.tgz#389a24396d425a0d3162e96d2b4638900fdc289a" - integrity sha512-CrG5GqAAzMT7144Cl+UIFP7mz/iIhiy+xQ6GGcnjTezhALT02uPMRw7tgDSESgB5MsfKt55+GPWw4ir1kVtMIQ== +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== + dependencies: + punycode "^2.1.1" + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -ts-pnp@^1.1.6: +ts-pnp@1.2.0, ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +tsconfig-paths@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" -tslib@^1.9.3: +tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" @@ -11092,6 +11535,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -11099,10 +11549,30 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" + integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== type-fest@^0.8.1: version "0.8.1" @@ -11123,9 +11593,9 @@ type@^1.0.1: integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" - integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== typed-function@^2.0.0: version "2.0.0" @@ -11137,6 +11607,13 @@ typed-styles@^0.0.7: resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -11161,6 +11638,16 @@ typescript-tuple@^2.2.1: dependencies: typescript-compare "^0.0.2" +unbox-primitive@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -11218,11 +11705,23 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -universalify@^0.1.0: +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +universalify@^0.1.0, universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -11241,15 +11740,15 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -upath@^1.1.1: +upath@^1.1.1, upath@^1.1.2, upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -11258,19 +11757,19 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-loader@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" - integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== +url-loader@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== dependencies: - loader-utils "^1.2.3" - mime "^2.4.4" - schema-utils "^2.5.0" + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== +url-parse@^1.4.3, url-parse@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" + integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== dependencies: querystringify "^2.1.1" requires-port "^1.0.0" @@ -11288,7 +11787,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -11301,7 +11800,7 @@ util.promisify@1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" -util.promisify@^1.0.0, util.promisify@~1.0.0: +util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== @@ -11325,7 +11824,7 @@ util@^0.11.0: dependencies: inherits "2.0.3" -utila@^0.4.0, utila@~0.4: +utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= @@ -11340,11 +11839,16 @@ uuid@8.2.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.2.0.tgz#cb10dd6b118e2dada7d0cd9730ba7417c93d920e" integrity sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q== -uuid@^3.0.1, uuid@^3.3.2: +uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + uuidv4@~6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-6.1.1.tgz#6565b4f2be7d6f841c14106f420fdb701eae5c81" @@ -11354,9 +11858,18 @@ uuidv4@~6.1.1: uuid "8.2.0" v8-compile-cache@^2.0.3: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +v8-to-istanbul@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" + integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" validate-npm-package-license@^3.0.1: version "3.0.4" @@ -11395,20 +11908,18 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -w3c-hr-time@^1.0.1: +w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" - integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== dependencies: - domexception "^1.0.1" - webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: @@ -11425,23 +11936,23 @@ warning@^4.0.2, warning@^4.0.3: dependencies: loose-envify "^1.0.0" -watchpack-chokidar2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" - integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" -watchpack@^1.6.0: - version "1.7.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa" - integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g== +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" neo-async "^2.5.0" optionalDependencies: - chokidar "^3.4.0" - watchpack-chokidar2 "^2.0.0" + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" @@ -11450,15 +11961,20 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== webpack-dev-middleware@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== dependencies: memory-fs "^0.4.1" mime "^2.4.4" @@ -11466,10 +11982,10 @@ webpack-dev-middleware@^3.7.2: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-server@3.10.3: - version "3.10.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz#f35945036813e57ef582c2420ef7b470e14d3af0" - integrity sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ== +webpack-dev-server@3.11.1: + version "3.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0" + integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ== dependencies: ansi-html "0.0.7" bonjour "^3.5.0" @@ -11479,31 +11995,31 @@ webpack-dev-server@3.10.3: debug "^4.1.1" del "^4.1.1" express "^4.17.1" - html-entities "^1.2.1" + html-entities "^1.3.1" http-proxy-middleware "0.19.1" import-local "^2.0.0" internal-ip "^4.3.0" ip "^1.1.5" is-absolute-url "^3.0.3" killable "^1.0.1" - loglevel "^1.6.6" + loglevel "^1.6.8" opn "^5.5.0" p-retry "^3.0.1" - portfinder "^1.0.25" + portfinder "^1.0.26" schema-utils "^1.0.0" - selfsigned "^1.10.7" + selfsigned "^1.10.8" semver "^6.3.0" serve-index "^1.9.1" - sockjs "0.3.19" - sockjs-client "1.4.0" - spdy "^4.0.1" + sockjs "^0.3.21" + sockjs-client "^1.5.0" + spdy "^4.0.2" strip-ansi "^3.0.1" supports-color "^6.1.0" url "^0.11.0" webpack-dev-middleware "^3.7.2" webpack-log "^2.0.0" ws "^6.2.1" - yargs "12.0.5" + yargs "^13.3.2" webpack-log@^2.0.0: version "2.0.0" @@ -11523,7 +12039,7 @@ webpack-manifest-plugin@2.2.0: object.entries "^1.1.0" tapable "^1.0.0" -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -11531,36 +12047,36 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-list-map "^2.0.0" source-map "~0.6.1" -webpack@4.42.0: - version "4.42.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.0.tgz#b901635dd6179391d90740a63c93f76f39883eb8" - integrity sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w== +webpack@4.44.2: + version "4.44.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72" + integrity sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" ajv "^6.10.2" ajv-keywords "^3.4.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" + enhanced-resolve "^4.3.0" eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" loader-runner "^2.4.0" loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" + watchpack "^1.7.4" webpack-sources "^1.4.1" -websocket-driver@>=0.5.1: +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== @@ -11574,40 +12090,42 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" -whatwg-fetch@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.1.0.tgz#49d630cdfa308dba7f2819d49d09364f540dbcc6" - integrity sha512-pgmbsVWKpH9GxLXZmtdowDIqtb/rvPyjjQv3z9wLcmgWKFHilKnZD3ldgrOlwJoPGOUluQsRPWd52yVkPfmI1A== +whatwg-fetch@^3.4.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" + integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + lodash "^4.7.0" + tr46 "^2.0.2" + webidl-conversions "^6.1.0" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" which-module@^2.0.0: version "2.0.0" @@ -11619,159 +12137,177 @@ which-pm-runs@^1.0.0: resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= -which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -word-wrap@~1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -workbox-background-sync@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz#26821b9bf16e9e37fd1d640289edddc08afd1950" - integrity sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg== +workbox-background-sync@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz#5ae0bbd455f4e9c319e8d827c055bb86c894fd12" + integrity sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.4" -workbox-broadcast-update@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz#e2c0280b149e3a504983b757606ad041f332c35b" - integrity sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA== +workbox-broadcast-update@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-5.1.4.tgz#0eeb89170ddca7f6914fa3523fb14462891f2cfc" + integrity sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.4" -workbox-build@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-4.3.1.tgz#414f70fb4d6de47f6538608b80ec52412d233e64" - integrity sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw== +workbox-build@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-5.1.4.tgz#23d17ed5c32060c363030c8823b39d0eabf4c8c7" + integrity sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow== dependencies: - "@babel/runtime" "^7.3.4" - "@hapi/joi" "^15.0.0" + "@babel/core" "^7.8.4" + "@babel/preset-env" "^7.8.4" + "@babel/runtime" "^7.8.4" + "@hapi/joi" "^15.1.0" + "@rollup/plugin-node-resolve" "^7.1.1" + "@rollup/plugin-replace" "^2.3.1" + "@surma/rollup-plugin-off-main-thread" "^1.1.1" common-tags "^1.8.0" - fs-extra "^4.0.2" - glob "^7.1.3" - lodash.template "^4.4.0" - pretty-bytes "^5.1.0" + fast-json-stable-stringify "^2.1.0" + fs-extra "^8.1.0" + glob "^7.1.6" + lodash.template "^4.5.0" + pretty-bytes "^5.3.0" + rollup "^1.31.1" + rollup-plugin-babel "^4.3.3" + rollup-plugin-terser "^5.3.1" + source-map "^0.7.3" + source-map-url "^0.4.0" stringify-object "^3.3.0" strip-comments "^1.0.2" - workbox-background-sync "^4.3.1" - workbox-broadcast-update "^4.3.1" - workbox-cacheable-response "^4.3.1" - workbox-core "^4.3.1" - workbox-expiration "^4.3.1" - workbox-google-analytics "^4.3.1" - workbox-navigation-preload "^4.3.1" - workbox-precaching "^4.3.1" - workbox-range-requests "^4.3.1" - workbox-routing "^4.3.1" - workbox-strategies "^4.3.1" - workbox-streams "^4.3.1" - workbox-sw "^4.3.1" - workbox-window "^4.3.1" - -workbox-cacheable-response@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz#f53e079179c095a3f19e5313b284975c91428c91" - integrity sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw== - dependencies: - workbox-core "^4.3.1" - -workbox-core@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6" - integrity sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg== - -workbox-expiration@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921" - integrity sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw== - dependencies: - workbox-core "^4.3.1" - -workbox-google-analytics@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a" - integrity sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg== - dependencies: - workbox-background-sync "^4.3.1" - workbox-core "^4.3.1" - workbox-routing "^4.3.1" - workbox-strategies "^4.3.1" - -workbox-navigation-preload@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz#29c8e4db5843803b34cd96dc155f9ebd9afa453d" - integrity sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw== - dependencies: - workbox-core "^4.3.1" - -workbox-precaching@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-4.3.1.tgz#9fc45ed122d94bbe1f0ea9584ff5940960771cba" - integrity sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ== - dependencies: - workbox-core "^4.3.1" - -workbox-range-requests@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74" - integrity sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA== - dependencies: - workbox-core "^4.3.1" - -workbox-routing@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-4.3.1.tgz#a675841af623e0bb0c67ce4ed8e724ac0bed0cda" - integrity sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g== - dependencies: - workbox-core "^4.3.1" - -workbox-strategies@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646" - integrity sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw== - dependencies: - workbox-core "^4.3.1" - -workbox-streams@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3" - integrity sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA== - dependencies: - workbox-core "^4.3.1" - -workbox-sw@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-4.3.1.tgz#df69e395c479ef4d14499372bcd84c0f5e246164" - integrity sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w== - -workbox-webpack-plugin@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz#47ff5ea1cc074b6c40fb5a86108863a24120d4bd" - integrity sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ== - dependencies: - "@babel/runtime" "^7.0.0" - json-stable-stringify "^1.0.1" - workbox-build "^4.3.1" + tempy "^0.3.0" + upath "^1.2.0" + workbox-background-sync "^5.1.4" + workbox-broadcast-update "^5.1.4" + workbox-cacheable-response "^5.1.4" + workbox-core "^5.1.4" + workbox-expiration "^5.1.4" + workbox-google-analytics "^5.1.4" + workbox-navigation-preload "^5.1.4" + workbox-precaching "^5.1.4" + workbox-range-requests "^5.1.4" + workbox-routing "^5.1.4" + workbox-strategies "^5.1.4" + workbox-streams "^5.1.4" + workbox-sw "^5.1.4" + workbox-window "^5.1.4" + +workbox-cacheable-response@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-5.1.4.tgz#9ff26e1366214bdd05cf5a43da9305b274078a54" + integrity sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA== + dependencies: + workbox-core "^5.1.4" + +workbox-core@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-5.1.4.tgz#8bbfb2362ecdff30e25d123c82c79ac65d9264f4" + integrity sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg== + +workbox-expiration@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-5.1.4.tgz#92b5df461e8126114943a3b15c55e4ecb920b163" + integrity sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ== + dependencies: + workbox-core "^5.1.4" + +workbox-google-analytics@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-5.1.4.tgz#b3376806b1ac7d7df8418304d379707195fa8517" + integrity sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA== + dependencies: + workbox-background-sync "^5.1.4" + workbox-core "^5.1.4" + workbox-routing "^5.1.4" + workbox-strategies "^5.1.4" + +workbox-navigation-preload@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-5.1.4.tgz#30d1b720d26a05efc5fa11503e5cc1ed5a78902a" + integrity sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ== + dependencies: + workbox-core "^5.1.4" + +workbox-precaching@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-5.1.4.tgz#874f7ebdd750dd3e04249efae9a1b3f48285fe6b" + integrity sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA== + dependencies: + workbox-core "^5.1.4" + +workbox-range-requests@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-5.1.4.tgz#7066a12c121df65bf76fdf2b0868016aa2bab859" + integrity sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw== + dependencies: + workbox-core "^5.1.4" + +workbox-routing@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-5.1.4.tgz#3e8cd86bd3b6573488d1a2ce7385e547b547e970" + integrity sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw== + dependencies: + workbox-core "^5.1.4" + +workbox-strategies@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-5.1.4.tgz#96b1418ccdfde5354612914964074d466c52d08c" + integrity sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA== + dependencies: + workbox-core "^5.1.4" + workbox-routing "^5.1.4" + +workbox-streams@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-5.1.4.tgz#05754e5e3667bdc078df2c9315b3f41210d8cac0" + integrity sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw== + dependencies: + workbox-core "^5.1.4" + workbox-routing "^5.1.4" + +workbox-sw@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-5.1.4.tgz#2bb34c9f7381f90d84cef644816d45150011d3db" + integrity sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA== + +workbox-webpack-plugin@5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-5.1.4.tgz#7bfe8c16e40fe9ed8937080ac7ae9c8bde01e79c" + integrity sha512-PZafF4HpugZndqISi3rZ4ZK4A4DxO8rAqt2FwRptgsDx7NF8TVKP86/huHquUsRjMGQllsNdn4FNl8CD/UvKmQ== + dependencies: + "@babel/runtime" "^7.5.5" + fast-json-stable-stringify "^2.0.0" + source-map-url "^0.4.0" + upath "^1.1.2" + webpack-sources "^1.3.0" + workbox-build "^5.1.4" -workbox-window@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-4.3.1.tgz#ee6051bf10f06afa5483c9b8dfa0531994ede0f3" - integrity sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg== +workbox-window@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-5.1.4.tgz#2740f7dea7f93b99326179a62f1cc0ca2c93c863" + integrity sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.4" worker-farm@^1.7.0: version "1.7.0" @@ -11787,14 +12323,6 @@ worker-rpc@^0.1.0: dependencies: microevent.ts "~0.1.1" -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" @@ -11818,36 +12346,28 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - graceful-fs "^4.1.11" imurmurhash "^0.1.4" + is-typedarray "^1.0.0" signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - -ws@^6.1.2, ws@^6.2.1: +ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== dependencies: async-limiter "~1.0.0" +ws@^7.4.4: + version "7.4.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" + integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== + ws@~6.1.0: version "6.1.4" resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" @@ -11860,7 +12380,7 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xmlchars@^2.1.1: +xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== @@ -11870,22 +12390,15 @@ xmlhttprequest-ssl@~1.5.4: resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= -xregexp@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.3.0.tgz#7e92e73d9174a99a59743f67a4ce879a04b5ae50" - integrity sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g== - dependencies: - "@babel/runtime-corejs3" "^7.8.3" - xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== yallist@^3.0.2: version "3.1.1" @@ -11897,18 +12410,10 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.7.2: - version "1.10.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" - integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" +yaml@^1.10.0, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yargs-parser@^13.1.2: version "13.1.2" @@ -11918,25 +12423,15 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== dependencies: - cliui "^4.0.0" + camelcase "^5.0.0" decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" -yargs@^13.3.0: +yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== @@ -11952,7 +12447,29 @@ yargs@^13.3.0: y18n "^4.0.0" yargs-parser "^13.1.2" +yargs@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -- cgit v1.2.3 From 18a776414cf5430e199c52805ee88194e30c9f27 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 10 May 2021 17:33:02 +0200 Subject: ui: Update Sentry dependencies --- opendc-web/opendc-web-ui/package.json | 4 ++-- opendc-web/opendc-web-ui/yarn.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index d27a4756..3f3cfad3 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -18,8 +18,8 @@ "private": true, "proxy": "http://localhost:8081", "dependencies": { - "@sentry/react": "^5.27.3", - "@sentry/tracing": "^5.27.3", + "@sentry/react": "^5.30.0", + "@sentry/tracing": "^5.30.0", "approximate-number": "~2.0.0", "bootstrap": "4.5.3", "classnames": "~2.2.5", diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index c29cea71..49b3a6c7 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -1612,7 +1612,7 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" -"@sentry/react@^5.27.3": +"@sentry/react@^5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.30.0.tgz#320e05f766b6a26faefa8d76d1101fd50c69f541" integrity sha512-dvn4mqCgbeEuUXEGp5P9PaW5j4GWTFUSdx/yG8f9IxNZv5zM+7otjog9ukrubFZvlxVxD/PrIxK0MhadfFY/Dw== @@ -1624,7 +1624,7 @@ hoist-non-react-statics "^3.3.2" tslib "^1.9.3" -"@sentry/tracing@^5.27.3": +"@sentry/tracing@^5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== -- cgit v1.2.3 From cc9802641836d77d5c7adec9a69f9c17362abc18 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 10 May 2021 17:34:41 +0200 Subject: ui: Update Bootstrap dependencies --- opendc-web/opendc-web-ui/package.json | 4 ++-- opendc-web/opendc-web-ui/yarn.lock | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 3f3cfad3..0b641bfb 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -21,7 +21,7 @@ "@sentry/react": "^5.30.0", "@sentry/tracing": "^5.30.0", "approximate-number": "~2.0.0", - "bootstrap": "4.5.3", + "bootstrap": "~4.6.0", "classnames": "~2.2.5", "husky": "~4.2.5", "konva": "~7.2.5", @@ -38,7 +38,7 @@ "react-redux": "~7.2.0", "react-router-dom": "~5.1.2", "react-scripts": "~4.0.3", - "reactstrap": "^8.6.0", + "reactstrap": "^8.9.0", "recharts": "~2.0.9", "redux": "~4.0.5", "redux-localstorage": "~0.4.1", diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 49b3a6c7..0990b562 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -3027,10 +3027,10 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= -bootstrap@4.5.3: - version "4.5.3" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6" - integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ== +bootstrap@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7" + integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw== brace-expansion@^1.1.7: version "1.1.11" @@ -9824,7 +9824,7 @@ react@~17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" -reactstrap@^8.6.0: +reactstrap@^8.9.0: version "8.9.0" resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.9.0.tgz#bca4afa3f5cd18899ef9b33d877a141886d5abae" integrity sha512-pmf33YjpNZk1IfrjqpWCUMq9hk6GzSnMWBAofTBNIRJQB1zQ0Au2kzv3lPUAFsBYgWEuI9iYa/xKXHaboSiMkQ== -- cgit v1.2.3 From e93131b622bd4e2522a5933d241fb9bd06c1446c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 10 May 2021 20:55:53 +0200 Subject: ui: Fix version number in package.json This change fixes the version number in package.json which contained the suffix "-rc1", which is apparently not supported by npm. --- opendc-web/opendc-web-ui/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 0b641bfb..54ac8437 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -1,6 +1,6 @@ { "name": "opendc-frontend", - "version": "2.1-rc1", + "version": "2.1.0", "description": "The user-facing component of the OpenDC stack, allowing users to build and interact with their own (virtual) datacenters.", "keywords": [ "opendc", -- cgit v1.2.3 From 09e5fe5a7f9ce8452fa9c042cb493e6fb4de221f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 10 May 2021 20:58:26 +0200 Subject: ui: Update mathjs This change updates the mathjs dependency to version 7.6.0 in order to fix the high-severity vulnerability in mathjs version lower than 7.5.1. --- opendc-web/opendc-web-ui/package.json | 2 +- opendc-web/opendc-web-ui/yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 54ac8437..0a29bcff 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -26,7 +26,7 @@ "husky": "~4.2.5", "konva": "~7.2.5", "lint-staged": "~10.2.2", - "mathjs": "~7.1.0", + "mathjs": "~7.6.0", "prettier": "~2.0.5", "prop-types": "~15.7.2", "react": "~17.0.2", diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 0990b562..8549a280 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -4240,7 +4240,7 @@ decimal.js-light@^2.4.1: resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== -decimal.js@^10.2.0, decimal.js@^10.2.1: +decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== @@ -7577,13 +7577,13 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -mathjs@~7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-7.1.0.tgz#83226e336b8b258b046a139865373e667db94afb" - integrity sha512-Km6PO2UR+COs5mru5auKQKi84GKBryuL5JDdKeAxAi0QV8mH/qwpZKLnzrycxBacQ/X/4Z4Kn+gtYc5gEeWsDQ== +mathjs@~7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-7.6.0.tgz#f0b7579e0756b13422995d0c4f29bd17d65d4dcc" + integrity sha512-abywR28hUpKF4at5jE8Ys+Kigk40eKMT5mcBLD0/dtsqjfOLbtzd3WjlRqIopNo7oQ6FME51qph6lb8h/bhpUg== dependencies: complex.js "^2.0.11" - decimal.js "^10.2.0" + decimal.js "^10.2.1" escape-latex "^1.2.0" fraction.js "^4.0.12" javascript-natural-sort "^0.7.1" -- cgit v1.2.3 From 873ddacf5abafe43fbc2b6c1033e473c3366dc62 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 11 May 2021 15:40:11 +0200 Subject: ui: Move component styling into CSS modules This change updates the frontend codebase by moving the component styling into CSS module files as opposed to the global styles which we used before. In addition, I have changed the syntax to the newer SCSS syntax, which is more similar to CSS. These changes reduces the styling conflicts that can occur between components and allows us to migrate to systems that do not support importing global styles in components. Moreover, we can benefit from treeshaking using CSS modules. --- .../app/map/controls/ScaleIndicatorComponent.js | 4 +- .../controls/ScaleIndicatorComponent.module.scss | 10 +++ .../app/map/controls/ScaleIndicatorComponent.sass | 9 --- .../app/map/controls/ToolPanelComponent.js | 4 +- .../map/controls/ToolPanelComponent.module.scss | 6 ++ .../app/map/controls/ToolPanelComponent.sass | 5 -- .../src/components/app/sidebars/Sidebar.js | 78 ++++++++++------------ .../components/app/sidebars/Sidebar.module.scss | 57 ++++++++++++++++ .../src/components/app/sidebars/Sidebar.sass | 50 -------------- .../sidebars/topology/rack/MachineListComponent.js | 4 +- .../topology/rack/MachineListComponent.module.scss | 3 + .../topology/rack/MachineListComponent.sass | 2 - .../sidebars/topology/rack/RackSidebarComponent.js | 8 +-- .../topology/rack/RackSidebarComponent.module.scss | 14 ++++ .../topology/rack/RackSidebarComponent.sass | 11 --- .../src/components/home/ContactSection.js | 6 +- .../src/components/home/ContactSection.module.scss | 20 ++++++ .../src/components/home/ContactSection.sass | 15 ----- .../src/components/home/ContentSection.js | 4 +- .../src/components/home/ContentSection.module.scss | 11 +++ .../src/components/home/ContentSection.sass | 9 --- .../src/components/home/IntroSection.js | 4 +- .../src/components/home/JumbotronHeader.js | 8 +-- .../components/home/JumbotronHeader.module.scss | 31 +++++++++ .../src/components/home/JumbotronHeader.sass | 24 ------- .../src/components/home/ModelingSection.js | 3 +- .../src/components/home/ScreenshotSection.js | 8 +-- .../components/home/ScreenshotSection.module.scss | 5 ++ .../src/components/home/ScreenshotSection.sass | 4 -- .../src/components/home/SimulationSection.js | 4 +- .../src/components/home/StakeholderSection.js | 4 +- .../src/components/home/TeamSection.js | 4 +- .../src/components/home/TechnologiesSection.js | 4 +- .../components/navigation/AppNavbarComponent.js | 2 +- .../src/components/navigation/HomeNavbar.js | 2 +- .../src/components/navigation/Navbar.js | 8 +-- .../src/components/navigation/Navbar.module.scss | 36 ++++++++++ .../src/components/navigation/Navbar.sass | 30 --------- .../src/components/not-found/BlinkingCursor.js | 4 +- .../not-found/BlinkingCursor.module.scss | 13 ++++ .../src/components/not-found/BlinkingCursor.sass | 35 ---------- .../src/components/not-found/CodeBlock.js | 4 +- .../src/components/not-found/CodeBlock.module.scss | 4 ++ .../src/components/not-found/CodeBlock.sass | 3 - .../src/components/not-found/TerminalWindow.js | 14 ++-- .../not-found/TerminalWindow.module.scss | 61 +++++++++++++++++ .../src/components/not-found/TerminalWindow.sass | 70 ------------------- .../src/components/projects/FilterPanel.js | 4 +- .../components/projects/FilterPanel.module.scss | 7 ++ .../src/components/projects/FilterPanel.sass | 5 -- .../opendc-web-ui/src/containers/auth/Login.js | 8 +-- opendc-web/opendc-web-ui/src/index.js | 2 +- opendc-web/opendc-web-ui/src/index.sass | 52 --------------- opendc-web/opendc-web-ui/src/index.scss | 68 +++++++++++++++++++ opendc-web/opendc-web-ui/src/pages/Home.js | 21 ++++-- .../opendc-web-ui/src/pages/Home.module.scss | 16 +++++ opendc-web/opendc-web-ui/src/pages/Home.sass | 9 --- opendc-web/opendc-web-ui/src/pages/NotFound.js | 4 +- .../opendc-web-ui/src/pages/NotFound.module.scss | 8 +++ opendc-web/opendc-web-ui/src/pages/NotFound.sass | 11 --- .../opendc-web-ui/src/style-globals/_mixins.sass | 21 ------ .../opendc-web-ui/src/style-globals/_mixins.scss | 5 ++ .../src/style-globals/_variables.sass | 31 --------- .../src/style-globals/_variables.scss | 31 +++++++++ 64 files changed, 516 insertions(+), 506 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.sass create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.sass create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.sass create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.sass create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.sass create mode 100644 opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/home/ContactSection.sass create mode 100644 opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/home/ContentSection.sass create mode 100644 opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.sass create mode 100644 opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.sass create mode 100644 opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/navigation/Navbar.sass create mode 100644 opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.sass create mode 100644 opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.sass create mode 100644 opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.sass create mode 100644 opendc-web/opendc-web-ui/src/components/projects/FilterPanel.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/FilterPanel.sass delete mode 100644 opendc-web/opendc-web-ui/src/index.sass create mode 100644 opendc-web/opendc-web-ui/src/index.scss create mode 100644 opendc-web/opendc-web-ui/src/pages/Home.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/pages/Home.sass create mode 100644 opendc-web/opendc-web-ui/src/pages/NotFound.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/pages/NotFound.sass delete mode 100644 opendc-web/opendc-web-ui/src/style-globals/_mixins.sass create mode 100644 opendc-web/opendc-web-ui/src/style-globals/_mixins.scss delete mode 100644 opendc-web/opendc-web-ui/src/style-globals/_variables.sass create mode 100644 opendc-web/opendc-web-ui/src/style-globals/_variables.scss diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js index 7cbb45c0..13226602 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js @@ -1,9 +1,9 @@ import React from 'react' import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from '../MapConstants' -import './ScaleIndicatorComponent.sass' +import { scaleIndicator } from './ScaleIndicatorComponent.module.scss' const ScaleIndicatorComponent = ({ scale }) => ( -
+
{TILE_SIZE_IN_METERS}m
) diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss new file mode 100644 index 00000000..f19e0ff2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss @@ -0,0 +1,10 @@ +.scaleIndicator { + position: absolute; + right: 10px; + bottom: 10px; + z-index: 50; + + border: solid 2px #212529; + border-top: none; + border-left: none; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.sass b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.sass deleted file mode 100644 index 03a72c99..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.sass +++ /dev/null @@ -1,9 +0,0 @@ -.scale-indicator - position: absolute - right: 10px - bottom: 10px - z-index: 50 - - border: solid 2px #212529 - border-top: none - border-left: none diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js index f372734d..d2f70953 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js @@ -1,10 +1,10 @@ import React from 'react' import ZoomControlContainer from '../../../../containers/app/map/controls/ZoomControlContainer' import ExportCanvasComponent from './ExportCanvasComponent' -import './ToolPanelComponent.sass' +import { toolPanel } from './ToolPanelComponent.module.scss' const ToolPanelComponent = () => ( -
+
diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss new file mode 100644 index 00000000..970b1ce2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss @@ -0,0 +1,6 @@ +.toolPanel { + position: absolute; + left: 10px; + bottom: 10px; + z-index: 50; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.sass b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.sass deleted file mode 100644 index 8b27d24a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.sass +++ /dev/null @@ -1,5 +0,0 @@ -.tool-panel - position: absolute - left: 10px - bottom: 10px - z-index: 50 diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js index f7368f54..64e95014 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js @@ -1,53 +1,45 @@ import PropTypes from 'prop-types' import classNames from 'classnames' -import React from 'react' -import './Sidebar.sass' +import React, { useState } from 'react' +import { collapseButton, collapseButtonRight, sidebar, sidebarRight } from './Sidebar.module.scss' -class Sidebar extends React.Component { - static propTypes = { - isRight: PropTypes.bool.isRequired, - collapsible: PropTypes.bool, - } +function Sidebar({ isRight, collapsible = true, children }) { + const [isCollapsed, setCollapsed] = useState(false) - static defaultProps = { - collapsible: true, - } + const button = ( +
setCollapsed(!isCollapsed)} + > + {(isCollapsed && isRight) || (!isCollapsed && !isRight) ? ( + + ) : ( + + )} +
+ ) - state = { - collapsed: false, + if (isCollapsed) { + return button } + return ( +
e.stopPropagation()} + > + {children} + {collapsible && button} +
+ ) +} - render() { - const collapseButton = ( -
this.setState({ collapsed: !this.state.collapsed })} - > - {(this.state.collapsed && this.props.isRight) || (!this.state.collapsed && !this.props.isRight) ? ( - - ) : ( - - )} -
- ) - - if (this.state.collapsed) { - return collapseButton - } - return ( -
e.stopPropagation()} - > - {this.props.children} - {this.props.collapsible && collapseButton} -
- ) - } +Sidebar.propTypes = { + isRight: PropTypes.bool.isRequired, + collapsible: PropTypes.bool, } export default Sidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss new file mode 100644 index 00000000..d6be4d9b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss @@ -0,0 +1,57 @@ +@import '../../../style-globals/_variables.scss'; +@import '../../../style-globals/_mixins.scss'; + +.collapseButton { + position: absolute; + left: 5px; + top: 5px; + padding: 5px 7px; + + background: white; + border: solid 1px $gray-semi-light; + z-index: 99; + + @include clickable; + border-radius: 5px; + transition: background 200ms; + + &.collapseButtonRight { + left: auto; + right: 5px; + top: 5px; + } + + &:hover { + background: #eeeeee; + } +} + +.sidebar { + position: absolute; + top: 0; + left: 0; + width: $side-bar-width; + + z-index: 100; + background: white; + + border-right: $gray-semi-dark 1px solid; + + .collapseButton { + left: auto; + right: -25px; + } +} + +.sidebarRight { + left: auto; + right: 0; + + border-left: $gray-semi-dark 1px solid; + border-right: none; + + .collapseButtonRight { + left: -25px; + right: auto; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.sass b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.sass deleted file mode 100644 index b8e15716..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.sass +++ /dev/null @@ -1,50 +0,0 @@ -@import ../../../style-globals/_variables.sass -@import ../../../style-globals/_mixins.sass - -.sidebar-collapse-button - position: absolute - left: 5px - top: 5px - padding: 5px 7px - - background: white - border: solid 1px $gray-semi-light - z-index: 99 - - +clickable - +border-radius(5px) - +transition(background, 200ms) - - &.sidebar-collapse-button-right - left: auto - right: 5px - top: 5px - - &:hover - background: #eeeeee - -.sidebar - position: absolute - top: 0 - left: 0 - width: $side-bar-width - - z-index: 100 - background: white - - border-right: $gray-semi-dark 1px solid - - .sidebar-collapse-button - left: auto - right: -25px - -.sidebar-right - left: auto - right: 0 - - border-left: $gray-semi-dark 1px solid - border-right: none - - .sidebar-collapse-button-right - left: -25px - right: auto diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js index 12be26bd..1c07d237 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js @@ -1,11 +1,11 @@ import React from 'react' import EmptySlotContainer from '../../../../../containers/app/sidebars/topology/rack/EmptySlotContainer' import MachineContainer from '../../../../../containers/app/sidebars/topology/rack/MachineContainer' -import './MachineListComponent.sass' +import { machineList } from './MachineListComponent.module.scss' const MachineListComponent = ({ machineIds }) => { return ( -
    +
      {machineIds.map((machineId, index) => { if (machineId === null) { return diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss new file mode 100644 index 00000000..f075aac9 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss @@ -0,0 +1,3 @@ +.machineList li { + min-height: 64px; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.sass b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.sass deleted file mode 100644 index 11b82c93..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.sass +++ /dev/null @@ -1,2 +0,0 @@ -.machine-list li - min-height: 64px diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js index ca41bf57..74313bf7 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js @@ -3,19 +3,19 @@ import BackToRoomContainer from '../../../../../containers/app/sidebars/topology import DeleteRackContainer from '../../../../../containers/app/sidebars/topology/rack/DeleteRackContainer' import MachineListContainer from '../../../../../containers/app/sidebars/topology/rack/MachineListContainer' import RackNameContainer from '../../../../../containers/app/sidebars/topology/rack/RackNameContainer' -import './RackSidebarComponent.sass' +import { sidebarContainer, sidebarHeaderContainer, machineListContainer } from './RackSidebarComponent.module.scss' import AddPrefabContainer from '../../../../../containers/app/sidebars/topology/rack/AddPrefabContainer' const RackSidebarComponent = () => { return ( -
      -
      +
      +
      -
      +
      diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss new file mode 100644 index 00000000..8ce3836a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss @@ -0,0 +1,14 @@ +.sidebarContainer { + display: flex; + height: 100%; + max-height: 100%; +} + +.sidebarHeaderContainer { + flex: 0; +} + +.machineListContainer { + flex: 1; + overflow-y: scroll; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.sass b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.sass deleted file mode 100644 index 29fec02a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.sass +++ /dev/null @@ -1,11 +0,0 @@ -.rack-sidebar-container - display: flex - height: 100% - max-height: 100% - -.rack-sidebar-header-container - flex: 0 - -.machine-list-container - flex: 1 - overflow-y: scroll diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js index d25a1bc4..25daaccf 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js @@ -3,10 +3,10 @@ import FontAwesome from 'react-fontawesome' import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' -import './ContactSection.sass' +import { contactSection, tudelftIcon } from './ContactSection.module.scss' const ContactSection = () => ( - + @@ -25,7 +25,7 @@ const ContactSection = () => ( - TU Delft + TU Delft diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss b/opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss new file mode 100644 index 00000000..9ab4fcb1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss @@ -0,0 +1,20 @@ +.contactSection { + background-color: #444; + color: #ddd; + + a { + color: #ddd; + + &:hover { + color: #fff; + } + } + + .tudelftIcon { + height: 100px; + } + + .disclaimer { + color: #cccccc; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.sass b/opendc-web/opendc-web-ui/src/components/home/ContactSection.sass deleted file mode 100644 index 997f8d98..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ContactSection.sass +++ /dev/null @@ -1,15 +0,0 @@ -.contact-section - background-color: #444 - color: #ddd - - a - color: #ddd - - a:hover - color: #fff - - .tudelft-icon - height: 100px - - .disclaimer - color: #cccccc diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js index 3a8960d9..3e9ad50a 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js @@ -2,10 +2,10 @@ import React from 'react' import classNames from 'classnames' import { Container } from 'reactstrap' import PropTypes from 'prop-types' -import './ContentSection.sass' +import { contentSection } from './ContentSection.module.scss' const ContentSection = ({ name, title, children, className }) => ( -
      +

      {title}

      {children} diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss b/opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss new file mode 100644 index 00000000..3d150c93 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss @@ -0,0 +1,11 @@ +@import '../../style-globals/_variables.scss'; + +.contentSection { + padding-top: 50px; + padding-bottom: 50px; + text-align: center; + + h1 { + margin-bottom: 30px; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.sass b/opendc-web/opendc-web-ui/src/components/home/ContentSection.sass deleted file mode 100644 index a4c8bd66..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ContentSection.sass +++ /dev/null @@ -1,9 +0,0 @@ -@import ../../style-globals/_variables.sass - -.content-section - padding-top: 50px - padding-bottom: 150px - text-align: center - - h1 - margin-bottom: 30px diff --git a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js index bc6ee83b..7b467889 100644 --- a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js @@ -1,8 +1,8 @@ import React from 'react' import { Container, Row, Col } from 'reactstrap' -const IntroSection = () => ( -
      +const IntroSection = ({ className }) => ( +
      diff --git a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js index 6a9ea00c..0d3217f9 100644 --- a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js +++ b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js @@ -1,13 +1,13 @@ import React from 'react' import { Container, Jumbotron, Button } from 'reactstrap' -import './JumbotronHeader.sass' +import { jumbotronHeader, jumbotron, dc } from './JumbotronHeader.module.scss' const JumbotronHeader = () => ( -
      +
      - +

      - OpenDC + OpenDC

      Collaborative Datacenter Simulation and Exploration for Everybody

      OpenDC diff --git a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss new file mode 100644 index 00000000..567b3e73 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss @@ -0,0 +1,31 @@ +.jumbotronHeader { + background: #00a6d6; +} + +.jumbotron { + background-color: inherit; + margin-bottom: 0; + text-align: center; + + padding-top: 120px; + padding-bottom: 120px; + + img { + max-width: 110px; + } + + h1 { + color: #fff; + font-size: 4.5em; + + .dc { + color: #fff; + font-weight: bold; + } + } + + :global(.lead) { + color: #fff; + font-size: 1.4em; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.sass b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.sass deleted file mode 100644 index 1b6a89fd..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.sass +++ /dev/null @@ -1,24 +0,0 @@ -.jumbotron-header - background: #00A6D6 - -.jumbotron - background-color: inherit - margin-bottom: 0 - - padding-top: 120px - padding-bottom: 120px - - img - max-width: 110px - - h1 - color: #fff - font-size: 4.5em - - .dc - color: #fff - font-weight: bold - - .lead - color: #fff - font-size: 1.4em diff --git a/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js b/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js index 643dca65..af36aa45 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js @@ -1,13 +1,14 @@ import React from 'react' import ScreenshotSection from './ScreenshotSection' -const ModelingSection = () => ( +const ModelingSection = ({ className }) => (

      Collaboratively...

        diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js index 33aab17f..4f634b28 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js @@ -1,16 +1,16 @@ import React from 'react' import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' -import './ScreenshotSection.sass' +import { screenshot } from './ScreenshotSection.module.scss' -const ScreenshotSection = ({ name, title, imageUrl, caption, imageIsRight, children }) => ( - +const ScreenshotSection = ({ className, name, title, imageUrl, caption, imageIsRight, children }) => ( + {children} - {caption} + {caption}
        {caption}
        diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss new file mode 100644 index 00000000..7e22de32 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss @@ -0,0 +1,5 @@ +.screenshot { + padding-left: 0; + padding-right: 0; + margin-bottom: 5px; +} diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.sass b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.sass deleted file mode 100644 index 6b1a6ec4..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.sass +++ /dev/null @@ -1,4 +0,0 @@ -.screenshot - padding-left: 0 - padding-right: 0 - margin-bottom: 5px diff --git a/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js b/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js index 8e98717a..44ce905b 100644 --- a/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js @@ -2,9 +2,9 @@ import React from 'react' import { Col, Row } from 'reactstrap' import ContentSection from './ContentSection' -const SimulationSection = () => { +const SimulationSection = ({ className }) => { return ( - +

        Working with OpenDC:

        diff --git a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js index 1624b4d2..9a4892ed 100644 --- a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js @@ -21,8 +21,8 @@ const Stakeholder = ({ name, title, subtitle }) => ( ) -const StakeholderSection = () => ( - +const StakeholderSection = ({ className }) => ( + diff --git a/opendc-web/opendc-web-ui/src/components/home/TeamSection.js b/opendc-web/opendc-web-ui/src/components/home/TeamSection.js index 1ee1cbf5..4e8a3906 100644 --- a/opendc-web/opendc-web-ui/src/components/home/TeamSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/TeamSection.js @@ -41,8 +41,8 @@ const TeamMember = ({ photoId, name }) => ( ) -const TeamSection = () => ( - +const TeamSection = ({ className }) => ( + diff --git a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js index efd77edf..6fdf4e5c 100644 --- a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js @@ -3,8 +3,8 @@ import FontAwesome from 'react-fontawesome' import { ListGroup, ListGroupItem } from 'reactstrap' import ContentSection from './ContentSection' -const TechnologiesSection = () => ( - +const TechnologiesSection = ({ className }) => ( + diff --git a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js index c5de3d0b..8c28c542 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js @@ -3,7 +3,7 @@ import FontAwesome from 'react-fontawesome' import { Link } from 'react-router-dom' import { NavLink } from 'reactstrap' import Navbar, { NavItem } from './Navbar' -import './Navbar.sass' +import {} from './Navbar.module.scss' const AppNavbarComponent = ({ project, fullWidth }) => ( diff --git a/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js b/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js index 08d222ea..46d01a25 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js @@ -1,7 +1,7 @@ import React from 'react' import { NavItem, NavLink } from 'reactstrap' import Navbar from './Navbar' -import './Navbar.sass' +import {} from './Navbar.module.scss' const ScrollNavItem = ({ id, name }) => ( diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js index 55f98900..bf18f1c4 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js @@ -14,7 +14,7 @@ import { userIsLoggedIn } from '../../auth/index' import Login from '../../containers/auth/Login' import Logout from '../../containers/auth/Logout' import ProfileName from '../../containers/auth/ProfileName' -import './Navbar.sass' +import { login, navbar, opendcBrand } from './Navbar.module.scss' export const NAVBAR_HEIGHT = 60 @@ -59,7 +59,7 @@ export const LoggedInSection = () => { ) : ( - + )} @@ -71,10 +71,10 @@ const Navbar = ({ fullWidth, children }) => { const toggle = () => setIsOpen(!isOpen) return ( - + - + OpenDC diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss new file mode 100644 index 00000000..2ea59a0f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss @@ -0,0 +1,36 @@ +@import '../../style-globals/_mixins.scss'; +@import '../../style-globals/_variables.scss'; + +.navbar { + border-top: $blue 3px solid; + border-bottom: $gray-semi-dark 1px solid; + color: $gray-very-dark; + background: #fafafb; +} + +.opendcBrand { + display: inline-block; + color: $gray-very-dark; + + transition: background $transition-length; + + img { + position: relative; + bottom: 3px; + display: inline-block; + width: 30px; + } +} + +.login { + height: 40px; + background: $blue; + border: none; + padding-top: 10px; + + @include clickable; + + &:hover { + background: $blue-dark; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.sass b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.sass deleted file mode 100644 index c9d2aad2..00000000 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.sass +++ /dev/null @@ -1,30 +0,0 @@ -@import ../../style-globals/_mixins.sass -@import ../../style-globals/_variables.sass - -.navbar - border-top: $blue 3px solid - border-bottom: $gray-semi-dark 1px solid - color: $gray-very-dark - background: #fafafb - -.opendc-brand - display: inline-block - color: $gray-very-dark - - +transition(background, $transition-length) - - img - position: relative - bottom: 3px - display: inline-block - width: 30px - -.login - height: 40px - background: $blue - border: none - padding-top: 10px - +clickable - - &:hover - background: $blue-dark diff --git a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js index dbdba212..03a4894b 100644 --- a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js +++ b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js @@ -1,6 +1,6 @@ import React from 'react' -import './BlinkingCursor.sass' +import { blinkingCursor } from './BlinkingCursor.module.scss' -const BlinkingCursor = () => _ +const BlinkingCursor = () => _ export default BlinkingCursor diff --git a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss new file mode 100644 index 00000000..aba0c604 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss @@ -0,0 +1,13 @@ +.blinkingCursor { + animation: blink 1s step-end infinite; +} + +@keyframes blink { + from, + to { + color: #eeeeee; + } + 50% { + color: #333333; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.sass b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.sass deleted file mode 100644 index ad91df85..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.sass +++ /dev/null @@ -1,35 +0,0 @@ -.blinking-cursor - -webkit-animation: 1s blink step-end infinite - -moz-animation: 1s blink step-end infinite - -o-animation: 1s blink step-end infinite - animation: 1s blink step-end infinite - -@keyframes blink - from, to - color: #eeeeee - 50% - color: #333333 - -@-moz-keyframes blink - from, to - color: #eeeeee - 50% - color: #333333 - -@-webkit-keyframes blink - from, to - color: #eeeeee - 50% - color: #333333 - -@-ms-keyframes blink - from, to - color: #eeeeee - 50% - color: #333333 - -@-o-keyframes blink - from, to - color: #eeeeee - 50% - color: #333333 diff --git a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js index bcc522c9..6ded4350 100644 --- a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js +++ b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js @@ -1,5 +1,5 @@ import React from 'react' -import './CodeBlock.sass' +import { codeBlock } from './CodeBlock.module.scss' const CodeBlock = () => { const textBlock = @@ -22,7 +22,7 @@ const CodeBlock = () => { } } - return
        + return
        } export default CodeBlock diff --git a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss new file mode 100644 index 00000000..8af3ee6d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss @@ -0,0 +1,4 @@ +.codeBlock { + white-space: pre-wrap; + margin-top: 60px; +} diff --git a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.sass b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.sass deleted file mode 100644 index e452f917..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.sass +++ /dev/null @@ -1,3 +0,0 @@ -.code-block - white-space: pre-wrap - margin-top: 60px diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js index a25e558a..b38fc183 100644 --- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js +++ b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js @@ -2,13 +2,13 @@ import React from 'react' import { Link } from 'react-router-dom' import BlinkingCursor from './BlinkingCursor' import CodeBlock from './CodeBlock' -import './TerminalWindow.sass' +import { terminalWindow, terminalHeader, terminalBody, segfault, subTitle, homeBtn } from './TerminalWindow.module.scss' const TerminalWindow = () => ( -
        -
        Terminal -- bash
        -
        -
        +
        +
        Terminal -- bash
        +
        +
        $ status
        opendc[4264]: segfault at 0000051497be459d1 err 12 in libopendc.9.0.4 @@ -19,11 +19,11 @@ const TerminalWindow = () => (
        -
        +
        Got lost?
        - + GET ME BACK TO OPENDC
        diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss new file mode 100644 index 00000000..614852d3 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss @@ -0,0 +1,61 @@ +.terminalWindow { + display: block; + align-self: center; + + margin: auto; + + user-select: none; + cursor: default; + + overflow: hidden; + + box-shadow: 5px 5px 20px #444444; +} + +.terminalHeader { + font-family: monospace; + background: #cccccc; + color: #444444; + height: 30px; + line-height: 30px; + padding-left: 10px; + + border-top-left-radius: 7px; + border-top-right-radius: 7px; +} + +.terminalBody { + font-family: monospace; + text-align: center; + background-color: #333333; + color: #eeeeee; + padding: 10px; + + height: 100%; +} + +.segfault { + text-align: left; +} + +.subTitle { + margin-top: 20px; +} + +.homeBtn { + margin-top: 10px; + padding: 5px; + display: inline-block; + border: 1px solid #eeeeee; + color: #eeeeee; + text-decoration: none; + cursor: pointer; + + transition: all 200ms; + + &:hover, + &:active { + background: #eeeeee; + color: #333333; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.sass b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.sass deleted file mode 100644 index 7f05335a..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.sass +++ /dev/null @@ -1,70 +0,0 @@ -.terminal-window - width: 600px - height: 400px - display: block - - position: absolute - top: 0 - bottom: 0 - left: 0 - right: 0 - - margin: auto - - -webkit-user-select: none - -moz-user-select: none - -ms-user-select: none - user-select: none - cursor: default - - overflow: hidden - - box-shadow: 5px 5px 20px #444444 - -.terminal-header - font-family: monospace - background: #cccccc - color: #444444 - height: 30px - line-height: 30px - padding-left: 10px - - border-top-left-radius: 7px - border-top-right-radius: 7px - -.terminal-body - font-family: monospace - text-align: center - background-color: #333333 - color: #eeeeee - padding: 10px - - height: 100% - -.segfault - text-align: left - -.sub-title - margin-top: 20px - -.home-btn - margin-top: 10px - padding: 5px - display: inline-block - border: 1px solid #eeeeee - color: #eeeeee - text-decoration: none - cursor: pointer - - -webkit-transition: all 200ms - -moz-transition: all 200ms - -o-transition: all 200ms - transition: all 200ms - -.home-btn:hover - background: #eeeeee - color: #333333 - -.home-btn:active - background: #333333 - color: #eeeeee diff --git a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js index 2b9795d0..89b483fb 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js +++ b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js @@ -1,9 +1,9 @@ import React from 'react' import FilterLink from '../../containers/projects/FilterLink' -import './FilterPanel.sass' +import { filterPanel } from './FilterPanel.module.scss' const FilterPanel = () => ( -
        +
        All Projects My Projects Shared with me diff --git a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.module.scss b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.module.scss new file mode 100644 index 00000000..79cdf81a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.module.scss @@ -0,0 +1,7 @@ +.filterPanel { + display: flex; + + button { + flex: 1 !important; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.sass b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.sass deleted file mode 100644 index f71cf6c8..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.sass +++ /dev/null @@ -1,5 +0,0 @@ -.filter-panel - display: flex - - button - flex: 1 !important diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js index 54605775..f652429d 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js @@ -2,10 +2,10 @@ import React from 'react' import GoogleLogin from 'react-google-login' import { useDispatch } from 'react-redux' import { logIn } from '../../actions/auth' +import { Button } from 'reactstrap' import config from '../../config' -const Login = (props) => { - const { visible } = props +function Login({ visible, className }) { const dispatch = useDispatch() const onLogin = (payload) => dispatch(logIn(payload)) @@ -34,9 +34,9 @@ const Login = (props) => { onSuccess={onAuthResponse} onFailure={onAuthFailure} render={(renderProps) => ( - + )} /> ) diff --git a/opendc-web/opendc-web-ui/src/index.js b/opendc-web/opendc-web-ui/src/index.js index ae3a5ddc..d40d17a2 100644 --- a/opendc-web/opendc-web-ui/src/index.js +++ b/opendc-web/opendc-web-ui/src/index.js @@ -4,7 +4,7 @@ import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' import { Provider } from 'react-redux' import { setupSocketConnection } from './api/socket' -import './index.sass' +import './index.scss' import Routes from './routes' import config from './config' import configureStore from './store/configure-store' diff --git a/opendc-web/opendc-web-ui/src/index.sass b/opendc-web/opendc-web-ui/src/index.sass deleted file mode 100644 index a78f7a19..00000000 --- a/opendc-web/opendc-web-ui/src/index.sass +++ /dev/null @@ -1,52 +0,0 @@ -@import "~bootstrap/scss/bootstrap" - -@import ./style-globals/_mixins.sass -@import ./style-globals/_variables.sass - -html, body, #root - margin: 0 - padding: 0 - width: 100% - height: 100% - - font-family: Roboto, Helvetica, Verdana, sans-serif - background: #eee - - // Scroll padding for top navbar - scroll-padding-top: 60px - -.full-height - position: relative - height: 100% !important - -.page-container - padding-top: 60px - -.text-page-container - padding-top: 80px - display: flex - flex-flow: column - -.vertically-expanding-container - flex: 1 1 auto - overflow-y: auto - -.bottom-btn-container - flex: 0 1 auto - padding: 20px 0 - -.btn, .list-group-item-action, .clickable - +clickable - -.btn-circle - +border-radius(50%) - -a, a:hover - text-decoration: none - -.app-page-container - padding-left: $side-bar-width - padding-top: 15px - -.w-70 - width: 70% !important diff --git a/opendc-web/opendc-web-ui/src/index.scss b/opendc-web/opendc-web-ui/src/index.scss new file mode 100644 index 00000000..0c1ddff4 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/index.scss @@ -0,0 +1,68 @@ +@import '~bootstrap/scss/bootstrap'; + +@import './style-globals/_mixins.scss'; +@import './style-globals/_variables.scss'; + +html, +body, +#root { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + + font-family: Roboto, Helvetica, Verdana, sans-serif; + background: #eee; + + // Scroll padding for top navbar + scroll-padding-top: 60px; +} + +.full-height { + position: relative; + height: 100% !important; +} + +.page-container { + padding-top: 60px; +} + +.text-page-container { + padding-top: 80px; + display: flex; + flex-flow: column; +} + +.vertically-expanding-container { + flex: 1 1 auto; + overflow-y: auto; +} + +.bottom-btn-container { + flex: 0 1 auto; + padding: 20px 0; +} + +.btn, +.list-group-item-action, +.clickable { + @include clickable; +} + +.btn-circle { + border-radius: 50%; +} + +a, +a:hover { + text-decoration: none; +} + +.app-page-container { + padding-left: $side-bar-width; + padding-top: 15px; +} + +.w-70 { + width: 70% !important; +} diff --git a/opendc-web/opendc-web-ui/src/pages/Home.js b/opendc-web/opendc-web-ui/src/pages/Home.js index fb383426..ee930fbe 100644 --- a/opendc-web/opendc-web-ui/src/pages/Home.js +++ b/opendc-web/opendc-web-ui/src/pages/Home.js @@ -8,7 +8,14 @@ import StakeholderSection from '../components/home/StakeholderSection' import TeamSection from '../components/home/TeamSection' import TechnologiesSection from '../components/home/TechnologiesSection' import HomeNavbar from '../components/navigation/HomeNavbar' -import './Home.sass' +import { + introSection, + stakeholderSection, + modelingSection, + simulationSection, + technologiesSection, + teamSection, +} from './Home.module.scss' import { useDocumentTitle } from '../util/hooks' function Home() { @@ -18,12 +25,12 @@ function Home() {
        - - - - - - + + + + + +
        diff --git a/opendc-web/opendc-web-ui/src/pages/Home.module.scss b/opendc-web/opendc-web-ui/src/pages/Home.module.scss new file mode 100644 index 00000000..aed1d88f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/pages/Home.module.scss @@ -0,0 +1,16 @@ +.bodyWrapper { + position: relative; + overflow-y: hidden; +} + +.introSection, +.modelingSection, +.technologiesSection { + background-color: #fff; +} + +.stakeholderSection, +.simulationSection, +.teamSection { + background-color: #f2f2f2; +} diff --git a/opendc-web/opendc-web-ui/src/pages/Home.sass b/opendc-web/opendc-web-ui/src/pages/Home.sass deleted file mode 100644 index 79cb9698..00000000 --- a/opendc-web/opendc-web-ui/src/pages/Home.sass +++ /dev/null @@ -1,9 +0,0 @@ -.body-wrapper - position: relative - overflow-y: hidden - -.intro-section, .modeling-section, .technologies-section - background-color: #fff - -.stakeholder-section, .simulation-section, .team-section - background-color: #f2f2f2 diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.js b/opendc-web/opendc-web-ui/src/pages/NotFound.js index b933ffa5..409ffa0e 100644 --- a/opendc-web/opendc-web-ui/src/pages/NotFound.js +++ b/opendc-web/opendc-web-ui/src/pages/NotFound.js @@ -1,12 +1,12 @@ import React from 'react' import TerminalWindow from '../components/not-found/TerminalWindow' -import './NotFound.sass' +import style from './NotFound.module.scss' import { useDocumentTitle } from '../util/hooks' const NotFound = () => { useDocumentTitle('Page Not Found - OpenDC') return ( -
        +
        ) diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.module.scss b/opendc-web/opendc-web-ui/src/pages/NotFound.module.scss new file mode 100644 index 00000000..e91c2780 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/pages/NotFound.module.scss @@ -0,0 +1,8 @@ +.not-found-backdrop { + display: flex; + + width: 100%; + height: 100%; + + background-image: linear-gradient(135deg, #00678a, #008fbf, #00a6d6); +} diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.sass b/opendc-web/opendc-web-ui/src/pages/NotFound.sass deleted file mode 100644 index 59231f7a..00000000 --- a/opendc-web/opendc-web-ui/src/pages/NotFound.sass +++ /dev/null @@ -1,11 +0,0 @@ -.not-found-backdrop - position: absolute - left: 0 - top: 0 - - margin: 0 - padding: 0 - width: 100% - height: 100% - - background-image: linear-gradient(135deg, #00678a, #008fbf, #00A6D6) diff --git a/opendc-web/opendc-web-ui/src/style-globals/_mixins.sass b/opendc-web/opendc-web-ui/src/style-globals/_mixins.sass deleted file mode 100644 index d0a8d1ac..00000000 --- a/opendc-web/opendc-web-ui/src/style-globals/_mixins.sass +++ /dev/null @@ -1,21 +0,0 @@ -=transition($property, $time) - -webkit-transition: $property $time - -moz-transition: $property $time - -o-transition: $property $time - transition: $property $time - -=user-select - -webkit-user-select: none - -moz-user-select: none - -ms-user-select: none - user-select: none - -=border-radius($length) - -webkit-border-radius: $length - -moz-border-radius: $length - border-radius: $length - -/* General Button Abstractions */ -=clickable - cursor: pointer - +user-select diff --git a/opendc-web/opendc-web-ui/src/style-globals/_mixins.scss b/opendc-web/opendc-web-ui/src/style-globals/_mixins.scss new file mode 100644 index 00000000..5f103cd7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/style-globals/_mixins.scss @@ -0,0 +1,5 @@ +/* General Button Abstractions */ +@mixin clickable { + cursor: pointer; + user-select: none; +} diff --git a/opendc-web/opendc-web-ui/src/style-globals/_variables.sass b/opendc-web/opendc-web-ui/src/style-globals/_variables.sass deleted file mode 100644 index 7553caa0..00000000 --- a/opendc-web/opendc-web-ui/src/style-globals/_variables.sass +++ /dev/null @@ -1,31 +0,0 @@ -// Sizes and Margins -$document-padding: 20px -$inter-element-margin: 5px -$standard-border-radius: 5px -$side-menu-width: 350px -$color-indicator-width: 140px - -$global-padding: 30px -$side-bar-width: 350px -$navbar-height: 50px -$navbar-padding: 10px - -// Durations -$transition-length: 150ms - -// Colors -$gray-very-dark: #5c5c5c -$gray-dark: #aaa -$gray-semi-dark: #bbb -$gray-semi-light: #ccc -$gray-light: #ddd -$gray-very-light: #eee -$blue: #00A6D6 -$blue-dark: #0087b5 -$blue-very-dark: #006182 -$blue-light: #deebf7 - -// Media queries -$screen-sm: 768px -$screen-md: 992px -$screen-lg: 1200px diff --git a/opendc-web/opendc-web-ui/src/style-globals/_variables.scss b/opendc-web/opendc-web-ui/src/style-globals/_variables.scss new file mode 100644 index 00000000..e3df6cbd --- /dev/null +++ b/opendc-web/opendc-web-ui/src/style-globals/_variables.scss @@ -0,0 +1,31 @@ +// Sizes and Margins +$document-padding: 20px; +$inter-element-margin: 5px; +$standard-border-radius: 5px; +$side-menu-width: 350px; +$color-indicator-width: 140px; + +$global-padding: 30px; +$side-bar-width: 350px; +$navbar-height: 50px; +$navbar-padding: 10px; + +// Durations +$transition-length: 150ms; + +// Colors +$gray-very-dark: #5c5c5c; +$gray-dark: #aaa; +$gray-semi-dark: #bbb; +$gray-semi-light: #ccc; +$gray-light: #ddd; +$gray-very-light: #eee; +$blue: #00a6d6; +$blue-dark: #0087b5; +$blue-very-dark: #006182; +$blue-light: #deebf7; + +// Media queries +$screen-sm: 768px; +$screen-md: 992px; +$screen-lg: 1200px; -- cgit v1.2.3 From 2dbb06f433964ccac13fd64ef512ed03142ed97b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 11 May 2021 16:34:25 +0200 Subject: ui: Move communication to REST API This change removes the socket.io websocket connection/client in favour of the OpenDC REST API. The socket.io websocket implementation was intended to be used for interactive and collaborative datacenter design and exploration. However, we do not support this functionality at the moment (collaborative design and exploration) and having the entire API run over this websocket connection is fragile and not standard practice. To improve maintainability, we therefore remove the websocket implementation in favour of the OpenDC REST API implementation using the fetch API. If we want to implement collaboration in the future, we will develop appropriate extensions in conjuction with the existing REST API. For this, we should look for standard and existing implementation of this functionality. --- opendc-web/opendc-web-ui/package.json | 1 - opendc-web/opendc-web-ui/src/api/index.js | 31 +++-- .../opendc-web-ui/src/api/routes/portfolios.js | 35 +---- opendc-web/opendc-web-ui/src/api/routes/prefabs.js | 33 +---- .../opendc-web-ui/src/api/routes/projects.js | 33 +---- .../opendc-web-ui/src/api/routes/scenarios.js | 35 +---- .../opendc-web-ui/src/api/routes/schedulers.js | 4 +- .../opendc-web-ui/src/api/routes/topologies.js | 35 +---- opendc-web/opendc-web-ui/src/api/routes/traces.js | 4 +- opendc-web/opendc-web-ui/src/api/routes/users.js | 41 +----- opendc-web/opendc-web-ui/src/api/routes/util.js | 37 ----- opendc-web/opendc-web-ui/src/api/socket.js | 50 ------- opendc-web/opendc-web-ui/src/index.js | 37 +++-- opendc-web/opendc-web-ui/yarn.lock | 152 +-------------------- 14 files changed, 72 insertions(+), 456 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/api/routes/util.js delete mode 100644 opendc-web/opendc-web-ui/src/api/socket.js diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 0a29bcff..61099709 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -46,7 +46,6 @@ "redux-saga": "~1.1.3", "redux-thunk": "~2.3.0", "sass": "^1.32.12", - "socket.io-client": "~2.3.0", "svgsaver": "~0.9.0", "uuidv4": "~6.1.1" }, diff --git a/opendc-web/opendc-web-ui/src/api/index.js b/opendc-web/opendc-web-ui/src/api/index.js index cefcb2c5..e6528fd9 100644 --- a/opendc-web/opendc-web-ui/src/api/index.js +++ b/opendc-web/opendc-web-ui/src/api/index.js @@ -1,13 +1,22 @@ -import { sendSocketRequest } from './socket' - -export function sendRequest(request) { - return new Promise((resolve, reject) => { - sendSocketRequest(request, (response) => { - if (response.status.code === 200) { - resolve(response.content) - } else { - reject(response) - } - }) +import config from '../config' +import { getAuthToken } from '../auth' + +const apiUrl = config['API_BASE_URL'] + +export async function request(path, method = 'GET', body) { + const res = await fetch(`${apiUrl}/v2/${path}`, { + method: method, + headers: { + 'auth-token': getAuthToken(), + 'Content-Type': 'application/json', + }, + body: body && JSON.stringify(body), }) + const { status, content } = await res.json() + + if (status.code !== 200) { + throw status + } + + return content } diff --git a/opendc-web/opendc-web-ui/src/api/routes/portfolios.js b/opendc-web/opendc-web-ui/src/api/routes/portfolios.js index 7c9ea02a..ba15e828 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/portfolios.js +++ b/opendc-web/opendc-web-ui/src/api/routes/portfolios.js @@ -1,42 +1,17 @@ -import { deleteById, getById } from './util' -import { sendRequest } from '../index' +import { request } from '../index' export function addPortfolio(projectId, portfolio) { - return sendRequest({ - path: '/projects/{projectId}/portfolios', - method: 'POST', - parameters: { - body: { - portfolio, - }, - path: { - projectId, - }, - query: {}, - }, - }) + return request(`projects/${projectId}/portfolios`, 'POST', { portfolio }) } export function getPortfolio(portfolioId) { - return getById('/portfolios/{portfolioId}', { portfolioId }) + return request(`portfolios/${portfolioId}`) } export function updatePortfolio(portfolioId, portfolio) { - return sendRequest({ - path: '/portfolios/{projectId}', - method: 'POST', - parameters: { - body: { - portfolio, - }, - path: { - portfolioId, - }, - query: {}, - }, - }) + return request(`portfolios/${portfolioId}`, 'PUT', { portfolio }) } export function deletePortfolio(portfolioId) { - return deleteById('/portfolios/{portfolioId}', { portfolioId }) + return request(`portfolios/${portfolioId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/prefabs.js b/opendc-web/opendc-web-ui/src/api/routes/prefabs.js index 8a1debfa..032e12bc 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/prefabs.js +++ b/opendc-web/opendc-web-ui/src/api/routes/prefabs.js @@ -1,40 +1,17 @@ -import { sendRequest } from '../index' -import { deleteById, getById } from './util' +import { request } from '../index' export function getPrefab(prefabId) { - return getById('/prefabs/{prefabId}', { prefabId }) + return request(`prefabs/${prefabId}`) } export function addPrefab(prefab) { - return sendRequest({ - path: '/prefabs', - method: 'POST', - parameters: { - body: { - prefab, - }, - path: {}, - query: {}, - }, - }) + return request('prefabs', 'POST', { prefab }) } export function updatePrefab(prefab) { - return sendRequest({ - path: '/prefabs/{prefabId}', - method: 'PUT', - parameters: { - body: { - prefab, - }, - path: { - prefabId: prefab._id, - }, - query: {}, - }, - }) + return request(`prefabs/${prefab._id}`, 'PUT', { prefab }) } export function deletePrefab(prefabId) { - return deleteById('/prefabs/{prefabId}', { prefabId }) + return request(`prefabs/${prefabId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/projects.js b/opendc-web/opendc-web-ui/src/api/routes/projects.js index 4109079c..cd46036f 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/projects.js +++ b/opendc-web/opendc-web-ui/src/api/routes/projects.js @@ -1,40 +1,17 @@ -import { sendRequest } from '../index' -import { deleteById, getById } from './util' +import { request } from '../index' export function getProject(projectId) { - return getById('/projects/{projectId}', { projectId }) + return request(`projects/${projectId}`) } export function addProject(project) { - return sendRequest({ - path: '/projects', - method: 'POST', - parameters: { - body: { - project, - }, - path: {}, - query: {}, - }, - }) + return request('projects', 'POST', { project }) } export function updateProject(project) { - return sendRequest({ - path: '/projects/{projectId}', - method: 'PUT', - parameters: { - body: { - project, - }, - path: { - projectId: project._id, - }, - query: {}, - }, - }) + return request(`projects/${project._id}`, 'PUT', { project }) } export function deleteProject(projectId) { - return deleteById('/projects/{projectId}', { projectId }) + return request(`projects/${projectId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/scenarios.js b/opendc-web/opendc-web-ui/src/api/routes/scenarios.js index ab2e8b86..00cc1eb0 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/scenarios.js +++ b/opendc-web/opendc-web-ui/src/api/routes/scenarios.js @@ -1,42 +1,17 @@ -import { deleteById, getById } from './util' -import { sendRequest } from '../index' +import { request } from '../index' export function addScenario(portfolioId, scenario) { - return sendRequest({ - path: '/portfolios/{portfolioId}/scenarios', - method: 'POST', - parameters: { - body: { - scenario, - }, - path: { - portfolioId, - }, - query: {}, - }, - }) + return request(`portfolios/${portfolioId}/scenarios`, 'POST', { scenario }) } export function getScenario(scenarioId) { - return getById('/scenarios/{scenarioId}', { scenarioId }) + return request(`scenarios/${scenarioId}`) } export function updateScenario(scenarioId, scenario) { - return sendRequest({ - path: '/scenarios/{projectId}', - method: 'POST', - parameters: { - body: { - scenario, - }, - path: { - scenarioId, - }, - query: {}, - }, - }) + return request(`scenarios/${scenarioId}`, 'PUT', { scenario }) } export function deleteScenario(scenarioId) { - return deleteById('/scenarios/{scenarioId}', { scenarioId }) + return request(`scenarios/${scenarioId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/schedulers.js b/opendc-web/opendc-web-ui/src/api/routes/schedulers.js index 4481fb2a..5e129d33 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/schedulers.js +++ b/opendc-web/opendc-web-ui/src/api/routes/schedulers.js @@ -1,5 +1,5 @@ -import { getAll } from './util' +import { request } from '../index' export function getAllSchedulers() { - return getAll('/schedulers') + return request('schedulers') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/topologies.js b/opendc-web/opendc-web-ui/src/api/routes/topologies.js index a8f0d6b1..076895ff 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/topologies.js +++ b/opendc-web/opendc-web-ui/src/api/routes/topologies.js @@ -1,42 +1,17 @@ -import { deleteById, getById } from './util' -import { sendRequest } from '../index' +import { request } from '../index' export function addTopology(topology) { - return sendRequest({ - path: '/projects/{projectId}/topologies', - method: 'POST', - parameters: { - body: { - topology, - }, - path: { - projectId: topology.projectId, - }, - query: {}, - }, - }) + return request(`projects/${topology.projectId}/topologies`, 'POST', { topology }) } export function getTopology(topologyId) { - return getById('/topologies/{topologyId}', { topologyId }) + return request(`topologies/${topologyId}`) } export function updateTopology(topology) { - return sendRequest({ - path: '/topologies/{topologyId}', - method: 'PUT', - parameters: { - body: { - topology, - }, - path: { - topologyId: topology._id, - }, - query: {}, - }, - }) + return request(`topologies/${topology._id}`, 'PUT', { topology }) } export function deleteTopology(topologyId) { - return deleteById('/topologies/{topologyId}', { topologyId }) + return request(`topologies/${topologyId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/traces.js b/opendc-web/opendc-web-ui/src/api/routes/traces.js index 67895a87..eb2526ee 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/traces.js +++ b/opendc-web/opendc-web-ui/src/api/routes/traces.js @@ -1,5 +1,5 @@ -import { getAll } from './util' +import { request } from '../index' export function getAllTraces() { - return getAll('/traces') + return request('traces') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/users.js b/opendc-web/opendc-web-ui/src/api/routes/users.js index 3028f3f7..619aec1f 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/users.js +++ b/opendc-web/opendc-web-ui/src/api/routes/users.js @@ -1,48 +1,17 @@ -import { sendRequest } from '../index' -import { deleteById } from './util' +import { request } from '../index' export function getUserByEmail(email) { - return sendRequest({ - path: '/users', - method: 'GET', - parameters: { - body: {}, - path: {}, - query: { - email, - }, - }, - }) + return request(`users` + new URLSearchParams({ email })) } export function addUser(user) { - return sendRequest({ - path: '/users', - method: 'POST', - parameters: { - body: { - user, - }, - path: {}, - query: {}, - }, - }) + return request('users', 'POST', { user }) } export function getUser(userId) { - return sendRequest({ - path: '/users/{userId}', - method: 'GET', - parameters: { - body: {}, - path: { - userId, - }, - query: {}, - }, - }) + return request(`users/${userId}`) } export function deleteUser(userId) { - return deleteById('/users/{userId}', { userId }) + return request(`users/${userId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/routes/util.js b/opendc-web/opendc-web-ui/src/api/routes/util.js deleted file mode 100644 index 67e7173b..00000000 --- a/opendc-web/opendc-web-ui/src/api/routes/util.js +++ /dev/null @@ -1,37 +0,0 @@ -import { sendRequest } from '../index' - -export function getAll(path) { - return sendRequest({ - path, - method: 'GET', - parameters: { - body: {}, - path: {}, - query: {}, - }, - }) -} - -export function getById(path, pathObject) { - return sendRequest({ - path, - method: 'GET', - parameters: { - body: {}, - path: pathObject, - query: {}, - }, - }) -} - -export function deleteById(path, pathObject) { - return sendRequest({ - path, - method: 'DELETE', - parameters: { - body: {}, - path: pathObject, - query: {}, - }, - }) -} diff --git a/opendc-web/opendc-web-ui/src/api/socket.js b/opendc-web/opendc-web-ui/src/api/socket.js deleted file mode 100644 index 87facda8..00000000 --- a/opendc-web/opendc-web-ui/src/api/socket.js +++ /dev/null @@ -1,50 +0,0 @@ -import io from 'socket.io-client' -import { getAuthToken } from '../auth/index' -import config from '../config' - -let socket -let requestIdCounter = 0 -const callbacks = {} - -export function setupSocketConnection(onConnect) { - const apiUrl = - config['API_BASE_URL'] || `${window.location.protocol}//${window.location.hostname}:${window.location.port}` - - socket = io.connect(apiUrl) - socket.on('connect', onConnect) - socket.on('response', onSocketResponse) -} - -export function sendSocketRequest(request, callback) { - if (!socket.connected) { - console.error('Attempted to send request over unconnected socket') - return - } - - const newId = requestIdCounter++ - callbacks[newId] = callback - - request.id = newId - request.token = getAuthToken() - - if (!request.isRootRoute) { - request.path = '/v2' + request.path - } - - socket.emit('request', request) - - if (process.env.NODE_ENV !== 'production') { - console.log('Sent socket request:', request) - } -} - -function onSocketResponse(json) { - const response = JSON.parse(json) - - if (process.env.NODE_ENV !== 'production') { - console.log('Received socket response:', response) - } - - callbacks[response.id](response) - delete callbacks[response.id] -} diff --git a/opendc-web/opendc-web-ui/src/index.js b/opendc-web/opendc-web-ui/src/index.js index d40d17a2..fdfec24b 100644 --- a/opendc-web/opendc-web-ui/src/index.js +++ b/opendc-web/opendc-web-ui/src/index.js @@ -3,30 +3,27 @@ import ReactDOM from 'react-dom' import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' import { Provider } from 'react-redux' -import { setupSocketConnection } from './api/socket' import './index.scss' import Routes from './routes' import config from './config' import configureStore from './store/configure-store' -setupSocketConnection(() => { - const store = configureStore() +const store = configureStore() - // Initialize Sentry if the user has configured a DSN - const dsn = config['SENTRY_DSN'] - if (dsn) { - Sentry.init({ - environment: process.env.NODE_ENV, - dsn: dsn, - integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 0.1, - }) - } +// Initialize Sentry if the user has configured a DSN +const dsn = config['SENTRY_DSN'] +if (dsn) { + Sentry.init({ + environment: process.env.NODE_ENV, + dsn: dsn, + integrations: [new Integrations.BrowserTracing()], + tracesSampleRate: 0.1, + }) +} - ReactDOM.render( - - - , - document.getElementById('root') - ) -}) +ReactDOM.render( + + + , + document.getElementById('root') +) diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 8549a280..cc7173a0 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -2362,11 +2362,6 @@ adjust-sourcemap-loader@3.0.0: loader-utils "^2.0.0" regex-parser "^2.2.11" -after@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" - integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -2584,11 +2579,6 @@ array.prototype.flatmap@^1.2.4: es-abstract "^1.18.0-next.1" function-bind "^1.1.1" -arraybuffer.slice@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" - integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== - arrify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" @@ -2897,21 +2887,11 @@ babylon@^6.18.0: resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== -backo2@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" - integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= - base64-js@^1.0.2: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -2974,11 +2954,6 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -blob@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" - integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== - bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -3620,21 +3595,11 @@ complex.js@^2.0.11: resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.12.tgz#fa4df97d8928e5f7b6a86b35bdeecc3a3eda8a22" integrity sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw== -component-bind@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" - integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= - -component-emitter@^1.2.1, component-emitter@~1.3.0: +component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -component-inherit@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" - integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= - compose-function@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" @@ -4223,13 +4188,6 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" -debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -4613,34 +4571,6 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -engine.io-client@~3.4.0: - version "3.4.4" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.4.tgz#77d8003f502b0782dd792b073a4d2cf7ca5ab967" - integrity sha512-iU4CRr38Fecj8HoZEnFtm2EiKGbYZcPn3cHxqNGl/tmdWRf60KhK+9vE0JeSjgnlS/0oynEfLgKbT9ALpim0sQ== - dependencies: - component-emitter "~1.3.0" - component-inherit "0.0.3" - debug "~3.1.0" - engine.io-parser "~2.2.0" - has-cors "1.1.0" - indexof "0.0.1" - parseqs "0.0.6" - parseuri "0.0.6" - ws "~6.1.0" - xmlhttprequest-ssl "~1.5.4" - yeast "0.1.2" - -engine.io-parser@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.1.tgz#57ce5611d9370ee94f99641b589f94c97e4f5da7" - integrity sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg== - dependencies: - after "0.8.2" - arraybuffer.slice "~0.0.7" - base64-arraybuffer "0.1.4" - blob "0.0.5" - has-binary2 "~1.0.2" - enhanced-resolve@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" @@ -5748,18 +5678,6 @@ has-bigints@^1.0.1: resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== -has-binary2@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" - integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== - dependencies: - isarray "2.0.1" - -has-cors@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" - integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -6158,11 +6076,6 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= - infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -6584,11 +6497,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isarray@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" - integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -8422,16 +8330,6 @@ parse5@6.0.1: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parseqs@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5" - integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w== - -parseuri@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a" - integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow== - parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -10742,32 +10640,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -socket.io-client@~2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.1.tgz#91a4038ef4d03c19967bb3c646fec6e0eaa78cff" - integrity sha512-YXmXn3pA8abPOY//JtYxou95Ihvzmg8U6kQyolArkIyLd0pgVhrfor/iMsox8cn07WCOOvvuJ6XKegzIucPutQ== - dependencies: - backo2 "1.0.2" - component-bind "1.0.0" - component-emitter "~1.3.0" - debug "~3.1.0" - engine.io-client "~3.4.0" - has-binary2 "~1.0.2" - indexof "0.0.1" - parseqs "0.0.6" - parseuri "0.0.6" - socket.io-parser "~3.3.0" - to-array "0.1.4" - -socket.io-parser@~3.3.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.2.tgz#ef872009d0adcf704f2fbe830191a14752ad50b6" - integrity sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg== - dependencies: - component-emitter "~1.3.0" - debug "~3.1.0" - isarray "2.0.1" - sockjs-client@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.1.tgz#256908f6d5adfb94dabbdbd02c66362cca0f9ea6" @@ -11405,11 +11277,6 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= -to-array@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" - integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= - to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -12368,13 +12235,6 @@ ws@^7.4.4: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== -ws@~6.1.0: - version "6.1.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" - integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== - dependencies: - async-limiter "~1.0.0" - xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" @@ -12385,11 +12245,6 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xmlhttprequest-ssl@~1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" - integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= - xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -12464,11 +12319,6 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yeast@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" - integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" -- cgit v1.2.3 From d21606bd238702645690586df5ad5b5075ca09c9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 11 May 2021 16:45:23 +0200 Subject: ui: Ensure Redux logger is last in middleware chain This change updates the Redux store initialization to ensure that the Redux logger is last in the middleware change. If we do not do this, Redux Logger might log thunds and promises, but not actual actions. See https://github.com/LogRocket/redux-logger/issues/20 --- opendc-web/opendc-web-ui/src/store/configure-store.js | 14 +++----------- .../src/store/middlewares/dummy-middleware.js | 3 --- 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/store/middlewares/dummy-middleware.js diff --git a/opendc-web/opendc-web-ui/src/store/configure-store.js b/opendc-web/opendc-web-ui/src/store/configure-store.js index d8f343ed..13bcd69e 100644 --- a/opendc-web/opendc-web-ui/src/store/configure-store.js +++ b/opendc-web/opendc-web-ui/src/store/configure-store.js @@ -6,24 +6,16 @@ import thunk from 'redux-thunk' import { authRedirectMiddleware } from '../auth/index' import rootReducer from '../reducers/index' import rootSaga from '../sagas/index' -import { dummyMiddleware } from './middlewares/dummy-middleware' import { viewportAdjustmentMiddleware } from './middlewares/viewport-adjustment' const sagaMiddleware = createSagaMiddleware() -let logger +const middlewares = [thunk, sagaMiddleware, authRedirectMiddleware, viewportAdjustmentMiddleware] + if (process.env.NODE_ENV !== 'production') { - logger = createLogger() + middlewares.push(createLogger()) } -const middlewares = [ - process.env.NODE_ENV === 'production' ? dummyMiddleware : logger, - thunk, - sagaMiddleware, - authRedirectMiddleware, - viewportAdjustmentMiddleware, -] - export let store = undefined export default function configureStore() { diff --git a/opendc-web/opendc-web-ui/src/store/middlewares/dummy-middleware.js b/opendc-web/opendc-web-ui/src/store/middlewares/dummy-middleware.js deleted file mode 100644 index 5ba35691..00000000 --- a/opendc-web/opendc-web-ui/src/store/middlewares/dummy-middleware.js +++ /dev/null @@ -1,3 +0,0 @@ -export const dummyMiddleware = (store) => (next) => (action) => { - next(action) -} -- cgit v1.2.3 From 4397a959e806bf476be4c81bc804616adf58b969 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 12 May 2021 22:42:12 +0200 Subject: ui: Migrate from CRA to Next.js This change updates the web frontend to use Next.js instead of Create React App (CRA). Next.js enables the possibility of rendering pages on the server side (which reduces the time to first frame) and overall provides a better development experience. Future commits will try to futher optimize the implementation for Next.js. --- .github/workflows/build.yml | 9 +- opendc-web/opendc-web-ui/.gitignore | 4 +- opendc-web/opendc-web-ui/README.md | 69 +- opendc-web/opendc-web-ui/package.json | 13 +- opendc-web/opendc-web-ui/src/actions/map.js | 1 + .../opendc-web-ui/src/actions/modals/profile.js | 14 - opendc-web/opendc-web-ui/src/api/index.js | 31 +- .../opendc-web-ui/src/api/routes/token-signin.js | 4 +- opendc-web/opendc-web-ui/src/auth/hook.js | 44 + opendc-web/opendc-web-ui/src/auth/index.js | 2 +- .../src/components/app/map/MapStageComponent.js | 118 +- .../app/sidebars/project/PortfolioListComponent.js | 13 +- .../app/sidebars/project/ScenarioListComponent.js | 13 +- .../src/components/modals/ConfirmationModal.js | 48 +- .../components/navigation/AppNavbarComponent.js | 20 +- .../src/components/navigation/LogoutButton.js | 3 +- .../src/components/navigation/Navbar.js | 47 +- .../src/components/not-found/TerminalWindow.js | 8 +- .../components/projects/ProjectActionButtons.js | 8 +- opendc-web/opendc-web-ui/src/config.js | 40 - opendc-web/opendc-web-ui/src/containers/app/App.js | 132 + .../src/containers/app/map/MapStage.js | 4 +- .../app/sidebars/project/PortfolioListContainer.js | 6 +- .../sidebars/project/ProjectSidebarContainer.js | 6 +- .../app/sidebars/project/TopologyListContainer.js | 8 +- .../opendc-web-ui/src/containers/auth/Login.js | 5 +- .../src/containers/modals/DeleteProfileModal.js | 27 - .../src/containers/modals/NewScenarioModal.js | 2 - opendc-web/opendc-web-ui/src/index.js | 29 - opendc-web/opendc-web-ui/src/index.scss | 2 +- opendc-web/opendc-web-ui/src/pages/404.js | 19 + opendc-web/opendc-web-ui/src/pages/404.module.scss | 8 + opendc-web/opendc-web-ui/src/pages/App.js | 103 - opendc-web/opendc-web-ui/src/pages/Home.js | 40 - .../opendc-web-ui/src/pages/Home.module.scss | 16 - opendc-web/opendc-web-ui/src/pages/NotFound.js | 15 - .../opendc-web-ui/src/pages/NotFound.module.scss | 8 - opendc-web/opendc-web-ui/src/pages/Profile.js | 31 - opendc-web/opendc-web-ui/src/pages/Projects.js | 30 - opendc-web/opendc-web-ui/src/pages/_app.js | 42 + opendc-web/opendc-web-ui/src/pages/_document.js | 96 + opendc-web/opendc-web-ui/src/pages/index.js | 42 + .../opendc-web-ui/src/pages/index.module.scss | 16 + opendc-web/opendc-web-ui/src/pages/profile.js | 54 + .../src/pages/projects/[project]/index.js | 37 + .../projects/[project]/portfolios/[portfolio].js | 37 + .../opendc-web-ui/src/pages/projects/index.js | 36 + opendc-web/opendc-web-ui/src/reducers/modals.js | 2 - opendc-web/opendc-web-ui/src/routes/index.js | 40 - .../opendc-web-ui/src/store/configure-store.js | 51 +- opendc-web/opendc-web-ui/src/util/hooks.js | 29 - opendc-web/opendc-web-ui/src/util/sidebar-space.js | 4 +- opendc-web/opendc-web-ui/yarn.lock | 12924 +++---------------- 53 files changed, 2725 insertions(+), 11685 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/actions/modals/profile.js create mode 100644 opendc-web/opendc-web-ui/src/auth/hook.js delete mode 100644 opendc-web/opendc-web-ui/src/config.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/App.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js delete mode 100644 opendc-web/opendc-web-ui/src/index.js create mode 100644 opendc-web/opendc-web-ui/src/pages/404.js create mode 100644 opendc-web/opendc-web-ui/src/pages/404.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/pages/App.js delete mode 100644 opendc-web/opendc-web-ui/src/pages/Home.js delete mode 100644 opendc-web/opendc-web-ui/src/pages/Home.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/pages/NotFound.js delete mode 100644 opendc-web/opendc-web-ui/src/pages/NotFound.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/pages/Profile.js delete mode 100644 opendc-web/opendc-web-ui/src/pages/Projects.js create mode 100644 opendc-web/opendc-web-ui/src/pages/_app.js create mode 100644 opendc-web/opendc-web-ui/src/pages/_document.js create mode 100644 opendc-web/opendc-web-ui/src/pages/index.js create mode 100644 opendc-web/opendc-web-ui/src/pages/index.module.scss create mode 100644 opendc-web/opendc-web-ui/src/pages/profile.js create mode 100644 opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js create mode 100644 opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js create mode 100644 opendc-web/opendc-web-ui/src/pages/projects/index.js delete mode 100644 opendc-web/opendc-web-ui/src/routes/index.js delete mode 100644 opendc-web/opendc-web-ui/src/util/hooks.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cbf2f80d..f2effb2f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,18 +98,17 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node: [14.x] + node: [16] defaults: run: working-directory: opendc-web/opendc-web-ui steps: - uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: node-version: ${{ matrix.node }} - - run: npm install - - run: npm run build --if-present - - run: npm test + - run: yarn install --frozen-lockfile + - run: yarn build env: CI: true diff --git a/opendc-web/opendc-web-ui/.gitignore b/opendc-web/opendc-web-ui/.gitignore index 4fa931fe..3340b9ee 100644 --- a/opendc-web/opendc-web-ui/.gitignore +++ b/opendc-web/opendc-web-ui/.gitignore @@ -22,7 +22,9 @@ yarn-error.log* /.idea # Environment variables -.env +.env.local # Sass output *.css + +/.next diff --git a/opendc-web/opendc-web-ui/README.md b/opendc-web/opendc-web-ui/README.md index f3a58e7a..370c693d 100644 --- a/opendc-web/opendc-web-ui/README.md +++ b/opendc-web/opendc-web-ui/README.md @@ -7,16 +7,19 @@ Collaborative Datacenter Simulation and Exploration for Everybody

        -The user-facing component of the OpenDC stack, allowing users to build and interact with their own (virtual) datacenters. Built in *React.js* and *Redux*, with the help of `create-react-app`. - +The user-facing component of the OpenDC stack, allowing users to build and interact with their own (virtual) +datacenters. Built in *React.js* and *Redux*, with the help of [Next.js](https://nextjs.org/). ## Get Up and Running -Looking for the full OpenDC stack? Check out [the main OpenDC repo](https://github.com/atlarge-research/opendc) for instructions on how to set up a Docker container with all of OpenDC, without the hassle of running each of the components manually. +Looking for the full OpenDC stack? Check out the [root](https://github.com/atlarge-research/opendc) for instructions on +how to set up a Docker container with all of OpenDC, without the hassle of running each of the components manually. ### Installation -To get started, you'll need the [Node.js environment](https://nodejs.org) and the [Yarn package manager](https://yarnpkg.com). Once you have those installed, run the following command from the root directory of this repo: +To get started, you'll need the [Node.js environment](https://nodejs.org) and +the [Yarn package manager](https://yarnpkg.com). Once you have those installed, run the following command from the root +directory of this repo: ```bash yarn @@ -24,17 +27,22 @@ yarn ### Running the development server -First, you need to have a Google OAuth client ID set up. Check the [documentation of the main OpenDC repo](https://github.com/atlarge-research/opendc) if you're not sure how to do this. Once you have such an ID, you need to set it as environment variable `REACT_APP_OAUTH_CLIENT_ID`. One way of doing this is to create an `.env` file with content `REACT_APP_OAUTH_CLIENT_ID=YOUR_ID` (`YOUR_ID` without quotes), in the root directory of this repo. +First, you need to have a Google OAuth client ID set up. Check +the [documentation of the main OpenDC repo](https://github.com/atlarge-research/opendc) if you're not sure how to do +this. Once you have such an ID, you need to set it as environment variable `NEXT_PUBLIC_OAUTH_CLIENT_ID`. One way of +doing this is to create an `.env.local` file with content `NEXT_PUBLIC_OAUTH_CLIENT_ID=YOUR_ID` (`YOUR_ID` without +quotes), in the root directory of this repo. Once you've set this variable, start the OpenDC `docker-compose` setup. See the root README for instructions on this. - + Now, you're ready to start the development server: ```bash -yarn start +yarn dev ``` -This will start a development server running on [`localhost:3000`](http://localhost:3000), watching for changes you make to the code and rebuilding automatically when you save changes. +This will start a development server running on [`localhost:3000`](http://localhost:3000), watching for changes you make +to the code and rebuilding automatically when you save changes. To compile everything for camera-ready deployment, use the following command: @@ -42,47 +50,62 @@ To compile everything for camera-ready deployment, use the following command: yarn build ``` - ## Architecture -The codebase follows a standard React.js structure, with static assets being contained in the `public` folder, while dynamic components and their styles are contained in `src`. The app uses client-side routing (with `react-router`), meaning that the only HTML file needing to be served is a `index.html` file. +The codebase follows a standard React.js structure, with static assets being contained in the `public` folder, while +dynamic components and their styles are contained in `src`. ### Pages -All pages are represented by a component in the `src/pages` directory. There are components for the following pages: +All pages are represented by a component in the `src/pages` directory, following +the [Next.js conventions](https://nextjs.org/docs/routing/introduction) for routing. There are components for the +following pages: -**Home.js** - Entry page (`/`) +**index.js** - Entry page (`/`) -**Projects.js** - Overview of projects of the user (`/projects`) +**projects/index.js** - Overview of projects of the user (`/projects`) -**App.js** - Main application, with datacenter construction and simulation UI (`/projects/:projectId` and `/projects/:projectId/portfolios/:portfolioId`) +**projects/[project]/index.js** - Main application, with datacenter construction and simulation UI (`/projects/:projectId` +and `/projects/:projectId/portfolios/:portfolioId`) -**Profile.js** - Profile of the current user (`/profile`) +**profile.js** - Profile of the current user (`/profile`) -**NotFound.js** - 404 page to appear when the route is invalid (`/*`) +**404.js** - 404 page to appear when the route is invalid (`/*`) ### Components & Containers -The building blocks of the UI are divided into so-called *components* and *containers* ([as encouraged](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) by the author of Redux). *Components* are considered 'pure', rendered as a function of input properties. *Containers*, on the other hand, are wrappers around *components*, injecting state through the properties of the components they wrap. +The building blocks of the UI are divided into so-called *components* and * +containers* ([as encouraged](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) by the author of +Redux). *Components* are considered 'pure', rendered as a function of input properties. *Containers*, on the other hand, +are wrappers around *components*, injecting state through the properties of the components they wrap. -Even the canvas (the main component of the app) is built using React components, with the help of the `react-konva` module. To illustrate: A rectangular object on the canvas is defined in a way that is not very different from how we define a standard `div` element on the splashpage. +Even the canvas (the main component of the app) is built using React components, with the help of the `react-konva` +module. To illustrate: A rectangular object on the canvas is defined in a way that is not very different from how we +define a standard `div` element on the splashpage. ### State Management -Almost all state is kept in a central Redux store. State is kept there in an immutable form, only to be modified through actions being dispatched. These actions are contained in the `src/actions` folder, and the reducers (managing how state is updated according to dispatched actions) are located in `src/reducers`. If you're not familiar with the Redux approach to state management, have a look at their [official documentation](https://redux.js.org/). +Almost all state is kept in a central Redux store. State is kept there in an immutable form, only to be modified through +actions being dispatched. These actions are contained in the `src/actions` folder, and the reducers (managing how state +is updated according to dispatched actions) are located in `src/reducers`. If you're not familiar with the Redux +approach to state management, have a look at their [official documentation](https://redux.js.org/). ### API Interaction -The web-app needs to pull data in from the API of a backend running on a server. The functions that call routes are located in `src/api`. The actual logic responsible for calling these functions is contained in `src/sagas`. These API fetch procedures are written with the help of `redux-saga`. The [official documentation](https://redux-saga.js.org/) of `redux-saga` can be a helpful aid in understanding that part of the codebase. - +The web-app needs to pull data in from the API of a backend running on a server. The functions that call routes are +located in `src/api`. The actual logic responsible for calling these functions is contained in `src/sagas`. These API +fetch procedures are written with the help of `redux-saga`. The [official documentation](https://redux-saga.js.org/) +of `redux-saga` can be a helpful aid in understanding that part of the codebase. ## Tests -Files containing tests can be recognized by the `.test.js` suffix. They are usually located right next to the source code they are testing, to make discovery easier. +Files containing tests can be recognized by the `.test.js` suffix. They are usually located right next to the source +code they are testing, to make discovery easier. ### Running all tests -The following command runs all tests in the codebase. On top of this, it also watches the code for changes and reruns the tests whenever any file is saved. +The following command runs all tests in the codebase. On top of this, it also watches the code for changes and reruns +the tests whenever any file is saved. ```bash yarn test diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 61099709..f6917398 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -16,7 +16,6 @@ "author": "Georgios Andreadis (https://gandreadis.com/)", "license": "MIT", "private": true, - "proxy": "http://localhost:8081", "dependencies": { "@sentry/react": "^5.30.0", "@sentry/tracing": "^5.30.0", @@ -27,6 +26,7 @@ "konva": "~7.2.5", "lint-staged": "~10.2.2", "mathjs": "~7.6.0", + "next": "^10.2.0", "prettier": "~2.0.5", "prop-types": "~15.7.2", "react": "~17.0.2", @@ -36,12 +36,10 @@ "react-hotkeys": "^2.0.0", "react-konva": "~17.0.2-0", "react-redux": "~7.2.0", - "react-router-dom": "~5.1.2", - "react-scripts": "~4.0.3", "reactstrap": "^8.9.0", "recharts": "~2.0.9", "redux": "~4.0.5", - "redux-localstorage": "~0.4.1", + "redux-localstorage": "^0.4.1", "redux-logger": "~3.0.6", "redux-saga": "~1.1.3", "redux-thunk": "~2.3.0", @@ -58,10 +56,9 @@ "scripts": { "format": "prettier --write src", "precommit": "lint-staged", - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" + "dev": "next dev", + "build": "next build", + "start": "next start" }, "browserslist": { "production": [ diff --git a/opendc-web/opendc-web-ui/src/actions/map.js b/opendc-web/opendc-web-ui/src/actions/map.js index 0d49d849..09196dca 100644 --- a/opendc-web/opendc-web-ui/src/actions/map.js +++ b/opendc-web/opendc-web-ui/src/actions/map.js @@ -64,6 +64,7 @@ export function setMapPositionWithBoundsCheck(x, y) { const state = getState() const scaledMapSize = MAP_SIZE_IN_PIXELS * state.map.scale + const updatedX = x > 0 ? 0 diff --git a/opendc-web/opendc-web-ui/src/actions/modals/profile.js b/opendc-web/opendc-web-ui/src/actions/modals/profile.js deleted file mode 100644 index 39c72c03..00000000 --- a/opendc-web/opendc-web-ui/src/actions/modals/profile.js +++ /dev/null @@ -1,14 +0,0 @@ -export const OPEN_DELETE_PROFILE_MODAL = 'OPEN_DELETE_PROFILE_MODAL' -export const CLOSE_DELETE_PROFILE_MODAL = 'CLOSE_DELETE_PROFILE_MODAL' - -export function openDeleteProfileModal() { - return { - type: OPEN_DELETE_PROFILE_MODAL, - } -} - -export function closeDeleteProfileModal() { - return { - type: CLOSE_DELETE_PROFILE_MODAL, - } -} diff --git a/opendc-web/opendc-web-ui/src/api/index.js b/opendc-web/opendc-web-ui/src/api/index.js index e6528fd9..65358745 100644 --- a/opendc-web/opendc-web-ui/src/api/index.js +++ b/opendc-web/opendc-web-ui/src/api/index.js @@ -1,8 +1,35 @@ -import config from '../config' +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + import { getAuthToken } from '../auth' -const apiUrl = config['API_BASE_URL'] +const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL +/** + * Send the specified request to the OpenDC API. + * @param path Relative path for the API. + * @param method The method to use for the request. + * @param body The body of the request. + */ export async function request(path, method = 'GET', body) { const res = await fetch(`${apiUrl}/v2/${path}`, { method: method, diff --git a/opendc-web/opendc-web-ui/src/api/routes/token-signin.js b/opendc-web/opendc-web-ui/src/api/routes/token-signin.js index ced5d2e0..1c285bdb 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/token-signin.js +++ b/opendc-web/opendc-web-ui/src/api/routes/token-signin.js @@ -1,7 +1,5 @@ -import config from '../../config' - export function performTokenSignIn(token) { - const apiUrl = config['API_BASE_URL'] + const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL return fetch(`${apiUrl}/tokensignin`, { method: 'POST', diff --git a/opendc-web/opendc-web-ui/src/auth/hook.js b/opendc-web/opendc-web-ui/src/auth/hook.js new file mode 100644 index 00000000..ddaf53ed --- /dev/null +++ b/opendc-web/opendc-web-ui/src/auth/hook.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useEffect, useState } from 'react' +import { userIsLoggedIn } from './index' +import { useRouter } from 'next/router' + +export function useAuth() { + const [isLoggedIn, setLoggedIn] = useState(false) + + useEffect(() => { + setLoggedIn(userIsLoggedIn()) + }, []) + + return isLoggedIn +} + +export function useRequireAuth() { + const router = useRouter() + useEffect(() => { + if (!userIsLoggedIn()) { + router.replace('/') + } + }) +} diff --git a/opendc-web/opendc-web-ui/src/auth/index.js b/opendc-web/opendc-web-ui/src/auth/index.js index b5953990..148e2e13 100644 --- a/opendc-web/opendc-web-ui/src/auth/index.js +++ b/opendc-web/opendc-web-ui/src/auth/index.js @@ -2,7 +2,7 @@ import { LOG_IN_SUCCEEDED, LOG_OUT } from '../actions/auth' import { DELETE_CURRENT_USER_SUCCEEDED } from '../actions/users' const getAuthObject = () => { - const authItem = localStorage.getItem('auth') + const authItem = global.localStorage && localStorage.getItem('auth') if (!authItem || authItem === '{}') { return undefined } diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js index 7ca10792..dd32927f 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect, useMemo, useRef, useState } from 'react' import { HotKeys } from 'react-hotkeys' import { Stage } from 'react-konva' import MapLayer from '../../../containers/app/map/layers/MapLayer' @@ -6,85 +6,75 @@ import ObjectHoverLayer from '../../../containers/app/map/layers/ObjectHoverLaye import RoomHoverLayer from '../../../containers/app/map/layers/RoomHoverLayer' import { NAVBAR_HEIGHT } from '../../navigation/Navbar' import { MAP_MOVE_PIXELS_PER_EVENT } from './MapConstants' -import { Provider } from 'react-redux' -import { store } from '../../../store/configure-store' +import { Provider, useStore } from 'react-redux' -class MapStageComponent extends React.Component { - state = { - mouseX: 0, - mouseY: 0, +function MapStageComponent({ + mapDimensions, + mapPosition, + setMapDimensions, + setMapPositionWithBoundsCheck, + zoomInOnPosition, +}) { + const [pos, setPos] = useState([0, 0]) + const stage = useRef(null) + const [x, y] = pos + const handlers = { + MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), + MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), } - constructor(props) { - super(props) + const moveWithDelta = (deltaX, deltaY) => + setMapPositionWithBoundsCheck(mapPosition.x + deltaX, mapPosition.y + deltaY) + const updateMousePosition = () => { + if (!stage.current) { + return + } - this.updateDimensions = this.updateDimensions.bind(this) - this.updateScale = this.updateScale.bind(this) + const mousePos = stage.current.getStage().getPointerPosition() + setPos([mousePos.x, mousePos.y]) } + const updateDimensions = () => setMapDimensions(window.innerWidth, window.innerHeight - NAVBAR_HEIGHT) + const updateScale = (e) => zoomInOnPosition(e.deltaY < 0, x, y) - componentDidMount() { - this.updateDimensions() + useEffect(() => { + updateDimensions() - window.addEventListener('resize', this.updateDimensions) - window.addEventListener('wheel', this.updateScale) + window.addEventListener('resize', updateDimensions) + window.addEventListener('wheel', updateScale) window['exportCanvasToImage'] = () => { const download = document.createElement('a') - download.href = this.stage.getStage().toDataURL() + download.href = stage.current.getStage().toDataURL() download.download = 'opendc-canvas-export-' + Date.now() + '.png' download.click() } - } - - componentWillUnmount() { - window.removeEventListener('resize', this.updateDimensions) - window.removeEventListener('wheel', this.updateScale) - } - - updateDimensions() { - this.props.setMapDimensions(window.innerWidth, window.innerHeight - NAVBAR_HEIGHT) - } - - updateScale(e) { - this.props.zoomInOnPosition(e.deltaY < 0, this.state.mouseX, this.state.mouseY) - } - - updateMousePosition() { - const mousePos = this.stage.getStage().getPointerPosition() - this.setState({ mouseX: mousePos.x, mouseY: mousePos.y }) - } - handlers = { - MOVE_LEFT: () => this.moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), - MOVE_RIGHT: () => this.moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), - MOVE_UP: () => this.moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), - MOVE_DOWN: () => this.moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), - } + return () => { + window.removeEventListener('resize', updateDimensions) + window.removeEventListener('wheel', updateScale) + } + }, []) - moveWithDelta(deltaX, deltaY) { - this.props.setMapPositionWithBoundsCheck(this.props.mapPosition.x + deltaX, this.props.mapPosition.y + deltaY) - } + const store = useStore() - render() { - return ( - - { - this.stage = stage - }} - width={this.props.mapDimensions.width} - height={this.props.mapDimensions.height} - onMouseMove={this.updateMousePosition.bind(this)} - > - - - - - - - - ) - } + return ( + + + + + + + + + + ) } export default MapStageComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js index b000b9e2..b714a7d2 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types' import React from 'react' import Shapes from '../../../../shapes' -import { Link } from 'react-router-dom' +import Link from 'next/link' import FontAwesome from 'react-fontawesome' import ScenarioListContainer from '../../../../containers/app/sidebars/project/ScenarioListContainer' @@ -44,11 +44,12 @@ class PortfolioListComponent extends React.Component { {portfolio.name}
        - this.props.onChoosePortfolio(portfolio._id)} - /> + + this.props.onChoosePortfolio(portfolio._id)} + /> + this.onDelete(portfolio._id)} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js index e775a663..4efa99ef 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types' import React from 'react' import Shapes from '../../../../shapes' -import { Link } from 'react-router-dom' +import Link from 'next/link' import FontAwesome from 'react-fontawesome' class ScenarioListComponent extends React.Component { @@ -34,10 +34,13 @@ class ScenarioListComponent extends React.Component {
        this.props.onChooseScenario(scenario.portfolioId, scenario._id)} - /> + href={`/projects/${this.props.currentProjectId}/portfolios/${scenario.portfolioId}/scenarios/${scenario._id}`} + > + this.props.onChooseScenario(scenario.portfolioId, scenario._id)} + /> + (idx !== 0 ? this.onDelete(scenario._id) : undefined)} diff --git a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js index 589047dc..5a95810a 100644 --- a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js +++ b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js @@ -2,36 +2,26 @@ import PropTypes from 'prop-types' import React from 'react' import Modal from './Modal' -class ConfirmationModal extends React.Component { - static propTypes = { - title: PropTypes.string.isRequired, - message: PropTypes.string.isRequired, - show: PropTypes.bool.isRequired, - callback: PropTypes.func.isRequired, - } - - onConfirm() { - this.props.callback(true) - } - - onCancel() { - this.props.callback(false) - } +function ConfirmationModal({ title, message, show, callback }) { + return ( + callback(true)} + onCancel={() => callback(false)} + submitButtonType="danger" + submitButtonText="Confirm" + > + {message} + + ) +} - render() { - return ( - - {this.props.message} - - ) - } +ConfirmationModal.propTypes = { + title: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + show: PropTypes.bool.isRequired, + callback: PropTypes.func.isRequired, } export default ConfirmationModal diff --git a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js index 8c28c542..7b1eaae2 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js @@ -1,6 +1,6 @@ import React from 'react' import FontAwesome from 'react-fontawesome' -import { Link } from 'react-router-dom' +import Link from 'next/link' import { NavLink } from 'reactstrap' import Navbar, { NavItem } from './Navbar' import {} from './Navbar.module.scss' @@ -8,16 +8,20 @@ import {} from './Navbar.module.scss' const AppNavbarComponent = ({ project, fullWidth }) => ( - - - My Projects - + + + + My Projects + + {project ? ( - - {project.name} - + + + {project.name} + + ) : undefined} diff --git a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js index 78b02b44..0c0feeb1 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js @@ -1,11 +1,10 @@ import PropTypes from 'prop-types' import React from 'react' import FontAwesome from 'react-fontawesome' -import { Link } from 'react-router-dom' import { NavLink } from 'reactstrap' const LogoutButton = ({ onLogout }) => ( - + ) diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js index bf18f1c4..90f55665 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js @@ -1,5 +1,6 @@ import React, { useState } from 'react' -import { Link, useLocation } from 'react-router-dom' +import Link from 'next/link' +import { useRouter } from 'next/router' import { Navbar as RNavbar, NavItem as RNavItem, @@ -15,6 +16,7 @@ import Login from '../../containers/auth/Login' import Logout from '../../containers/auth/Logout' import ProfileName from '../../containers/auth/ProfileName' import { login, navbar, opendcBrand } from './Navbar.module.scss' +import { useAuth } from '../../auth/hook' export const NAVBAR_HEIGHT = 60 @@ -24,32 +26,45 @@ const GitHubLink = () => ( className="ml-2 mr-3 text-dark" style={{ position: 'relative', top: 7 }} > - + ) export const NavItem = ({ route, children }) => { - const location = useLocation() - return {children} + const router = useRouter() + const handleClick = (e) => { + e.preventDefault() + router.push(route) + } + return ( + + {children} + + ) } export const LoggedInSection = () => { - const location = useLocation() + const router = useRouter() + const isLoggedIn = useAuth() return ( ) @@ -74,7 +89,7 @@ const Navbar = ({ fullWidth, children }) => { - + OpenDC diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js index b38fc183..28fd81e9 100644 --- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js +++ b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js @@ -1,5 +1,5 @@ import React from 'react' -import { Link } from 'react-router-dom' +import Link from 'next/link' import BlinkingCursor from './BlinkingCursor' import CodeBlock from './CodeBlock' import { terminalWindow, terminalHeader, terminalBody, segfault, subTitle, homeBtn } from './TerminalWindow.module.scss' @@ -23,8 +23,10 @@ const TerminalWindow = () => ( Got lost?
        - - GET ME BACK TO OPENDC + +
        + GET ME BACK TO OPENDC +
        diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js index 1c76cc7f..48cce019 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js +++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js @@ -1,11 +1,13 @@ import PropTypes from 'prop-types' import React from 'react' -import { Link } from 'react-router-dom' +import Link from 'next/link' const ProjectActionButtons = ({ projectId, onViewUsers, onDelete }) => ( - - + + + +
        { + useRequireAuth() + + const projectName = useSelector( + (state) => + state.currentProjectId !== '-1' && + state.objects.project[state.currentProjectId] && + state.objects.project[state.currentProjectId].name + ) + const topologyIsLoading = useSelector((state) => state.currentTopologyIdd === '-1') + + const dispatch = useDispatch() + useEffect(() => { + if (scenarioId) { + dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)) + } else if (portfolioId) { + dispatch(openPortfolioSucceeded(projectId, portfolioId)) + } else { + dispatch(openProjectSucceeded(projectId)) + } + }, [projectId, portfolioId, scenarioId, dispatch]) + + const constructionElements = topologyIsLoading ? ( +
        + +
        + ) : ( +
        + + + + + +
        + ) + + const portfolioElements = ( +
        + +
        + +
        +
        + ) + + const scenarioElements = ( +
        + +
        +

        Scenario loading

        +
        +
        + ) + + const title = projectName ? projectName + ' - OpenDC' : 'Simulation - OpenDC' + + return ( + + + {title} + + + {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} + + + + + + + + + + ) +} + +App.propTypes = { + projectId: PropTypes.string.isRequired, + portfolioId: PropTypes.string, + scenarioId: PropTypes.string, +} + +export default App diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js index 61d123e8..9394238d 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -4,11 +4,13 @@ import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } fro import MapStageComponent from '../../../components/app/map/MapStageComponent' const MapStage = () => { - const { position, dimensions } = useSelector((state) => state.map) + const position = useSelector((state) => state.map.position) + const dimensions = useSelector((state) => state.map.dimensions) const dispatch = useDispatch() const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height)) + return ( { }) const dispatch = useDispatch() - const history = useHistory() + const router = useRouter() const actions = { onNewPortfolio: () => { dispatch(openNewPortfolioModal()) @@ -37,7 +37,7 @@ const PortfolioListContainer = (props) => { const state = await getState(dispatch) dispatch(deletePortfolio(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - history.push(`/projects/${state.currentProjectId}`) + router.push(`/projects/${state.currentProjectId}`) } }, } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js index 35e6c52b..06c7f0f7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js @@ -1,11 +1,11 @@ import React from 'react' -import { useLocation } from 'react-router-dom' +import { useRouter } from 'next/router' import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' import { isCollapsible } from '../../../../util/sidebar-space' const ProjectSidebarContainer = (props) => { - const location = useLocation() - return + const router = useRouter() + return } export default ProjectSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 954284a6..e9c05f17 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -3,13 +3,13 @@ import { useDispatch, useSelector } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' import { setCurrentTopology } from '../../../../actions/topology/building' import { openNewTopologyModal } from '../../../../actions/modals/topology' -import { useHistory } from 'react-router-dom' +import { useRouter } from 'next/router' import { getState } from '../../../../util/state-utils' import { deleteTopology } from '../../../../actions/topologies' const TopologyListContainer = () => { const dispatch = useDispatch() - const history = useHistory() + const router = useRouter() const topologies = useSelector((state) => { let topologies = state.objects.project[state.currentProjectId] @@ -26,7 +26,7 @@ const TopologyListContainer = () => { const onChooseTopology = async (id) => { dispatch(setCurrentTopology(id)) const state = await getState(dispatch) - history.push(`/projects/${state.currentProjectId}`) + router.push(`/projects/${state.currentProjectId}`) } const onNewTopology = () => { dispatch(openNewTopologyModal()) @@ -36,7 +36,7 @@ const TopologyListContainer = () => { const state = await getState(dispatch) dispatch(deleteTopology(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - history.push(`/projects/${state.currentProjectId}`) + router.push(`/projects/${state.currentProjectId}`) } } diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js index f652429d..178f269e 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js @@ -3,7 +3,6 @@ import GoogleLogin from 'react-google-login' import { useDispatch } from 'react-redux' import { logIn } from '../../actions/auth' import { Button } from 'reactstrap' -import config from '../../config' function Login({ visible, className }) { const dispatch = useDispatch() @@ -30,12 +29,12 @@ function Login({ visible, className }) { return ( ( )} /> diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js deleted file mode 100644 index 93a38642..00000000 --- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { closeDeleteProfileModal } from '../../actions/modals/profile' -import { deleteCurrentUser } from '../../actions/users' -import ConfirmationModal from '../../components/modals/ConfirmationModal' - -const DeleteProfileModal = () => { - const visible = useSelector((state) => state.modals.deleteProfileModalVisible) - - const dispatch = useDispatch() - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteCurrentUser()) - } - dispatch(closeDeleteProfileModal()) - } - return ( - - ) -} - -export default DeleteProfileModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js index b588b4bc..18ad65f9 100644 --- a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js @@ -6,8 +6,6 @@ import { closeNewScenarioModal } from '../../actions/modals/scenarios' const NewScenarioModal = (props) => { const topologies = useSelector(({ currentProjectId, objects }) => { - console.log(currentProjectId, objects) - if (currentProjectId === '-1' || !objects.project[currentProjectId]) { return [] } diff --git a/opendc-web/opendc-web-ui/src/index.js b/opendc-web/opendc-web-ui/src/index.js deleted file mode 100644 index fdfec24b..00000000 --- a/opendc-web/opendc-web-ui/src/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import * as Sentry from '@sentry/react' -import { Integrations } from '@sentry/tracing' -import { Provider } from 'react-redux' -import './index.scss' -import Routes from './routes' -import config from './config' -import configureStore from './store/configure-store' - -const store = configureStore() - -// Initialize Sentry if the user has configured a DSN -const dsn = config['SENTRY_DSN'] -if (dsn) { - Sentry.init({ - environment: process.env.NODE_ENV, - dsn: dsn, - integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 0.1, - }) -} - -ReactDOM.render( - - - , - document.getElementById('root') -) diff --git a/opendc-web/opendc-web-ui/src/index.scss b/opendc-web/opendc-web-ui/src/index.scss index 0c1ddff4..1a4d1303 100644 --- a/opendc-web/opendc-web-ui/src/index.scss +++ b/opendc-web/opendc-web-ui/src/index.scss @@ -5,7 +5,7 @@ html, body, -#root { +#__next { margin: 0; padding: 0; width: 100%; diff --git a/opendc-web/opendc-web-ui/src/pages/404.js b/opendc-web/opendc-web-ui/src/pages/404.js new file mode 100644 index 00000000..cc9281fc --- /dev/null +++ b/opendc-web/opendc-web-ui/src/pages/404.js @@ -0,0 +1,19 @@ +import React from 'react' +import Head from 'next/head' +import TerminalWindow from '../components/not-found/TerminalWindow' +import style from './404.module.scss' + +const NotFound = () => { + return ( + <> + + Page Not Found - OpenDC + +
        + +
        + + ) +} + +export default NotFound diff --git a/opendc-web/opendc-web-ui/src/pages/404.module.scss b/opendc-web/opendc-web-ui/src/pages/404.module.scss new file mode 100644 index 00000000..e91c2780 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/pages/404.module.scss @@ -0,0 +1,8 @@ +.not-found-backdrop { + display: flex; + + width: 100%; + height: 100%; + + background-image: linear-gradient(135deg, #00678a, #008fbf, #00a6d6); +} diff --git a/opendc-web/opendc-web-ui/src/pages/App.js b/opendc-web/opendc-web-ui/src/pages/App.js deleted file mode 100644 index ea62e8dc..00000000 --- a/opendc-web/opendc-web-ui/src/pages/App.js +++ /dev/null @@ -1,103 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useEffect } from 'react' -import { HotKeys } from 'react-hotkeys' -import { useDispatch, useSelector } from 'react-redux' -import { openPortfolioSucceeded } from '../actions/portfolios' -import { openProjectSucceeded } from '../actions/projects' -import ToolPanelComponent from '../components/app/map/controls/ToolPanelComponent' -import LoadingScreen from '../components/app/map/LoadingScreen' -import ScaleIndicatorContainer from '../containers/app/map/controls/ScaleIndicatorContainer' -import MapStage from '../containers/app/map/MapStage' -import TopologySidebarContainer from '../containers/app/sidebars/topology/TopologySidebarContainer' -import DeleteMachineModal from '../containers/modals/DeleteMachineModal' -import DeleteRackModal from '../containers/modals/DeleteRackModal' -import DeleteRoomModal from '../containers/modals/DeleteRoomModal' -import EditRackNameModal from '../containers/modals/EditRackNameModal' -import EditRoomNameModal from '../containers/modals/EditRoomNameModal' -import NewTopologyModal from '../containers/modals/NewTopologyModal' -import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' -import ProjectSidebarContainer from '../containers/app/sidebars/project/ProjectSidebarContainer' -import { openScenarioSucceeded } from '../actions/scenarios' -import NewPortfolioModal from '../containers/modals/NewPortfolioModal' -import NewScenarioModal from '../containers/modals/NewScenarioModal' -import PortfolioResultsContainer from '../containers/app/results/PortfolioResultsContainer' -import KeymapConfiguration from '../shortcuts/keymap' -import { useDocumentTitle } from '../util/hooks' - -const App = ({ projectId, portfolioId, scenarioId }) => { - const projectName = useSelector( - (state) => - state.currentProjectId !== '-1' && - state.objects.project[state.currentProjectId] && - state.objects.project[state.currentProjectId].name - ) - const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') - - const dispatch = useDispatch() - useEffect(() => { - if (scenarioId) { - dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)) - } else if (portfolioId) { - dispatch(openPortfolioSucceeded(projectId, portfolioId)) - } else { - dispatch(openProjectSucceeded(projectId)) - } - }, [projectId, portfolioId, scenarioId, dispatch]) - - const constructionElements = topologyIsLoading ? ( -
        - -
        - ) : ( -
        - - - - - -
        - ) - - const portfolioElements = ( -
        - -
        - -
        -
        - ) - - const scenarioElements = ( -
        - -
        -

        Scenario loading

        -
        -
        - ) - - useDocumentTitle(projectName ? projectName + ' - OpenDC' : 'Simulation - OpenDC') - - return ( - - - {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} - - - - - - - - - - ) -} - -App.propTypes = { - projectId: PropTypes.string.isRequired, - portfolioId: PropTypes.string, - scenarioId: PropTypes.string, -} - -export default App diff --git a/opendc-web/opendc-web-ui/src/pages/Home.js b/opendc-web/opendc-web-ui/src/pages/Home.js deleted file mode 100644 index ee930fbe..00000000 --- a/opendc-web/opendc-web-ui/src/pages/Home.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' -import ContactSection from '../components/home/ContactSection' -import IntroSection from '../components/home/IntroSection' -import JumbotronHeader from '../components/home/JumbotronHeader' -import ModelingSection from '../components/home/ModelingSection' -import SimulationSection from '../components/home/SimulationSection' -import StakeholderSection from '../components/home/StakeholderSection' -import TeamSection from '../components/home/TeamSection' -import TechnologiesSection from '../components/home/TechnologiesSection' -import HomeNavbar from '../components/navigation/HomeNavbar' -import { - introSection, - stakeholderSection, - modelingSection, - simulationSection, - technologiesSection, - teamSection, -} from './Home.module.scss' -import { useDocumentTitle } from '../util/hooks' - -function Home() { - useDocumentTitle('OpenDC') - return ( -
        - -
        - - - - - - - - -
        -
        - ) -} - -export default Home diff --git a/opendc-web/opendc-web-ui/src/pages/Home.module.scss b/opendc-web/opendc-web-ui/src/pages/Home.module.scss deleted file mode 100644 index aed1d88f..00000000 --- a/opendc-web/opendc-web-ui/src/pages/Home.module.scss +++ /dev/null @@ -1,16 +0,0 @@ -.bodyWrapper { - position: relative; - overflow-y: hidden; -} - -.introSection, -.modelingSection, -.technologiesSection { - background-color: #fff; -} - -.stakeholderSection, -.simulationSection, -.teamSection { - background-color: #f2f2f2; -} diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.js b/opendc-web/opendc-web-ui/src/pages/NotFound.js deleted file mode 100644 index 409ffa0e..00000000 --- a/opendc-web/opendc-web-ui/src/pages/NotFound.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import TerminalWindow from '../components/not-found/TerminalWindow' -import style from './NotFound.module.scss' -import { useDocumentTitle } from '../util/hooks' - -const NotFound = () => { - useDocumentTitle('Page Not Found - OpenDC') - return ( -
        - -
        - ) -} - -export default NotFound diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.module.scss b/opendc-web/opendc-web-ui/src/pages/NotFound.module.scss deleted file mode 100644 index e91c2780..00000000 --- a/opendc-web/opendc-web-ui/src/pages/NotFound.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.not-found-backdrop { - display: flex; - - width: 100%; - height: 100%; - - background-image: linear-gradient(135deg, #00678a, #008fbf, #00a6d6); -} diff --git a/opendc-web/opendc-web-ui/src/pages/Profile.js b/opendc-web/opendc-web-ui/src/pages/Profile.js deleted file mode 100644 index ea781686..00000000 --- a/opendc-web/opendc-web-ui/src/pages/Profile.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { openDeleteProfileModal } from '../actions/modals/profile' -import DeleteProfileModal from '../containers/modals/DeleteProfileModal' -import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' -import { useDocumentTitle } from '../util/hooks' - -const Profile = () => { - const dispatch = useDispatch() - const onDelete = () => dispatch(openDeleteProfileModal()) - - useDocumentTitle('My Profile - OpenDC') - return ( -
        - -
        - -

        - This does not delete your Google account, but simply disconnects it from the OpenDC platform and - deletes any project info that is associated with you (projects you own and any authorizations you - may have on other projects). -

        -
        - -
        - ) -} - -export default Profile diff --git a/opendc-web/opendc-web-ui/src/pages/Projects.js b/opendc-web/opendc-web-ui/src/pages/Projects.js deleted file mode 100644 index 5e642a03..00000000 --- a/opendc-web/opendc-web-ui/src/pages/Projects.js +++ /dev/null @@ -1,30 +0,0 @@ -import React, { useEffect } from 'react' -import { useDispatch } from 'react-redux' -import { fetchAuthorizationsOfCurrentUser } from '../actions/users' -import ProjectFilterPanel from '../components/projects/FilterPanel' -import NewProjectModal from '../containers/modals/NewProjectModal' -import NewProjectButtonContainer from '../containers/projects/NewProjectButtonContainer' -import VisibleProjectList from '../containers/projects/VisibleProjectAuthList' -import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' -import { useDocumentTitle } from '../util/hooks' - -function Projects() { - const dispatch = useDispatch() - - useEffect(() => dispatch(fetchAuthorizationsOfCurrentUser())) - useDocumentTitle('My Projects - OpenDC') - - return ( -
        - -
        - - - -
        - -
        - ) -} - -export default Projects diff --git a/opendc-web/opendc-web-ui/src/pages/_app.js b/opendc-web/opendc-web-ui/src/pages/_app.js new file mode 100644 index 00000000..77ffa698 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/pages/_app.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import Head from 'next/head' +import { Provider } from 'react-redux' +import { useStore } from '../store/configure-store' +import '../index.scss' + +export default function App({ Component, pageProps }) { + const store = useStore(pageProps.initialReduxState) + + return ( + <> + + + + + + + + + ) +} diff --git a/opendc-web/opendc-web-ui/src/pages/_document.js b/opendc-web/opendc-web-ui/src/pages/_document.js new file mode 100644 index 00000000..943ae395 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/pages/_document.js @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import Document, { Html, Head, Main, NextScript } from 'next/document' + +class OpenDCDocument extends Document { + render() { + return ( + + + + + + + + + + + {/* Twitter Card data */} + + + + + + + + {/* OpenGraph meta tags */} + + + + + + + + + {/* CDN Dependencies */} + + - - - - - -
        -Sign out - -

        Your auth token:

        -

        Loading...

        \ No newline at end of file -- cgit v1.2.3 From 0c6ccca5fac44ab40671627fd3181e9b138672fa Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 May 2021 15:17:49 +0200 Subject: api: Migrate to Auth0 for API authorization This change updates the OpenDC API to use Auth0 for API authorization. This removes the hard dependency on Google for logging into OpenDC and simplifies implementation as we do not have to store user information anymore, other than the user identifier. --- opendc-web/opendc-web-api/README.md | 8 +- opendc-web/opendc-web-api/app.py | 47 +--- opendc-web/opendc-web-api/conftest.py | 18 +- .../api/v2/portfolios/portfolioId/endpoint.py | 6 +- .../portfolios/portfolioId/scenarios/endpoint.py | 4 +- .../api/v2/prefabs/authorizations/endpoint.py | 2 +- .../opendc/api/v2/prefabs/endpoint.py | 2 +- .../opendc/api/v2/prefabs/prefabId/endpoint.py | 6 +- .../opendc/api/v2/projects/endpoint.py | 2 +- .../projects/projectId/authorizations/endpoint.py | 2 +- .../opendc/api/v2/projects/projectId/endpoint.py | 8 +- .../v2/projects/projectId/portfolios/endpoint.py | 2 +- .../v2/projects/projectId/topologies/endpoint.py | 2 +- .../opendc/api/v2/scenarios/scenarioId/endpoint.py | 6 +- .../api/v2/topologies/topologyId/endpoint.py | 6 +- .../opendc-web-api/opendc/api/v2/users/endpoint.py | 2 +- .../opendc/api/v2/users/userId/endpoint.py | 4 +- opendc-web/opendc-web-api/opendc/util/auth.py | 253 +++++++++++++++++++++ opendc-web/opendc-web-api/opendc/util/rest.py | 36 +-- opendc-web/opendc-web-api/requirements.txt | 1 + 20 files changed, 314 insertions(+), 103 deletions(-) create mode 100644 opendc-web/opendc-web-api/opendc/util/auth.py diff --git a/opendc-web/opendc-web-api/README.md b/opendc-web/opendc-web-api/README.md index e1d83daf..af3cf927 100644 --- a/opendc-web/opendc-web-api/README.md +++ b/opendc-web/opendc-web-api/README.md @@ -33,8 +33,8 @@ The `Util` package handles several miscellaneous tasks: database. * `Exceptions`: Holds definitions for exceptions used throughout the web server. * `Parameter Checker`: Recursively checks whether required `Request` parameters are present and correctly typed. -* `REST`: Parses HTTP messages into `Request` objects, and calls the appropriate `API` endpoint to get - a `Response` object to return to the `Main Server Loop`. +* `REST`: Parses HTTP messages into `Request` objects, and calls the appropriate `API` endpoint to get a `Response` + object to return to the `Main Server Loop`. ### API Package @@ -80,8 +80,8 @@ repository. #### Get and configure the code -Clone OpenDC and follow the [instructions in the main repository](../../) to set up a Google OAuth ID and environment -variables. +Clone OpenDC and follow the [instructions in the main repository](../../) to set up an [Auth0](https://auth0.com) +application and environment variables. **Important:** Be sure to set up environment variables according to those instructions, in a `.env` file. diff --git a/opendc-web/opendc-web-api/app.py b/opendc-web/opendc-web-api/app.py index 7a687678..ee4b3d32 100755 --- a/opendc-web/opendc-web-api/app.py +++ b/opendc-web/opendc-web-api/app.py @@ -3,16 +3,14 @@ import json import os import sys import traceback -import urllib.request from dotenv import load_dotenv from flask import Flask, request, jsonify from flask_compress import Compress from flask_cors import CORS -from oauth2client import client, crypt -from opendc.models.user import User from opendc.util import rest, path_parser, database +from opendc.util.auth import AuthError, AuthManager, AsymmetricJwtAlgorithm from opendc.util.exceptions import AuthorizationTokenError, RequestInitializationError from opendc.util.json import JSONEncoder @@ -50,46 +48,21 @@ CORS(app) compress = Compress() compress.init_app(app) -API_VERSIONS = {'v2'} - - -@app.route('/tokensignin', methods=['POST']) -def sign_in(): - """Authenticate a user with Google sign in""" +auth = AuthManager(AsymmetricJwtAlgorithm(jwks_url=f"https://{os.environ['AUTH0_DOMAIN']}/.well-known/jwks.json"), + issuer=f"https://{os.environ['AUTH0_DOMAIN']}/", audience=os.environ['AUTH0_AUDIENCE']) - try: - token = request.form['idtoken'] - except KeyError: - return 'No idtoken provided', 401 - - try: - idinfo = client.verify_id_token(token, os.environ['OPENDC_OAUTH_CLIENT_ID']) - - if idinfo['aud'] != os.environ['OPENDC_OAUTH_CLIENT_ID']: - raise crypt.AppIdentityError('Unrecognized client.') - - if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: - raise crypt.AppIdentityError('Wrong issuer.') - except ValueError: - url = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={}".format(token) - req = urllib.request.Request(url) - response = urllib.request.urlopen(url=req, timeout=30) - res = response.read() - idinfo = json.loads(res) - except crypt.AppIdentityError as e: - return 'Did not successfully authenticate' - - user = User.from_google_id(idinfo['sub']) - - data = {'isNewUser': user.obj is None} +API_VERSIONS = {'v2'} - if user.obj is not None: - data['userId'] = user.get_id() - return jsonify(**data) +@app.errorhandler(AuthError) +def handle_auth_error(ex): + response = jsonify(ex.error) + response.status_code = ex.status_code + return response @app.route('//', methods=['GET', 'POST', 'PUT', 'DELETE']) +@auth.require def api_call(version, endpoint_path): """Call an API endpoint directly over HTTP.""" diff --git a/opendc-web/opendc-web-api/conftest.py b/opendc-web/opendc-web-api/conftest.py index 8bb55ccc..c502c078 100644 --- a/opendc-web/opendc-web-api/conftest.py +++ b/opendc-web/opendc-web-api/conftest.py @@ -1,14 +1,30 @@ """ Configuration file for all unit tests. """ + +from functools import wraps import pytest +from flask import _request_ctx_stack + -from app import app +def decorator(self, f): + @wraps(f) + def decorated_function(*args, **kwargs): + _request_ctx_stack.top.current_user = {'sub': 'test'} + return f(*args, **kwargs) + return decorated_function @pytest.fixture def client(): """Returns a Flask API client to interact with.""" + + # Disable authorization for test API endpoints + from opendc.util.auth import AuthManager + AuthManager.require = decorator + + from app import app + app.config['TESTING'] = True with app.test_client() as client: diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py index 0ba61a13..c856f4ce 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py @@ -11,7 +11,7 @@ def GET(request): portfolio = Portfolio.from_id(request.params_path['portfolioId']) portfolio.check_exists() - portfolio.check_user_access(request.google_id, False) + portfolio.check_user_access(request.current_user['sub'], False) return Response(200, 'Successfully retrieved portfolio.', portfolio.obj) @@ -30,7 +30,7 @@ def PUT(request): portfolio = Portfolio.from_id(request.params_path['portfolioId']) portfolio.check_exists() - portfolio.check_user_access(request.google_id, True) + portfolio.check_user_access(request.current_user['sub'], True) portfolio.set_property('name', request.params_body['portfolio']['name']) @@ -52,7 +52,7 @@ def DELETE(request): portfolio = Portfolio.from_id(request.params_path['portfolioId']) portfolio.check_exists() - portfolio.check_user_access(request.google_id, True) + portfolio.check_user_access(request.current_user['sub'], True) portfolio_id = portfolio.get_id() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py index 2f042e06..b12afce3 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py @@ -29,13 +29,13 @@ def POST(request): portfolio = Portfolio.from_id(request.params_path['portfolioId']) portfolio.check_exists() - portfolio.check_user_access(request.google_id, True) + portfolio.check_user_access(request.current_user['sub'], True) scenario = Scenario(request.params_body['scenario']) topology = Topology.from_id(scenario.obj['topology']['topologyId']) topology.check_exists() - topology.check_user_access(request.google_id, True) + topology.check_user_access(request.current_user['sub'], True) scenario.set_property('portfolioId', portfolio.get_id()) scenario.set_property('simulation', {'state': 'QUEUED'}) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py index 0d9ad5cd..0de50851 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py @@ -7,7 +7,7 @@ from opendc.util.rest import Response def GET(request): """Return all prefabs the user is authorized to access""" - user = User.from_google_id(request.google_id) + user = User.from_google_id(request.current_user['sub']) user.check_exists() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py index 723a2f0d..e77c7150 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py @@ -15,7 +15,7 @@ def POST(request): prefab.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) prefab.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) - user = User.from_google_id(request.google_id) + user = User.from_google_id(request.current_user['sub']) prefab.set_property('authorId', user.get_id()) prefab.insert() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py index 7b81f546..f1cf1fcd 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py @@ -12,7 +12,7 @@ def GET(request): prefab = Prefab.from_id(request.params_path['prefabId']) prefab.check_exists() - prefab.check_user_access(request.google_id) + prefab.check_user_access(request.current_user['sub']) return Response(200, 'Successfully retrieved prefab', prefab.obj) @@ -25,7 +25,7 @@ def PUT(request): prefab = Prefab.from_id(request.params_path['prefabId']) prefab.check_exists() - prefab.check_user_access(request.google_id) + prefab.check_user_access(request.current_user['sub']) prefab.set_property('name', request.params_body['prefab']['name']) prefab.set_property('rack', request.params_body['prefab']['rack']) @@ -43,7 +43,7 @@ def DELETE(request): prefab = Prefab.from_id(request.params_path['prefabId']) prefab.check_exists() - prefab.check_user_access(request.google_id) + prefab.check_user_access(request.current_user['sub']) old_object = prefab.delete() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py index bf031382..dacbe6a4 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py @@ -25,7 +25,7 @@ def POST(request): topology.set_property('projectId', project.get_id()) topology.update() - user = User.from_google_id(request.google_id) + user = User.from_google_id(request.current_user['sub']) user.obj['authorizations'].append({'projectId': project.get_id(), 'authorizationLevel': 'OWN'}) user.update() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py index 9f6a60ec..1b229122 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py @@ -10,7 +10,7 @@ def GET(request): project = Project.from_id(request.params_path['projectId']) project.check_exists() - project.check_user_access(request.google_id, False) + project.check_user_access(request.current_user['sub'], False) authorizations = project.get_all_authorizations() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py index caac37ca..37cf1860 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py @@ -16,7 +16,7 @@ def GET(request): project = Project.from_id(request.params_path['projectId']) project.check_exists() - project.check_user_access(request.google_id, False) + project.check_user_access(request.current_user['sub'], False) return Response(200, 'Successfully retrieved project', project.obj) @@ -29,7 +29,7 @@ def PUT(request): project = Project.from_id(request.params_path['projectId']) project.check_exists() - project.check_user_access(request.google_id, True) + project.check_user_access(request.current_user['sub'], True) project.set_property('name', request.params_body['project']['name']) project.set_property('datetime_last_edited', Database.datetime_to_string(datetime.now())) @@ -46,7 +46,7 @@ def DELETE(request): project = Project.from_id(request.params_path['projectId']) project.check_exists() - project.check_user_access(request.google_id, True) + project.check_user_access(request.current_user['sub'], True) for topology_id in project.obj['topologyIds']: topology = Topology.from_id(topology_id) @@ -56,7 +56,7 @@ def DELETE(request): portfolio = Portfolio.from_id(portfolio_id) portfolio.delete() - user = User.from_google_id(request.google_id) + user = User.from_google_id(request.current_user['sub']) user.obj['authorizations'] = list( filter(lambda x: x['projectId'] != project.get_id(), user.obj['authorizations'])) user.update() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py index 2cdb1194..18b4d007 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py @@ -20,7 +20,7 @@ def POST(request): project = Project.from_id(request.params_path['projectId']) project.check_exists() - project.check_user_access(request.google_id, True) + project.check_user_access(request.current_user['sub'], True) portfolio = Portfolio(request.params_body['portfolio']) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py index 44a0d575..47f2a207 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py @@ -14,7 +14,7 @@ def POST(request): project = Project.from_id(request.params_path['projectId']) project.check_exists() - project.check_user_access(request.google_id, True) + project.check_user_access(request.current_user['sub'], True) topology = Topology({ 'projectId': project.get_id(), diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py index 88a74e9c..7399f98c 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py @@ -11,7 +11,7 @@ def GET(request): scenario = Scenario.from_id(request.params_path['scenarioId']) scenario.check_exists() - scenario.check_user_access(request.google_id, False) + scenario.check_user_access(request.current_user['sub'], False) return Response(200, 'Successfully retrieved scenario.', scenario.obj) @@ -26,7 +26,7 @@ def PUT(request): scenario = Scenario.from_id(request.params_path['scenarioId']) scenario.check_exists() - scenario.check_user_access(request.google_id, True) + scenario.check_user_access(request.current_user['sub'], True) scenario.set_property('name', request.params_body['scenario']['name']) @@ -44,7 +44,7 @@ def DELETE(request): scenario = Scenario.from_id(request.params_path['scenarioId']) scenario.check_exists() - scenario.check_user_access(request.google_id, True) + scenario.check_user_access(request.current_user['sub'], True) scenario_id = scenario.get_id() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py index ea82b2e2..80618190 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py @@ -14,7 +14,7 @@ def GET(request): topology = Topology.from_id(request.params_path['topologyId']) topology.check_exists() - topology.check_user_access(request.google_id, False) + topology.check_user_access(request.current_user['sub'], False) return Response(200, 'Successfully retrieved topology.', topology.obj) @@ -25,7 +25,7 @@ def PUT(request): topology = Topology.from_id(request.params_path['topologyId']) topology.check_exists() - topology.check_user_access(request.google_id, True) + topology.check_user_access(request.current_user['sub'], True) topology.set_property('name', request.params_body['topology']['name']) topology.set_property('rooms', request.params_body['topology']['rooms']) @@ -43,7 +43,7 @@ def DELETE(request): topology = Topology.from_id(request.params_path['topologyId']) topology.check_exists() - topology.check_user_access(request.google_id, True) + topology.check_user_access(request.current_user['sub'], True) topology_id = topology.get_id() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py index 0dcf2463..fe61ce25 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py @@ -20,7 +20,7 @@ def POST(request): request.check_required_parameters(body={'user': {'email': 'string'}}) user = User(request.params_body['user']) - user.set_property('googleId', request.google_id) + user.set_property('googleId', request.current_user['sub']) user.set_property('authorizations', []) user.check_already_exists() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py index be3462c0..26ff7717 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py @@ -27,7 +27,7 @@ def PUT(request): user = User.from_id(request.params_path['userId']) user.check_exists() - user.check_correct_user(request.google_id) + user.check_correct_user(request.current_user['sub']) user.set_property('givenName', request.params_body['user']['givenName']) user.set_property('familyName', request.params_body['user']['familyName']) @@ -45,7 +45,7 @@ def DELETE(request): user = User.from_id(request.params_path['userId']) user.check_exists() - user.check_correct_user(request.google_id) + user.check_correct_user(request.current_user['sub']) for authorization in user.obj['authorizations']: if authorization['authorizationLevel'] != 'OWN': diff --git a/opendc-web/opendc-web-api/opendc/util/auth.py b/opendc-web/opendc-web-api/opendc/util/auth.py new file mode 100644 index 00000000..810b582a --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/util/auth.py @@ -0,0 +1,253 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +import json +import time +from functools import wraps + +import urllib3 +from flask import request, _request_ctx_stack +from jose import jwt, JWTError +from werkzeug.local import LocalProxy + +current_user = LocalProxy(lambda: getattr(_request_ctx_stack.top, 'current_user', None)) + + +class AuthError(Exception): + """ + This error is thrown when the request failed to authorize. + """ + + def __init__(self, error, status_code): + Exception.__init__(self, error) + self.error = error + self.status_code = status_code + + +class AuthManager: + """ + This class handles the authorization of requests. + """ + + def __init__(self, alg, issuer, audience): + self._alg = alg + self._issuer = issuer + self._audience = audience + + def require(self, f): + """Determines if the Access Token is valid + """ + + @wraps(f) + def decorated(*args, **kwargs): + token = _get_token() + try: + header = jwt.get_unverified_header(token) + except JWTError as e: + raise AuthError({"code": "invalid_token", + "description": str(e)}, 401) + + alg = header.get('alg', None) + if alg != self._alg.algorithm: + raise AuthError({"code": "invalid_header", + "description": f"Signature algorithm of {alg} is not supported. Expected the ID token " + f"to be signed with {self._alg.algorithm}"}, 401) + + kid = header.get('kid', None) + try: + secret_or_certificate = self._alg.get_key(key_id=kid) + except TokenValidationError as e: + raise AuthError({"code": "invalid_header", + "description": str(e)}, 401) + try: + payload = jwt.decode(token, + key=secret_or_certificate, + algorithms=[self._alg.algorithm], + audience=self._audience, + issuer=self._issuer) + _request_ctx_stack.top.current_user = payload + return f(*args, **kwargs) + except jwt.ExpiredSignatureError: + raise AuthError({"code": "token_expired", + "description": "token is expired"}, 401) + except jwt.JWTClaimsError: + raise AuthError({"code": "invalid_claims", + "description": + "incorrect claims," + "please check the audience and issuer"}, 401) + except Exception as e: + print(e) + raise AuthError({"code": "invalid_header", + "description": + "Unable to parse authentication" + " token."}, 401) + + return decorated + + +def _get_token(): + """ + Obtain the Access Token from the Authorization Header + """ + auth = request.headers.get("Authorization", None) + if not auth: + raise AuthError({"code": "authorization_header_missing", + "description": + "Authorization header is expected"}, 401) + + parts = auth.split() + + if parts[0].lower() != "bearer": + raise AuthError({"code": "invalid_header", + "description": + "Authorization header must start with" + " Bearer"}, 401) + if len(parts) == 1: + raise AuthError({"code": "invalid_header", + "description": "Token not found"}, 401) + if len(parts) > 2: + raise AuthError({"code": "invalid_header", + "description": + "Authorization header must be" + " Bearer token"}, 401) + + token = parts[1] + return token + + +class SymmetricJwtAlgorithm: + """Verifier for HMAC signatures, which rely on shared secrets. + Args: + shared_secret (str): The shared secret used to decode the token. + algorithm (str, optional): The expected signing algorithm. Defaults to "HS256". + """ + + def __init__(self, shared_secret, algorithm="HS256"): + self.algorithm = algorithm + self._shared_secret = shared_secret + + # pylint: disable=W0613 + def get_key(self, key_id=None): + """ + Obtain the key for this algorithm. + :param key_id: The identifier of the key. + :return: The JWK key. + """ + return self._shared_secret + + +class AsymmetricJwtAlgorithm: + """Verifier for RSA signatures, which rely on public key certificates. + Args: + jwks_url (str): The url where the JWK set is located. + algorithm (str, optional): The expected signing algorithm. Defaults to "RS256". + """ + + def __init__(self, jwks_url, algorithm="RS256"): + self.algorithm = algorithm + self._fetcher = JwksFetcher(jwks_url) + + def get_key(self, key_id=None): + """ + Obtain the key for this algorithm. + :param key_id: The identifier of the key. + :return: The JWK key. + """ + return self._fetcher.get_key(key_id) + + +class TokenValidationError(Exception): + """ + Error thrown when the token cannot be validated + """ + + +class JwksFetcher: + """Class that fetches and holds a JSON web key set. + This class makes use of an in-memory cache. For it to work properly, define this instance once and re-use it. + Args: + jwks_url (str): The url where the JWK set is located. + cache_ttl (str, optional): The lifetime of the JWK set cache in seconds. Defaults to 600 seconds. + """ + CACHE_TTL = 600 # 10 min cache lifetime + + def __init__(self, jwks_url, cache_ttl=CACHE_TTL): + self._jwks_url = jwks_url + self._http = urllib3.PoolManager() + self._cache_value = {} + self._cache_date = 0 + self._cache_ttl = cache_ttl + self._cache_is_fresh = False + + def _fetch_jwks(self, force=False): + """Attempts to obtain the JWK set from the cache, as long as it's still valid. + When not, it will perform a network request to the jwks_url to obtain a fresh result + and update the cache value with it. + Args: + force (bool, optional): whether to ignore the cache and force a network request or not. Defaults to False. + """ + has_expired = self._cache_date + self._cache_ttl < time.time() + + if not force and not has_expired: + # Return from cache + self._cache_is_fresh = False + return self._cache_value + + # Invalidate cache and fetch fresh data + self._cache_value = {} + response = self._http.request('GET', self._jwks_url) + + if response.status == 200: + # Update cache + jwks = json.loads(response.data.decode('utf-8')) + self._cache_value = self._parse_jwks(jwks) + self._cache_is_fresh = True + self._cache_date = time.time() + return self._cache_value + + @staticmethod + def _parse_jwks(jwks): + """Converts a JWK string representation into a binary certificate in PEM format. + """ + keys = {} + + for key in jwks['keys']: + keys[key["kid"]] = key + return keys + + def get_key(self, key_id): + """Obtains the JWK associated with the given key id. + Args: + key_id (str): The id of the key to fetch. + Returns: + the JWK associated with the given key id. + + Raises: + TokenValidationError: when a key with that id cannot be found + """ + keys = self._fetch_jwks() + + if keys and key_id in keys: + return keys[key_id] + + if not self._cache_is_fresh: + keys = self._fetch_jwks(force=True) + if keys and key_id in keys: + return keys[key_id] + raise TokenValidationError(f"RSA Public Key with ID {key_id} was not found.") diff --git a/opendc-web/opendc-web-api/opendc/util/rest.py b/opendc-web/opendc-web-api/opendc/util/rest.py index c9e98295..63d063b3 100644 --- a/opendc-web/opendc-web-api/opendc/util/rest.py +++ b/opendc-web/opendc-web-api/opendc/util/rest.py @@ -1,11 +1,9 @@ import importlib import json -import os - -from oauth2client import client, crypt from opendc.util import exceptions, parameter_checker from opendc.util.exceptions import ClientError +from opendc.util.auth import current_user class Request: @@ -57,16 +55,7 @@ class Request: raise exceptions.UnsupportedMethodError('Unimplemented method at endpoint {}: {}'.format( self.path, self.method)) - # Verify the user - - if "OPENDC_FLASK_TESTING" in os.environ: - self.google_id = 'test' - return - - try: - self.google_id = self._verify_token(self.token) - except crypt.AppIdentityError as e: - raise exceptions.AuthorizationTokenError(e) + self.current_user = current_user def check_required_parameters(self, **kwargs): """Raise an error if a parameter is missing or of the wrong type.""" @@ -99,27 +88,6 @@ class Request: return json.dumps(self.message) - @staticmethod - def _verify_token(token): - """Return the ID of the signed-in user. - - Or throw an Exception if the token is invalid. - """ - - try: - id_info = client.verify_id_token(token, os.environ['OPENDC_OAUTH_CLIENT_ID']) - except Exception as e: - print(e) - raise crypt.AppIdentityError('Exception caught trying to verify ID token: {}'.format(e)) - - if id_info['aud'] != os.environ['OPENDC_OAUTH_CLIENT_ID']: - raise crypt.AppIdentityError('Unrecognized client.') - - if id_info['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: - raise crypt.AppIdentityError('Wrong issuer.') - - return id_info['sub'] - class Response: """Response to websocket mapping""" diff --git a/opendc-web/opendc-web-api/requirements.txt b/opendc-web/opendc-web-api/requirements.txt index 555ba751..a518da47 100644 --- a/opendc-web/opendc-web-api/requirements.txt +++ b/opendc-web/opendc-web-api/requirements.txt @@ -33,6 +33,7 @@ pytest-cov==2.11.1 pytest-env==0.6.2 pytest-mock==3.2.0 python-dotenv==0.14.0 +python-jose==3.2.0 rsa==4.7 sentry-sdk==0.19.2 six==1.15.0 -- cgit v1.2.3 From 05d2318538eba71ac0555dc5ec146499d9cb0592 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 May 2021 16:50:23 +0200 Subject: api: Remove user handling from OpenDC API server This change removes any of the user handling and endpoints from the OpenDC API server. The API server does not need to store user information other than an identifier in the database. --- database/mongo-init-opendc-db.sh | 2 +- opendc-api-spec.yml | 178 +-------------------- .../portfolioId/scenarios/test_endpoint.py | 4 +- .../api/v2/portfolios/portfolioId/test_endpoint.py | 15 +- .../api/v2/prefabs/authorizations/endpoint.py | 7 +- .../opendc/api/v2/prefabs/endpoint.py | 5 +- .../api/v2/prefabs/prefabId/test_endpoint.py | 6 +- .../opendc/api/v2/projects/endpoint.py | 14 +- .../projects/projectId/authorizations/__init__.py | 0 .../projects/projectId/authorizations/endpoint.py | 17 -- .../projectId/authorizations/test_endpoint.py | 43 ----- .../opendc/api/v2/projects/projectId/endpoint.py | 6 - .../projects/projectId/portfolios/test_endpoint.py | 4 +- .../api/v2/projects/projectId/test_endpoint.py | 15 +- .../projects/projectId/topologies/test_endpoint.py | 4 +- .../opendc/api/v2/projects/test_endpoint.py | 7 + .../api/v2/scenarios/scenarioId/test_endpoint.py | 90 ++++------- .../api/v2/topologies/topologyId/test_endpoint.py | 16 +- .../opendc-web-api/opendc/api/v2/users/__init__.py | 0 .../opendc-web-api/opendc/api/v2/users/endpoint.py | 30 ---- .../opendc/api/v2/users/test_endpoint.py | 34 ---- .../opendc/api/v2/users/userId/__init__.py | 0 .../opendc/api/v2/users/userId/endpoint.py | 59 ------- .../opendc/api/v2/users/userId/test_endpoint.py | 56 ------- .../opendc-web-api/opendc/models/portfolio.py | 17 +- opendc-web/opendc-web-api/opendc/models/prefab.py | 19 +-- opendc-web/opendc-web-api/opendc/models/project.py | 29 ++-- .../opendc-web-api/opendc/models/scenario.py | 16 +- .../opendc-web-api/opendc/models/topology.py | 20 +-- opendc-web/opendc-web-api/opendc/models/user.py | 36 ----- 30 files changed, 116 insertions(+), 633 deletions(-) delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/models/user.py diff --git a/database/mongo-init-opendc-db.sh b/database/mongo-init-opendc-db.sh index bd07f5ad..d55b8990 100644 --- a/database/mongo-init-opendc-db.sh +++ b/database/mongo-init-opendc-db.sh @@ -13,7 +13,7 @@ MONGO_CMD="mongo $OPENDC_DB -u $OPENDC_DB_USERNAME -p $OPENDC_DB_PASSWORD --auth echo 'Creating collections' -$MONGO_CMD --eval 'db.createCollection("users");' +$MONGO_CMD --eval 'db.createCollection("authorizations");' $MONGO_CMD --eval 'db.createCollection("projects");' $MONGO_CMD --eval 'db.createCollection("topologies");' $MONGO_CMD --eval 'db.createCollection("portfolios");' diff --git a/opendc-api-spec.yml b/opendc-api-spec.yml index f195983b..1f7c5697 100644 --- a/opendc-api-spec.yml +++ b/opendc-api-spec.yml @@ -9,129 +9,20 @@ schemes: - https paths: - '/users': - get: - tags: - - users - description: Search for a User using their email address. - parameters: - - name: email - in: query - description: User's email address. - required: true - type: string - responses: - '200': - description: Successfully searched Users. - schema: - $ref: '#/definitions/User' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '404': - description: User not found. - post: - tags: - - users - description: Add a new User. - parameters: - - name: user - in: body - description: The new User. - required: true - schema: - $ref: '#/definitions/User' - responses: - '200': - description: Successfully added User. - schema: - $ref: '#/definitions/User' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '409': - description: User already exists. - '/users/{userId}': + '/projects': get: tags: - - users - description: Get this User. - parameters: - - name: userId - in: path - description: User's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved User. - schema: - $ref: '#/definitions/User' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '404': - description: User not found. - put: - tags: - - users - description: Update this User's given name and/ or family name. - parameters: - - name: userId - in: path - description: User's ID. - required: true - type: string - - name: user - in: body - description: User's new properties. - required: true - schema: - properties: - givenName: - type: string - familyName: - type: string - responses: - '200': - description: Successfully updated User. - schema: - $ref: '#/definitions/User' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from updating User. - '404': - description: User not found. - delete: - tags: - - users - description: Delete this User. - parameters: - - name: userId - in: path - description: User's ID. - required: true - type: string + - projects + description: List Projects of the active user responses: '200': - description: Successfully deleted User. + description: Successfully schema: - $ref: '#/definitions/User' - '400': - description: Missing or incorrectly typed parameter. + type: array + items: + $ref: '#/definitions/Project' '401': description: Unauthorized. - '403': - description: Forbidden from deleting User. - '404': - description: User not found. - '/projects': post: tags: - projects @@ -232,39 +123,6 @@ paths: description: Forbidden from deleting Project. '404': description: Project not found. - '/projects/{projectId}/authorizations': - get: - tags: - - projects - description: Get this Project's Authorizations. - parameters: - - name: projectId - in: path - description: Project's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Project's Authorizations. - schema: - type: array - items: - type: object - properties: - userId: - type: string - projectId: - type: string - authorizationLevel: - type: string - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from retrieving this Project's Authorizations. - '404': - description: Project not found. '/projects/{projectId}/topologies': post: tags: @@ -900,28 +758,6 @@ definitions: type: string type: type: string - User: - type: object - properties: - _id: - type: string - googleId: - type: integer - email: - type: string - givenName: - type: string - familyName: - type: string - authorizations: - type: array - items: - type: object - properties: - projectId: - type: string - authorizationLevel: - type: string Prefab: type: object properties: diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py index e5982b7f..ff1666c0 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py @@ -37,7 +37,7 @@ def test_add_scenario_not_authorized(client, mocker): 'projectId': test_id, 'portfolioId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }] }) @@ -71,7 +71,7 @@ def test_add_scenario(client, mocker): 'portfolioIds': [test_id], 'scenarioIds': [test_id], 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'EDIT' }], 'simulation': { diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py index 52f71aa4..1a44c63d 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py @@ -21,10 +21,7 @@ def test_get_portfolio_not_authorized(client, mocker): return_value={ 'projectId': test_id, '_id': test_id, - 'authorizations': [{ - 'projectId': test_id_2, - 'authorizationLevel': 'OWN' - }] + 'authorizations': [] }) res = client.get(f'/v2/portfolios/{test_id}') assert '403' in res.status @@ -37,7 +34,7 @@ def test_get_portfolio(client, mocker): 'projectId': test_id, '_id': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'EDIT' }] }) @@ -69,7 +66,7 @@ def test_update_portfolio_not_authorized(client, mocker): '_id': test_id, 'projectId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }] }) @@ -92,7 +89,7 @@ def test_update_portfolio(client, mocker): '_id': test_id, 'projectId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }], 'targets': { @@ -125,7 +122,7 @@ def test_delete_project_different_user(client, mocker): 'projectId': test_id, 'googleId': 'other_test', 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }] }) @@ -142,7 +139,7 @@ def test_delete_project(client, mocker): 'googleId': 'test', 'portfolioIds': [test_id], 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }] }) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py index 0de50851..5a8d367f 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py @@ -1,17 +1,14 @@ from opendc.models.prefab import Prefab from opendc.util.database import DB -from opendc.models.user import User from opendc.util.rest import Response def GET(request): """Return all prefabs the user is authorized to access""" - user = User.from_google_id(request.current_user['sub']) + user_id = request.current_user['sub'] - user.check_exists() - - own_prefabs = DB.fetch_all({'authorId': user.get_id()}, Prefab.collection_name) + own_prefabs = DB.fetch_all({'authorId': user_id}, Prefab.collection_name) public_prefabs = DB.fetch_all({'visibility': 'public'}, Prefab.collection_name) authorizations = {"authorizations": []} diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py index e77c7150..4a30f7eb 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py @@ -1,7 +1,6 @@ from datetime import datetime from opendc.models.prefab import Prefab -from opendc.models.user import User from opendc.util.database import Database from opendc.util.rest import Response @@ -15,8 +14,8 @@ def POST(request): prefab.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) prefab.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) - user = User.from_google_id(request.current_user['sub']) - prefab.set_property('authorId', user.get_id()) + user_id = request.current_user['sub'] + prefab.set_property('authorId', user_id) prefab.insert() diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py index 2daeb6bf..bc3b1a32 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py @@ -32,7 +32,7 @@ def test_get_private_prefab(client, mocker): DB.fetch_one.side_effect = [{ '_id': test_id, 'name': 'test prefab', - 'authorId': test_id, + 'authorId': 'test', 'visibility': 'private', 'rack': {} }, @@ -92,7 +92,7 @@ def test_update_prefab(client, mocker): DB.fetch_one.side_effect = [{ '_id': test_id, 'name': 'test prefab', - 'authorId': test_id, + 'authorId': 'test', 'visibility': 'private', 'rack': {} }, @@ -132,7 +132,7 @@ def test_delete_prefab(client, mocker): DB.fetch_one.side_effect = [{ '_id': test_id, 'name': 'test prefab', - 'authorId': test_id, + 'authorId': 'test', 'visibility': 'private', 'rack': {} }, diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py index dacbe6a4..b381d689 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py @@ -2,15 +2,22 @@ from datetime import datetime from opendc.models.project import Project from opendc.models.topology import Topology -from opendc.models.user import User from opendc.util.database import Database from opendc.util.rest import Response +def GET(request): + """Get the authorized projects of the user""" + user_id = request.current_user['sub'] + projects = Project.get_for_user(user_id) + return Response(200, 'Successfully retrieved projects', projects) + + def POST(request): """Create a new project, and return that new project.""" request.check_required_parameters(body={'project': {'name': 'string'}}) + user_id = request.current_user['sub'] topology = Topology({'name': 'Default topology', 'rooms': []}) topology.insert() @@ -20,13 +27,10 @@ def POST(request): project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) project.set_property('topologyIds', [topology.get_id()]) project.set_property('portfolioIds', []) + project.set_property('authorizations', [{'userId': user_id, 'authorizationLevel': 'OWN'}]) project.insert() topology.set_property('projectId', project.get_id()) topology.update() - user = User.from_google_id(request.current_user['sub']) - user.obj['authorizations'].append({'projectId': project.get_id(), 'authorizationLevel': 'OWN'}) - user.update() - return Response(200, 'Successfully created project.', project.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py deleted file mode 100644 index 1b229122..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py +++ /dev/null @@ -1,17 +0,0 @@ -from opendc.models.project import Project -from opendc.util.rest import Response - - -def GET(request): - """Find all authorizations for a Project.""" - - request.check_required_parameters(path={'projectId': 'string'}) - - project = Project.from_id(request.params_path['projectId']) - - project.check_exists() - project.check_user_access(request.current_user['sub'], False) - - authorizations = project.get_all_authorizations() - - return Response(200, 'Successfully retrieved project authorizations', authorizations) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py deleted file mode 100644 index bebd6cff..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py +++ /dev/null @@ -1,43 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' -test_id_2 = 24 * '2' - - -def test_get_authorizations_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - mocker.patch.object(DB, 'fetch_all', return_value=None) - assert '404' in client.get(f'/v2/projects/{test_id}/authorizations').status - - -def test_get_authorizations_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'name': 'test trace', - 'authorizations': [{ - 'projectId': test_id_2, - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'fetch_all', return_value=[]) - res = client.get(f'/v2/projects/{test_id}/authorizations') - assert '403' in res.status - - -def test_get_authorizations(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'name': 'test trace', - 'authorizations': [{ - 'projectId': test_id, - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'fetch_all', return_value=[]) - res = client.get(f'/v2/projects/{test_id}/authorizations') - assert len(res.json['content']) == 0 - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py index 37cf1860..fa53ce6b 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py @@ -3,7 +3,6 @@ from datetime import datetime from opendc.models.portfolio import Portfolio from opendc.models.project import Project from opendc.models.topology import Topology -from opendc.models.user import User from opendc.util.database import Database from opendc.util.rest import Response @@ -56,11 +55,6 @@ def DELETE(request): portfolio = Portfolio.from_id(portfolio_id) portfolio.delete() - user = User.from_google_id(request.current_user['sub']) - user.obj['authorizations'] = list( - filter(lambda x: x['projectId'] != project.get_id(), user.obj['authorizations'])) - user.update() - old_object = project.delete() return Response(200, 'Successfully deleted project.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py index 04c699b5..7ddfe0ce 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py @@ -28,7 +28,7 @@ def test_add_portfolio_not_authorized(client, mocker): '_id': test_id, 'projectId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }] }) @@ -52,7 +52,7 @@ def test_add_portfolio(client, mocker): 'projectId': test_id, 'portfolioIds': [test_id], 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'EDIT' }] }) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py index f9ffaf37..03e6758b 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py @@ -20,10 +20,7 @@ def test_get_project_not_authorized(client, mocker): 'fetch_one', return_value={ '_id': test_id, - 'authorizations': [{ - 'projectId': test_id_2, - 'authorizationLevel': 'OWN' - }] + 'authorizations': [] }) res = client.get(f'/v2/projects/{test_id}') assert '403' in res.status @@ -35,7 +32,7 @@ def test_get_project(client, mocker): return_value={ '_id': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'EDIT' }] }) @@ -58,7 +55,7 @@ def test_update_project_not_authorized(client, mocker): return_value={ '_id': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }] }) @@ -72,7 +69,7 @@ def test_update_project(client, mocker): return_value={ '_id': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }] }) @@ -94,7 +91,7 @@ def test_delete_project_different_user(client, mocker): '_id': test_id, 'googleId': 'other_test', 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }], 'topologyIds': [] @@ -110,7 +107,7 @@ def test_delete_project(client, mocker): '_id': test_id, 'googleId': 'test', 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }], 'topologyIds': [], diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py index 71e88f00..2e872415 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py @@ -13,7 +13,7 @@ def test_add_topology(client, mocker): return_value={ '_id': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }], 'topologyIds': [] @@ -39,7 +39,7 @@ def test_add_topology_not_authorized(client, mocker): '_id': test_id, 'projectId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'VIEW' }] }) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py index 9444b1e4..db768f28 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py @@ -3,6 +3,13 @@ from opendc.util.database import DB test_id = 24 * '1' +def test_get_user_projects(client, mocker): + mocker.patch.object(DB, 'fetch_all', return_value={'_id': test_id, 'authorizations': [{'userId': 'test', + 'authorizationLevel': 'OWN'}]}) + res = client.get('/v2/projects') + assert '200' in res.status + + def test_add_project_missing_parameter(client): assert '400' in client.post('/v2/projects').status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py index cd4bcdf8..24b38671 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py @@ -10,26 +10,9 @@ def test_get_scenario_non_existing(client, mocker): def test_get_scenario_no_authorizations(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={ - 'portfolioId': '1', - 'authorizations': [] - }) - res = client.get(f'/v2/scenarios/{test_id}') - assert '403' in res.status - - -def test_get_scenario_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - 'projectId': test_id, - 'portfolioId': test_id, - '_id': test_id, - 'authorizations': [{ - 'projectId': test_id_2, - 'authorizationLevel': 'OWN' - }] - }) + m = mocker.MagicMock() + m.side_effect = ({'portfolioId': test_id}, {'projectId': test_id}, {'authorizations': []}) + mocker.patch.object(DB, 'fetch_one', m) res = client.get(f'/v2/scenarios/{test_id}') assert '403' in res.status @@ -37,15 +20,12 @@ def test_get_scenario_not_authorized(client, mocker): def test_get_scenario(client, mocker): mocker.patch.object(DB, 'fetch_one', - return_value={ - 'projectId': test_id, - 'portfolioId': test_id, - '_id': test_id, - 'authorizations': [{ - 'projectId': test_id, - 'authorizationLevel': 'EDIT' - }] - }) + side_effect=[ + {'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'authorizationLevel': 'OWN'}] + }]) res = client.get(f'/v2/scenarios/{test_id}') assert '200' in res.status @@ -66,15 +46,12 @@ def test_update_scenario_non_existing(client, mocker): def test_update_scenario_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioId': test_id, - 'authorizations': [{ - 'projectId': test_id, - 'authorizationLevel': 'VIEW' - }] - }) + side_effect=[ + {'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'authorizationLevel': 'VIEW'}] + }]) mocker.patch.object(DB, 'update', return_value={}) assert '403' in client.put(f'/v2/scenarios/{test_id}', json={ 'scenario': { @@ -86,19 +63,12 @@ def test_update_scenario_not_authorized(client, mocker): def test_update_scenario(client, mocker): mocker.patch.object(DB, 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioId': test_id, - 'authorizations': [{ - 'projectId': test_id, - 'authorizationLevel': 'OWN' - }], - 'targets': { - 'enabledMetrics': [], - 'repeatsPerScenario': 1 - } - }) + side_effect=[ + {'_id': test_id, 'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'authorizationLevel': 'OWN'}] + }]) mocker.patch.object(DB, 'update', return_value={}) res = client.put(f'/v2/scenarios/{test_id}', json={'scenario': { @@ -115,16 +85,12 @@ def test_delete_project_non_existing(client, mocker): def test_delete_project_different_user(client, mocker): mocker.patch.object(DB, 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioId': test_id, - 'googleId': 'other_test', - 'authorizations': [{ - 'projectId': test_id, - 'authorizationLevel': 'VIEW' - }] - }) + side_effect=[ + {'_id': test_id, 'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'authorizationLevel': 'VIEW'}] + }]) mocker.patch.object(DB, 'delete_one', return_value=None) assert '403' in client.delete(f'/v2/scenarios/{test_id}').status @@ -139,7 +105,7 @@ def test_delete_project(client, mocker): 'googleId': 'test', 'scenarioIds': [test_id], 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }] }) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py index 4da0bc64..96d2e08e 100644 --- a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py +++ b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py @@ -11,7 +11,7 @@ def test_get_topology(client, mocker): '_id': test_id, 'projectId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'EDIT' }] }) @@ -30,10 +30,7 @@ def test_get_topology_not_authorized(client, mocker): return_value={ '_id': test_id, 'projectId': test_id, - 'authorizations': [{ - 'projectId': test_id_2, - 'authorizationLevel': 'OWN' - }] + 'authorizations': [] }) res = client.get(f'/v2/topologies/{test_id}') assert '403' in res.status @@ -60,10 +57,7 @@ def test_update_topology_not_authorized(client, mocker): return_value={ '_id': test_id, 'projectId': test_id, - 'authorizations': [{ - 'projectId': test_id, - 'authorizationLevel': 'VIEW' - }] + 'authorizations': [] }) mocker.patch.object(DB, 'update', return_value={}) assert '403' in client.put(f'/v2/topologies/{test_id}', json={ @@ -81,7 +75,7 @@ def test_update_topology(client, mocker): '_id': test_id, 'projectId': test_id, 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }] }) @@ -104,7 +98,7 @@ def test_delete_topology(client, mocker): 'googleId': 'test', 'topologyIds': [test_id], 'authorizations': [{ - 'projectId': test_id, + 'userId': 'test', 'authorizationLevel': 'OWN' }] }) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py deleted file mode 100644 index fe61ce25..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py +++ /dev/null @@ -1,30 +0,0 @@ -from opendc.models.user import User -from opendc.util.rest import Response - - -def GET(request): - """Search for a User using their email address.""" - - request.check_required_parameters(query={'email': 'string'}) - - user = User.from_email(request.params_query['email']) - - user.check_exists() - - return Response(200, 'Successfully retrieved user.', user.obj) - - -def POST(request): - """Add a new User.""" - - request.check_required_parameters(body={'user': {'email': 'string'}}) - - user = User(request.params_body['user']) - user.set_property('googleId', request.current_user['sub']) - user.set_property('authorizations', []) - - user.check_already_exists() - - user.insert() - - return Response(200, 'Successfully created user.', user.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py deleted file mode 100644 index 13b63b20..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py +++ /dev/null @@ -1,34 +0,0 @@ -from opendc.util.database import DB - - -def test_get_user_by_email_missing_parameter(client): - assert '400' in client.get('/v2/users').status - - -def test_get_user_by_email_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/v2/users?email=test@test.com').status - - -def test_get_user_by_email(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'}) - res = client.get('/v2/users?email=test@test.com') - assert 'email' in res.json['content'] - assert '200' in res.status - - -def test_add_user_missing_parameter(client): - assert '400' in client.post('/v2/users').status - - -def test_add_user_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'}) - assert '409' in client.post('/v2/users', json={'user': {'email': 'test@test.com'}}).status - - -def test_add_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - mocker.patch.object(DB, 'insert', return_value={'email': 'test@test.com'}) - res = client.post('/v2/users', json={'user': {'email': 'test@test.com'}}) - assert 'email' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py deleted file mode 100644 index 26ff7717..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py +++ /dev/null @@ -1,59 +0,0 @@ -from opendc.models.project import Project -from opendc.models.user import User -from opendc.util.rest import Response - - -def GET(request): - """Get this User.""" - - request.check_required_parameters(path={'userId': 'string'}) - - user = User.from_id(request.params_path['userId']) - - user.check_exists() - - return Response(200, 'Successfully retrieved user.', user.obj) - - -def PUT(request): - """Update this User's given name and/or family name.""" - - request.check_required_parameters(body={'user': { - 'givenName': 'string', - 'familyName': 'string' - }}, - path={'userId': 'string'}) - - user = User.from_id(request.params_path['userId']) - - user.check_exists() - user.check_correct_user(request.current_user['sub']) - - user.set_property('givenName', request.params_body['user']['givenName']) - user.set_property('familyName', request.params_body['user']['familyName']) - - user.update() - - return Response(200, 'Successfully updated user.', user.obj) - - -def DELETE(request): - """Delete this User.""" - - request.check_required_parameters(path={'userId': 'string'}) - - user = User.from_id(request.params_path['userId']) - - user.check_exists() - user.check_correct_user(request.current_user['sub']) - - for authorization in user.obj['authorizations']: - if authorization['authorizationLevel'] != 'OWN': - continue - - project = Project.from_id(authorization['projectId']) - project.delete() - - old_object = user.delete() - - return Response(200, 'Successfully deleted user.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py deleted file mode 100644 index 4085642f..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py +++ /dev/null @@ -1,56 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_get_user_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get(f'/v2/users/{test_id}').status - - -def test_get_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'}) - res = client.get(f'/v2/users/{test_id}') - assert 'email' in res.json['content'] - assert '200' in res.status - - -def test_update_user_missing_parameter(client): - assert '400' in client.put(f'/v2/users/{test_id}').status - - -def test_update_user_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put(f'/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status - - -def test_update_user_different_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'other_test'}) - assert '403' in client.put(f'/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status - - -def test_update_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'test'}) - mocker.patch.object(DB, 'update', return_value={'givenName': 'A', 'familyName': 'B'}) - res = client.put(f'/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}) - assert 'givenName' in res.json['content'] - assert '200' in res.status - - -def test_delete_user_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete(f'/v2/users/{test_id}').status - - -def test_delete_user_different_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'other_test'}) - assert '403' in client.delete(f'/v2/users/{test_id}').status - - -def test_delete_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'test', 'authorizations': []}) - mocker.patch.object(DB, 'delete_one', return_value={'googleId': 'test'}) - res = client.delete(f'/v2/users/{test_id}', ) - - assert 'googleId' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/models/portfolio.py b/opendc-web/opendc-web-api/opendc/models/portfolio.py index 32961b63..8e3f2a52 100644 --- a/opendc-web/opendc-web-api/opendc/models/portfolio.py +++ b/opendc-web/opendc-web-api/opendc/models/portfolio.py @@ -1,7 +1,5 @@ +from opendc.models.project import Project from opendc.models.model import Model -from opendc.models.user import User -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response class Portfolio(Model): @@ -9,16 +7,13 @@ class Portfolio(Model): collection_name = 'portfolios' - def check_user_access(self, google_id, edit_access): - """Raises an error if the user with given [google_id] has insufficient access. + def check_user_access(self, user_id, edit_access): + """Raises an error if the user with given [user_id] has insufficient access. Checks access on the parent project. - :param google_id: The Google ID of the user. + :param user_id: The User ID of the user. :param edit_access: True when edit access should be checked, otherwise view access. """ - user = User.from_google_id(google_id) - authorizations = list( - filter(lambda x: str(x['projectId']) == str(self.obj['projectId']), user.obj['authorizations'])) - if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'): - raise ClientError(Response(403, 'Forbidden from retrieving/editing portfolio.')) + project = Project.from_id(self.obj['projectId']) + project.check_user_access(user_id, edit_access) diff --git a/opendc-web/opendc-web-api/opendc/models/prefab.py b/opendc-web/opendc-web-api/opendc/models/prefab.py index edf1d4c4..05356358 100644 --- a/opendc-web/opendc-web-api/opendc/models/prefab.py +++ b/opendc-web/opendc-web-api/opendc/models/prefab.py @@ -1,5 +1,4 @@ from opendc.models.model import Model -from opendc.models.user import User from opendc.util.exceptions import ClientError from opendc.util.rest import Response @@ -9,20 +8,10 @@ class Prefab(Model): collection_name = 'prefabs' - def check_user_access(self, google_id): - """Raises an error if the user with given [google_id] has insufficient access to view this prefab. + def check_user_access(self, user_id): + """Raises an error if the user with given [user_id] has insufficient access to view this prefab. - :param google_id: The Google ID of the user. + :param user_id: The Google ID of the user. """ - user = User.from_google_id(google_id) - - # TODO(Jacob) add special handling for OpenDC-provided prefabs - - #try: - - print(self.obj) - if self.obj['authorId'] != user.get_id() and self.obj['visibility'] == "private": + if self.obj['authorId'] != user_id and self.obj['visibility'] == "private": raise ClientError(Response(403, "Forbidden from retrieving prefab.")) - #except KeyError: - # OpenDC-authored objects don't necessarily have an authorId - # return diff --git a/opendc-web/opendc-web-api/opendc/models/project.py b/opendc-web/opendc-web-api/opendc/models/project.py index b57e9f77..2b3fd5f4 100644 --- a/opendc-web/opendc-web-api/opendc/models/project.py +++ b/opendc-web/opendc-web-api/opendc/models/project.py @@ -1,5 +1,4 @@ from opendc.models.model import Model -from opendc.models.user import User from opendc.util.database import DB from opendc.util.exceptions import ClientError from opendc.util.rest import Response @@ -10,22 +9,20 @@ class Project(Model): collection_name = 'projects' - def check_user_access(self, google_id, edit_access): - """Raises an error if the user with given [google_id] has insufficient access. + def check_user_access(self, user_id, edit_access): + """Raises an error if the user with given [user_id] has insufficient access. - :param google_id: The Google ID of the user. + :param user_id: The User ID of the user. :param edit_access: True when edit access should be checked, otherwise view access. """ - user = User.from_google_id(google_id) - authorizations = list(filter(lambda x: str(x['projectId']) == str(self.get_id()), - user.obj['authorizations'])) - if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'): - raise ClientError(Response(403, "Forbidden from retrieving project.")) + for authorization in self.obj['authorizations']: + if user_id == authorization['userId'] and authorization['authorizationLevel'] != 'VIEW' or not edit_access: + return + raise ClientError(Response(403, "Forbidden from retrieving project.")) - def get_all_authorizations(self): - """Get all user IDs having access to this project.""" - return [ - str(user['_id']) for user in DB.fetch_all({'authorizations': { - 'projectId': self.obj['_id'] - }}, User.collection_name) - ] + @classmethod + def get_for_user(cls, user_id): + """Get all projects for the specified user id.""" + return DB.fetch_all({'authorizations': { + 'userId': user_id + }}, Project.collection_name) diff --git a/opendc-web/opendc-web-api/opendc/models/scenario.py b/opendc-web/opendc-web-api/opendc/models/scenario.py index 8d53e408..3dfde012 100644 --- a/opendc-web/opendc-web-api/opendc/models/scenario.py +++ b/opendc-web/opendc-web-api/opendc/models/scenario.py @@ -1,8 +1,5 @@ from opendc.models.model import Model from opendc.models.portfolio import Portfolio -from opendc.models.user import User -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response class Scenario(Model): @@ -10,17 +7,14 @@ class Scenario(Model): collection_name = 'scenarios' - def check_user_access(self, google_id, edit_access): - """Raises an error if the user with given [google_id] has insufficient access. + def check_user_access(self, user_id, edit_access): + """Raises an error if the user with given [user_id] has insufficient access. Checks access on the parent project. - :param google_id: The Google ID of the user. + :param user_id: The User ID of the user. :param edit_access: True when edit access should be checked, otherwise view access. """ portfolio = Portfolio.from_id(self.obj['portfolioId']) - user = User.from_google_id(google_id) - authorizations = list( - filter(lambda x: str(x['projectId']) == str(portfolio.obj['projectId']), user.obj['authorizations'])) - if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'): - raise ClientError(Response(403, 'Forbidden from retrieving/editing scenario.')) + print(portfolio.obj) + portfolio.check_user_access(user_id, edit_access) diff --git a/opendc-web/opendc-web-api/opendc/models/topology.py b/opendc-web/opendc-web-api/opendc/models/topology.py index cb4c4bab..3ebec16d 100644 --- a/opendc-web/opendc-web-api/opendc/models/topology.py +++ b/opendc-web/opendc-web-api/opendc/models/topology.py @@ -1,7 +1,5 @@ +from opendc.models.project import Project from opendc.models.model import Model -from opendc.models.user import User -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response class Topology(Model): @@ -9,19 +7,13 @@ class Topology(Model): collection_name = 'topologies' - def check_user_access(self, google_id, edit_access): - """Raises an error if the user with given [google_id] has insufficient access. + def check_user_access(self, user_id, edit_access): + """Raises an error if the user with given [user_id] has insufficient access. Checks access on the parent project. - :param google_id: The Google ID of the user. + :param user_id: The User ID of the user. :param edit_access: True when edit access should be checked, otherwise view access. """ - user = User.from_google_id(google_id) - if 'projectId' not in self.obj: - raise ClientError(Response(400, 'Missing projectId in topology.')) - - authorizations = list( - filter(lambda x: str(x['projectId']) == str(self.obj['projectId']), user.obj['authorizations'])) - if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'): - raise ClientError(Response(403, 'Forbidden from retrieving topology.')) + project = Project.from_id(self.obj['projectId']) + project.check_user_access(user_id, edit_access) diff --git a/opendc-web/opendc-web-api/opendc/models/user.py b/opendc-web/opendc-web-api/opendc/models/user.py deleted file mode 100644 index 8e8ff945..00000000 --- a/opendc-web/opendc-web-api/opendc/models/user.py +++ /dev/null @@ -1,36 +0,0 @@ -from opendc.models.model import Model -from opendc.util.database import DB -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response - - -class User(Model): - """Model representing a User.""" - - collection_name = 'users' - - @classmethod - def from_email(cls, email): - """Fetches the user with given email from the collection.""" - return User(DB.fetch_one({'email': email}, User.collection_name)) - - @classmethod - def from_google_id(cls, google_id): - """Fetches the user with given Google ID from the collection.""" - return User(DB.fetch_one({'googleId': google_id}, User.collection_name)) - - def check_correct_user(self, request_google_id): - """Raises an error if a user tries to modify another user. - - :param request_google_id: - """ - if request_google_id is not None and self.obj['googleId'] != request_google_id: - raise ClientError(Response(403, f'Forbidden from editing user with ID {self.obj["_id"]}.')) - - def check_already_exists(self): - """Checks if the user already exists in the database.""" - - existing_user = DB.fetch_one({'googleId': self.obj['googleId']}, self.collection_name) - - if existing_user is not None: - raise ClientError(Response(409, 'User already exists.')) -- cgit v1.2.3 From eac80eaa36560dc43e338ade58267860865d1c48 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 17 Mar 2021 16:44:51 +0100 Subject: ci: Update to Java 16 This change switches one of the CI builds to use Java 16 when building and testing the simulator. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cbf2f80d..8690cf5b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - java: [8, 15] + java: [8, 16] steps: - name: Checkout repository uses: actions/checkout@v2 -- cgit v1.2.3 From ef3868ec729f7ce3f5976d4f9a0c8b95098d9857 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 4 May 2021 14:40:46 +0200 Subject: build: Update to Kotlin 1.5.0 --- buildSrc/build.gradle.kts | 8 +------- buildSrc/src/main/kotlin/kotlin-conventions.gradle.kts | 1 - gradle/libs.versions.toml | 14 +++++++------- .../opendc-experiments-serverless20/build.gradle.kts | 3 ++- opendc-format/build.gradle.kts | 5 ++++- opendc-web/opendc-web-runner/build.gradle.kts | 5 ++++- opendc-workflow/opendc-workflow-service/build.gradle.kts | 5 ++++- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3b793a61..56b85608 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -33,16 +33,10 @@ repositories { } dependencies { - implementation(kotlin("gradle-plugin", version = "1.4.31")) + implementation(kotlin("gradle-plugin", version = "1.5.0")) implementation("org.jlleitschuh.gradle:ktlint-gradle:10.0.0") implementation("org.jetbrains.kotlin:kotlin-allopen:1.4.31") implementation("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.3.0") implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.4.32") implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:7.0.0") } - -tasks.withType().configureEach { - kotlinOptions { - allWarningsAsErrors = true - } -} diff --git a/buildSrc/src/main/kotlin/kotlin-conventions.gradle.kts b/buildSrc/src/main/kotlin/kotlin-conventions.gradle.kts index 703e9938..7fda64a2 100644 --- a/buildSrc/src/main/kotlin/kotlin-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/kotlin-conventions.gradle.kts @@ -39,6 +39,5 @@ java { tasks.withType().configureEach { kotlinOptions.jvmTarget = Libs.jvmTarget.toString() - kotlinOptions.useIR = true kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 12cbfb4e..1d7fdd3e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,13 +1,13 @@ [versions] -junit-jupiter = "5.7.1" -junit-platform = "1.7.1" +junit-jupiter = "5.7.2" +junit-platform = "1.7.2" slf4j = "1.7.30" log4j = "2.14.1" -opentelemetry-main = "1.1.0" -opentelemetry-metrics = "1.1.0-alpha" +opentelemetry-main = "1.2.0" +opentelemetry-metrics = "1.2.0-alpha" [libraries] -kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.4.3" } +kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.5.0" } # Logging kotlin-logging = { module = "io.github.microutils:kotlin-logging", version = "2.0.6" } @@ -30,7 +30,7 @@ junit-platform-engine = { module = "org.junit.platform:junit-platform-engine", v mockk = { module = "io.mockk:mockk", version = "1.11.0" } # CLI -clikt = { module = "com.github.ajalt.clikt:clikt", version = "3.1.0" } +clikt = { module = "com.github.ajalt.clikt:clikt", version = "3.2.0" } progressbar = { module = "me.tongfei:progressbar", version = "0.9.0" } # Format @@ -45,4 +45,4 @@ kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchm # Other mongodb = { module = "org.mongodb:mongodb-driver-sync", version = "4.2.3" } classgraph = { module = "io.github.classgraph:classgraph", version = "4.8.105" } -hadoop-client = { module = "org.apache.hadoop:hadoop-client", version = "3.2.1" } +hadoop-client = { module = "org.apache.hadoop:hadoop-client", version = "3.3.0" } diff --git a/opendc-experiments/opendc-experiments-serverless20/build.gradle.kts b/opendc-experiments/opendc-experiments-serverless20/build.gradle.kts index bdb0d098..88479765 100644 --- a/opendc-experiments/opendc-experiments-serverless20/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-serverless20/build.gradle.kts @@ -38,7 +38,8 @@ dependencies { implementation(libs.kotlin.logging) implementation(libs.config) - implementation(libs.parquet) { + implementation(libs.parquet) + implementation(libs.hadoop.client) { exclude(group = "org.slf4j", module = "slf4j-log4j12") exclude(group = "log4j") } diff --git a/opendc-format/build.gradle.kts b/opendc-format/build.gradle.kts index 2647c834..e95cb666 100644 --- a/opendc-format/build.gradle.kts +++ b/opendc-format/build.gradle.kts @@ -35,7 +35,10 @@ dependencies { api(projects.opendcWorkflow.opendcWorkflowApi) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcCompute.opendcComputeSimulator) - api(libs.jackson.module.kotlin) + api(libs.jackson.module.kotlin) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") + } + implementation(kotlin("reflect")) implementation(libs.parquet) implementation(libs.hadoop.client) { diff --git a/opendc-web/opendc-web-runner/build.gradle.kts b/opendc-web/opendc-web-runner/build.gradle.kts index b7eb223c..f2b2ba23 100644 --- a/opendc-web/opendc-web-runner/build.gradle.kts +++ b/opendc-web/opendc-web-runner/build.gradle.kts @@ -42,7 +42,10 @@ dependencies { implementation(libs.kotlin.logging) implementation(libs.clikt) - implementation(libs.jackson.module.kotlin) + implementation(libs.jackson.module.kotlin) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") + } + implementation(kotlin("reflect")) implementation(libs.sentry.log4j2) implementation(libs.mongodb) diff --git a/opendc-workflow/opendc-workflow-service/build.gradle.kts b/opendc-workflow/opendc-workflow-service/build.gradle.kts index 5e73222c..bc082dbc 100644 --- a/opendc-workflow/opendc-workflow-service/build.gradle.kts +++ b/opendc-workflow/opendc-workflow-service/build.gradle.kts @@ -41,6 +41,9 @@ dependencies { testImplementation(projects.opendcCompute.opendcComputeSimulator) testImplementation(projects.opendcFormat) testImplementation(projects.opendcTelemetry.opendcTelemetrySdk) - testImplementation(libs.jackson.module.kotlin) + testImplementation(libs.jackson.module.kotlin) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") + } + testImplementation(kotlin("reflect")) testRuntimeOnly(libs.log4j.slf4j) } -- cgit v1.2.3 From cc9310efad6177909ff2f7415384d7c393383106 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 5 May 2021 23:14:56 +0200 Subject: chore: Address deprecations due to Kotlin 1.5 This change addresses the deprecations that were caused by the migration to Kotlin 1.5. --- .../kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt | 2 +- .../experiments/capelin/telemetry/parquet/ParquetEventWriter.kt | 1 + .../opendc/experiments/capelin/trace/Sc20RawParquetTraceReader.kt | 2 +- .../org/opendc/experiments/capelin/trace/Sc20TraceConverter.kt | 2 ++ .../kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt | 4 ++-- .../main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt | 4 ++-- .../org/opendc/experiments/tf20/network/NetworkController.kt | 2 +- .../src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt | 4 ---- .../kotlin/org/opendc/serverless/simulator/SimFunctionDeployer.kt | 2 +- .../main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt | 2 +- .../opendc/simulator/resources/SimAbstractResourceAggregator.kt | 4 ++-- opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt | 7 +++---- .../src/main/kotlin/org/opendc/runner/web/TopologyParser.kt | 2 +- 13 files changed, 18 insertions(+), 20 deletions(-) diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt index 0fd5b2a4..1fe90454 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt @@ -59,7 +59,7 @@ public class FilterScheduler(private val filters: List, private val true } .sortedByDescending { host -> - weighers.sumByDouble { (weigher, factor) -> weigher.getWeight(host, server) * factor } + weighers.sumOf { (weigher, factor) -> weigher.getWeight(host, server) * factor } } .firstOrNull() } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt index 38930ee5..4fa6ae66 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt @@ -52,6 +52,7 @@ public open class ParquetEventWriter( /** * The writer to write the Parquet file. */ + @Suppress("DEPRECATION") private val writer = AvroParquetWriter.builder(Path(path.absolutePath)) .withSchema(schema) .withCompressionCodec(CompressionCodecName.SNAPPY) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20RawParquetTraceReader.kt index ffbf46d4..bd27cf02 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20RawParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20RawParquetTraceReader.kt @@ -105,7 +105,7 @@ public class Sc20RawParquetTraceReader(private val path: File) { val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) val vmFragments = fragments.getValue(id).asSequence() - val totalLoad = vmFragments.sumByDouble { it.usage } * 5 * 60 // avg MHz * duration = MFLOPs + val totalLoad = vmFragments.sumOf { it.usage } * 5 * 60 // avg MHz * duration = MFLOPs val workload = SimTraceWorkload(vmFragments) entries.add( TraceEntry( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20TraceConverter.kt index 7713c06f..1f9e289c 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20TraceConverter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20TraceConverter.kt @@ -109,6 +109,7 @@ public class TraceConverterCli : CliktCommand(name = "trace-converter") { traceParquet.delete() } + @Suppress("DEPRECATION") val metaWriter = AvroParquetWriter.builder(Path(metaParquet.toURI())) .withSchema(metaSchema) .withCompressionCodec(CompressionCodecName.SNAPPY) @@ -116,6 +117,7 @@ public class TraceConverterCli : CliktCommand(name = "trace-converter") { .withRowGroupSize(16 * 1024 * 1024) // For write buffering (Page size) .build() + @Suppress("DEPRECATION") val writer = AvroParquetWriter.builder(Path(traceParquet.toURI())) .withSchema(schema) .withCompressionCodec(CompressionCodecName.SNAPPY) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt index 5c8727ea..6de3f265 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt @@ -69,7 +69,7 @@ public fun sampleRegularWorkload( val totalLoad = if (workload is CompositeWorkload) { workload.totalLoad } else { - shuffled.sumByDouble { it.meta.getValue("total-load") as Double } + shuffled.sumOf { it.meta.getValue("total-load") as Double } } var currentLoad = 0.0 @@ -129,7 +129,7 @@ public fun sampleHpcWorkload( val totalLoad = if (workload is CompositeWorkload) { workload.totalLoad } else { - trace.sumByDouble { it.meta.getValue("total-load") as Double } + trace.sumOf { it.meta.getValue("total-load") as Double } } logger.debug { "Total trace load: $totalLoad" } diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt index 411ddb59..83995fa1 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt @@ -49,10 +49,10 @@ public class Sequential(vararg layers: Layer) : TrainableModel(*layers) { } override fun forward(): Double { - return layers.sumByDouble { it.forward() } + return layers.sumOf { it.forward() } } override fun backward(): Double { - return layers.sumByDouble { it.backward() } + return layers.sumOf { it.backward() } } } diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt index 75b11423..9771cc20 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt @@ -82,7 +82,7 @@ public class NetworkController(context: CoroutineContext, clock: Clock) : AutoCl val target = channels[to] ?: return // Drop if destination not found - scheduler.startSingleTimer(message, delayTime) { target.offer(message) } + scheduler.startSingleTimer(message, delayTime) { target.trySend(message) } } /** diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt index 0d1f3cea..50ab652e 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt @@ -69,8 +69,6 @@ public class SwfTraceReader( var cores: Int var memory: Long var slicedWaitTime: Long - var flopsPerSecond: Long - var flopsPartialSlice: Long var runtimePartialSliceRemainder: Long BufferedReader(FileReader(file)).use { reader -> @@ -121,9 +119,7 @@ public class SwfTraceReader( // Insert run time slices - flopsPerSecond = 4_000L * cores runtimePartialSliceRemainder = runTime % sliceDuration - flopsPartialSlice = flopsPerSecond * runtimePartialSliceRemainder for ( tick in (submitTime + slicedWaitTime) diff --git a/opendc-serverless/opendc-serverless-simulator/src/main/kotlin/org/opendc/serverless/simulator/SimFunctionDeployer.kt b/opendc-serverless/opendc-serverless-simulator/src/main/kotlin/org/opendc/serverless/simulator/SimFunctionDeployer.kt index 0605eaac..b5516b4d 100644 --- a/opendc-serverless/opendc-serverless-simulator/src/main/kotlin/org/opendc/serverless/simulator/SimFunctionDeployer.kt +++ b/opendc-serverless/opendc-serverless-simulator/src/main/kotlin/org/opendc/serverless/simulator/SimFunctionDeployer.kt @@ -102,7 +102,7 @@ public class SimFunctionDeployer( check(state != FunctionInstanceState.Deleted) { "Function instance has been released" } return suspendCancellableCoroutine { cont -> queue.add(InvocationRequest(cont)) - chan.offer(Unit) + chan.trySend(Unit) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index f6324e13..e501033a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -80,7 +80,7 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine override suspend fun run(workload: SimWorkload, meta: Map): Unit = withContext(context) { require(!isTerminated) { "Machine is terminated" } val ctx = Context(meta) - val totalCapacity = model.cpus.sumByDouble { it.frequency } + val totalCapacity = model.cpus.sumOf { it.frequency } _speed = DoubleArray(model.cpus.size) { 0.0 } var totalSpeed = 0.0 diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt index 6ae04f27..653b53e0 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt @@ -82,7 +82,7 @@ public abstract class SimAbstractResourceAggregator(private val scheduler: SimRe return if (_remainingWorkFlush < now) { _remainingWorkFlush = now - _inputConsumers.sumByDouble { it._ctx?.remainingWork ?: 0.0 }.also { _remainingWork = it } + _inputConsumers.sumOf { it._ctx?.remainingWork ?: 0.0 }.also { _remainingWork = it } } else { _remainingWork } @@ -132,7 +132,7 @@ public abstract class SimAbstractResourceAggregator(private val scheduler: SimRe private fun updateCapacity() { // Adjust capacity of output resource - context.capacity = _inputConsumers.sumByDouble { it._ctx?.capacity ?: 0.0 } + context.capacity = _inputConsumers.sumOf { it._ctx?.capacity ?: 0.0 } } /* Input */ diff --git a/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt b/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt index aa2f3367..d7da7f99 100644 --- a/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt +++ b/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt @@ -24,7 +24,6 @@ package org.opendc.utils import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.sendBlocking import kotlinx.coroutines.selects.select import java.time.Clock import java.util.* @@ -145,9 +144,9 @@ public class TimerScheduler(context: CoroutineContext, private val clock: Clo queue.poll() if (queue.isNotEmpty()) { - channel.sendBlocking(peek.timestamp) + channel.trySend(peek.timestamp) } else { - channel.sendBlocking(null) + channel.trySend(null) } } } @@ -212,7 +211,7 @@ public class TimerScheduler(context: CoroutineContext, private val clock: Clo // Check if we need to push the interruption forward // Note that we check by timer reference if (queue.peek() === timer) { - channel.offer(timer.timestamp) + channel.trySend(timer.timestamp) } timer diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt index 2dd63340..e96a681d 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt @@ -73,7 +73,7 @@ public class TopologyParser(private val collection: MongoCollection) { ) } - val energyConsumptionW = machine.getList("cpus", Document::class.java).sumBy { it.getInteger("energyConsumptionW") }.toDouble() + val energyConsumptionW = machine.getList("cpus", Document::class.java).sumOf { it.getInteger("energyConsumptionW") }.toDouble() nodes.add( MachineDef( -- cgit v1.2.3 From 0f7e0bdbec732b23141f6bbe11b3b2299ca22813 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 6 May 2021 16:41:53 +0200 Subject: build: Update Jacoco to version 0.8.7 This change updates the Gradle build configuration to use Jacoco 0.8.7, which is necessary for Kotlin 1.5.0 to work nicely with Jacoco. --- .../src/main/kotlin/jacoco-aggregation.gradle.kts | 7 ++++ .../src/main/kotlin/jacoco-conventions.gradle.kts | 38 +++------------------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/buildSrc/src/main/kotlin/jacoco-aggregation.gradle.kts b/buildSrc/src/main/kotlin/jacoco-aggregation.gradle.kts index 3e8aa741..1ea5de4c 100644 --- a/buildSrc/src/main/kotlin/jacoco-aggregation.gradle.kts +++ b/buildSrc/src/main/kotlin/jacoco-aggregation.gradle.kts @@ -1,3 +1,5 @@ +import gradle.kotlin.dsl.accessors._a850a9ab866951e91ee43960bbc39582.jacoco + /* * MIT License * @@ -32,6 +34,11 @@ repositories { mavenCentral() } +jacoco { + // Necessary for Kotlin 1.5.0. See https://github.com/jacoco/jacoco/issues/1155 + toolVersion = "0.8.7" +} + tasks.register("codeCoverageReport") { group = "Coverage reports" description = "Generates an aggregate report based on all subprojects" diff --git a/buildSrc/src/main/kotlin/jacoco-conventions.gradle.kts b/buildSrc/src/main/kotlin/jacoco-conventions.gradle.kts index d0534d4f..5c7aea83 100644 --- a/buildSrc/src/main/kotlin/jacoco-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/jacoco-conventions.gradle.kts @@ -25,41 +25,13 @@ plugins { jacoco } +jacoco { + // Necessary for Kotlin 1.5.0. See https://github.com/jacoco/jacoco/issues/1155 + toolVersion = "0.8.7" +} + tasks.jacocoTestReport { reports { html.isEnabled = true } } - -/* Share sources folder with other projects for aggregated JaCoCo reports */ -configurations.create("transitiveSourcesElements") { - isVisible = false - isCanBeResolved = false - isCanBeConsumed = true - extendsFrom(configurations.implementation.get()) - attributes { - attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) - attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) - attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("source-folders")) - } - sourceSets.main.get().java.srcDirs.forEach { - outgoing.artifact(it) - } -} - -/* Share the coverage data to be aggregated for the whole product */ -configurations.create("coverageDataElements") { - isVisible = false - isCanBeResolved = false - isCanBeConsumed = true - extendsFrom(configurations.implementation.get()) - attributes { - attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) - attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) - attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("jacoco-coverage-data")) - } - // This will cause the test task to run if the coverage data is requested by the aggregation task - outgoing.artifact(tasks.test.map { task -> - task.extensions.getByType().destinationFile!! - }) -} -- cgit v1.2.3 From 7cbb401a0939cc58daae8b481a97f4b05140ec3b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 18 May 2021 14:46:29 +0200 Subject: build: Update to Gradle 7.0.2 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f371643e..0f80bbf5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -- cgit v1.2.3 From 2281d3265423d01e60f8cc088de5a5730bb8a910 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sat, 15 May 2021 13:09:06 +0200 Subject: api: Migrate to Flask Restful This change updates the API to use Flask Restful instead of our own in-house REST library. This change reduces the maintenance effort and allows us to drastically simplify the API implementation needed for the OpenDC v2 API. --- docker-compose.override.yml | 2 +- docker-compose.prod.yml | 2 +- opendc-web/opendc-web-api/.pylintrc | 3 +- opendc-web/opendc-web-api/Dockerfile | 12 +- opendc-web/opendc-web-api/app.py | 179 +++++------- opendc-web/opendc-web-api/conftest.py | 19 +- opendc-web/opendc-web-api/opendc/api/portfolios.py | 135 +++++++++ opendc-web/opendc-web-api/opendc/api/prefabs.py | 120 ++++++++ opendc-web/opendc-web-api/opendc/api/projects.py | 195 +++++++++++++ opendc-web/opendc-web-api/opendc/api/scenarios.py | 81 ++++++ opendc-web/opendc-web-api/opendc/api/schedulers.py | 46 +++ opendc-web/opendc-web-api/opendc/api/topologies.py | 93 ++++++ opendc-web/opendc-web-api/opendc/api/traces.py | 51 ++++ .../opendc-web-api/opendc/api/v2/__init__.py | 0 opendc-web/opendc-web-api/opendc/api/v2/paths.json | 19 -- .../opendc/api/v2/portfolios/__init__.py | 0 .../api/v2/portfolios/portfolioId/__init__.py | 0 .../api/v2/portfolios/portfolioId/endpoint.py | 67 ----- .../portfolios/portfolioId/scenarios/__init__.py | 0 .../portfolios/portfolioId/scenarios/endpoint.py | 49 ---- .../portfolioId/scenarios/test_endpoint.py | 125 -------- .../api/v2/portfolios/portfolioId/test_endpoint.py | 149 ---------- .../opendc/api/v2/prefabs/__init__.py | 0 .../api/v2/prefabs/authorizations/__init__.py | 0 .../api/v2/prefabs/authorizations/endpoint.py | 19 -- .../api/v2/prefabs/authorizations/test_endpoint.py | 71 ----- .../opendc/api/v2/prefabs/endpoint.py | 22 -- .../opendc/api/v2/prefabs/prefabId/__init__.py | 0 .../opendc/api/v2/prefabs/prefabId/endpoint.py | 50 ---- .../api/v2/prefabs/prefabId/test_endpoint.py | 145 --------- .../opendc/api/v2/prefabs/test_endpoint.py | 24 -- .../opendc/api/v2/projects/__init__.py | 0 .../opendc/api/v2/projects/endpoint.py | 36 --- .../opendc/api/v2/projects/projectId/__init__.py | 0 .../opendc/api/v2/projects/projectId/endpoint.py | 60 ---- .../v2/projects/projectId/portfolios/__init__.py | 0 .../v2/projects/projectId/portfolios/endpoint.py | 35 --- .../projects/projectId/portfolios/test_endpoint.py | 85 ------ .../api/v2/projects/projectId/test_endpoint.py | 119 -------- .../v2/projects/projectId/topologies/__init__.py | 0 .../v2/projects/projectId/topologies/endpoint.py | 31 -- .../projects/projectId/topologies/test_endpoint.py | 52 ---- .../opendc/api/v2/projects/test_endpoint.py | 32 -- .../opendc/api/v2/scenarios/__init__.py | 0 .../opendc/api/v2/scenarios/scenarioId/__init__.py | 0 .../opendc/api/v2/scenarios/scenarioId/endpoint.py | 59 ---- .../api/v2/scenarios/scenarioId/test_endpoint.py | 115 -------- .../opendc/api/v2/schedulers/__init__.py | 0 .../opendc/api/v2/schedulers/endpoint.py | 19 -- .../opendc/api/v2/schedulers/test_endpoint.py | 2 - .../opendc/api/v2/topologies/__init__.py | 0 .../api/v2/topologies/topologyId/__init__.py | 0 .../api/v2/topologies/topologyId/endpoint.py | 58 ---- .../api/v2/topologies/topologyId/test_endpoint.py | 113 ------- .../opendc/api/v2/traces/__init__.py | 0 .../opendc/api/v2/traces/endpoint.py | 10 - .../opendc/api/v2/traces/test_endpoint.py | 6 - .../opendc/api/v2/traces/traceId/__init__.py | 0 .../opendc/api/v2/traces/traceId/endpoint.py | 14 - .../opendc/api/v2/traces/traceId/test_endpoint.py | 15 - opendc-web/opendc-web-api/opendc/auth.py | 240 +++++++++++++++ opendc-web/opendc-web-api/opendc/database.py | 102 +++++++ opendc-web/opendc-web-api/opendc/exts.py | 60 ++++ opendc-web/opendc-web-api/opendc/models/model.py | 19 +- .../opendc-web-api/opendc/models/portfolio.py | 21 ++ opendc-web/opendc-web-api/opendc/models/prefab.py | 23 +- opendc-web/opendc-web-api/opendc/models/project.py | 27 +- .../opendc-web-api/opendc/models/scenario.py | 46 ++- .../opendc-web-api/opendc/models/topology.py | 76 +++++ opendc-web/opendc-web-api/opendc/util.py | 32 ++ opendc-web/opendc-web-api/opendc/util/__init__.py | 0 opendc-web/opendc-web-api/opendc/util/auth.py | 253 ---------------- opendc-web/opendc-web-api/opendc/util/database.py | 77 ----- .../opendc-web-api/opendc/util/exceptions.py | 64 ---- opendc-web/opendc-web-api/opendc/util/json.py | 12 - .../opendc/util/parameter_checker.py | 85 ------ .../opendc-web-api/opendc/util/path_parser.py | 36 --- opendc-web/opendc-web-api/opendc/util/rest.py | 109 ------- opendc-web/opendc-web-api/requirements.txt | 2 + .../opendc-web-api/tests/api/test_portfolios.py | 324 +++++++++++++++++++++ .../opendc-web-api/tests/api/test_prefabs.py | 252 ++++++++++++++++ .../opendc-web-api/tests/api/test_projects.py | 167 +++++++++++ .../opendc-web-api/tests/api/test_scenarios.py | 135 +++++++++ .../opendc-web-api/tests/api/test_schedulers.py | 22 ++ .../opendc-web-api/tests/api/test_topologies.py | 140 +++++++++ opendc-web/opendc-web-api/tests/api/test_traces.py | 40 +++ opendc-web/opendc-web-ui/src/shapes.js | 2 +- 87 files changed, 2516 insertions(+), 2389 deletions(-) create mode 100644 opendc-web/opendc-web-api/opendc/api/portfolios.py create mode 100644 opendc-web/opendc-web-api/opendc/api/prefabs.py create mode 100644 opendc-web/opendc-web-api/opendc/api/projects.py create mode 100644 opendc-web/opendc-web-api/opendc/api/scenarios.py create mode 100644 opendc-web/opendc-web-api/opendc/api/schedulers.py create mode 100644 opendc-web/opendc-web-api/opendc/api/topologies.py create mode 100644 opendc-web/opendc-web-api/opendc/api/traces.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/paths.json delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/prefabs/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/scenarios/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/schedulers/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/schedulers/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/schedulers/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/topologies/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/traces/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/traces/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/traces/test_endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/endpoint.py delete mode 100644 opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/test_endpoint.py create mode 100644 opendc-web/opendc-web-api/opendc/auth.py create mode 100644 opendc-web/opendc-web-api/opendc/database.py create mode 100644 opendc-web/opendc-web-api/opendc/exts.py create mode 100644 opendc-web/opendc-web-api/opendc/util.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/__init__.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/auth.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/database.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/exceptions.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/json.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/parameter_checker.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/path_parser.py delete mode 100644 opendc-web/opendc-web-api/opendc/util/rest.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_portfolios.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_prefabs.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_projects.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_scenarios.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_schedulers.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_topologies.py create mode 100644 opendc-web/opendc-web-api/tests/api/test_traces.py diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 2f4d8e7b..d42b0c65 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -10,7 +10,7 @@ services: api: ports: - - "8081:8081" + - "8081:80" environment: SENTRY_ENVIRONMENT: "development" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 3a8c1cba..b0000cd0 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -10,7 +10,7 @@ services: api: ports: - - "8081:8081" + - "8081:80" environment: SENTRY_ENVIRONMENT: "production" diff --git a/opendc-web/opendc-web-api/.pylintrc b/opendc-web/opendc-web-api/.pylintrc index 7fe24187..4dbb0b50 100644 --- a/opendc-web/opendc-web-api/.pylintrc +++ b/opendc-web/opendc-web-api/.pylintrc @@ -65,7 +65,8 @@ disable=duplicate-code, invalid-name, bare-except, too-few-public-methods, - fixme + fixme, + no-self-use # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/opendc-web/opendc-web-api/Dockerfile b/opendc-web/opendc-web-api/Dockerfile index 49702c90..a2f2d787 100644 --- a/opendc-web/opendc-web-api/Dockerfile +++ b/opendc-web/opendc-web-api/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.8 +FROM python:3.8-slim MAINTAINER OpenDC Maintainers # Ensure the STDOUT is not buffered by Python so that our logs become visible @@ -9,9 +9,15 @@ ENV PYTHONUNBUFFERED 1 COPY ./ /opendc # Fetch web server dependencies -RUN pip install -r /opendc/requirements.txt +RUN pip install -r /opendc/requirements.txt && pip install pyuwsgi + +# Create opendc user +RUN groupadd --gid 1000 opendc \ + && useradd --uid 1000 --gid opendc --shell /bin/bash --create-home opendc +RUN chown -R opendc:opendc /opendc +USER opendc # Set working directory WORKDIR /opendc -CMD ["python3", "main.py"] +CMD uwsgi -M --socket 0.0.0.0:80 --protocol=http --wsgi-file app.py --enable-threads --processes 2 --lazy-app diff --git a/opendc-web/opendc-web-api/app.py b/opendc-web/opendc-web-api/app.py index ee4b3d32..5041457f 100755 --- a/opendc-web/opendc-web-api/app.py +++ b/opendc-web/opendc-web-api/app.py @@ -1,25 +1,35 @@ #!/usr/bin/env python3 -import json import os -import sys -import traceback from dotenv import load_dotenv -from flask import Flask, request, jsonify +from flask import Flask, jsonify from flask_compress import Compress from flask_cors import CORS +from flask_restful import Api +from marshmallow import ValidationError -from opendc.util import rest, path_parser, database -from opendc.util.auth import AuthError, AuthManager, AsymmetricJwtAlgorithm -from opendc.util.exceptions import AuthorizationTokenError, RequestInitializationError -from opendc.util.json import JSONEncoder +from opendc.api.portfolios import Portfolio, PortfolioScenarios +from opendc.api.prefabs import Prefab, PrefabList +from opendc.api.projects import ProjectList, Project, ProjectTopologies, ProjectPortfolios +from opendc.api.scenarios import Scenario +from opendc.api.schedulers import SchedulerList +from opendc.api.topologies import Topology +from opendc.api.traces import TraceList, Trace +from opendc.auth import AuthError +from opendc.util import JSONEncoder + +# Load environmental variables from dotenv file load_dotenv() -TEST_MODE = "OPENDC_FLASK_TESTING" in os.environ -# Setup Sentry if DSN is specified -if 'SENTRY_DSN' in os.environ: +def setup_sentry(): + """ + Setup the Sentry integration for Flask if a DSN is supplied via the environmental variables. + """ + if 'SENTRY_DSN' not in os.environ: + return + import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration @@ -28,119 +38,64 @@ if 'SENTRY_DSN' in os.environ: traces_sample_rate=0.1 ) -# Set up database if not testing -if not TEST_MODE: - database.DB.initialize_database( - user=os.environ['OPENDC_DB_USERNAME'], - password=os.environ['OPENDC_DB_PASSWORD'], - database=os.environ['OPENDC_DB'], - host=os.environ.get('OPENDC_DB_HOST', 'localhost')) - -# Set up the core app -app = Flask("opendc") -app.testing = TEST_MODE -app.config['SECRET_KEY'] = os.environ['OPENDC_FLASK_SECRET'] -app.json_encoder = JSONEncoder - -# Set up CORS support -CORS(app) - -compress = Compress() -compress.init_app(app) - -auth = AuthManager(AsymmetricJwtAlgorithm(jwks_url=f"https://{os.environ['AUTH0_DOMAIN']}/.well-known/jwks.json"), - issuer=f"https://{os.environ['AUTH0_DOMAIN']}/", audience=os.environ['AUTH0_AUDIENCE']) - -API_VERSIONS = {'v2'} - - -@app.errorhandler(AuthError) -def handle_auth_error(ex): - response = jsonify(ex.error) - response.status_code = ex.status_code - return response - - -@app.route('//', methods=['GET', 'POST', 'PUT', 'DELETE']) -@auth.require -def api_call(version, endpoint_path): - """Call an API endpoint directly over HTTP.""" - - # Check whether given version is valid - if version not in API_VERSIONS: - return jsonify(error='API version not found'), 404 - - # Get path and parameters - (path, path_parameters) = path_parser.parse(version, endpoint_path) - - query_parameters = request.args.to_dict() - for param in query_parameters: - try: - query_parameters[param] = int(query_parameters[param]) - except: - pass - - try: - body_parameters = json.loads(request.get_data()) - except: - body_parameters = {} - - # Create and call request - (req, response) = _process_message({ - 'id': 0, - 'method': request.method, - 'parameters': { - 'body': body_parameters, - 'path': path_parameters, - 'query': query_parameters - }, - 'path': path, - 'token': request.headers.get('auth-token') - }) - print( - f'HTTP:\t{req.method} to `/{req.path}` resulted in {response.status["code"]}: {response.status["description"]}') - sys.stdout.flush() +def setup_api(app): + """ + Setup the API interface. + """ + api = Api(app) + # Map to ('string', 'ObjectId') passing type and format + api.add_resource(ProjectList, '/projects/') + api.add_resource(Project, '/projects/') + api.add_resource(ProjectTopologies, '/projects//topologies') + api.add_resource(ProjectPortfolios, '/projects//portfolios') + api.add_resource(Topology, '/topologies/') + api.add_resource(PrefabList, '/prefabs/') + api.add_resource(Prefab, '/prefabs/') + api.add_resource(Portfolio, '/portfolios/') + api.add_resource(PortfolioScenarios, '/portfolios//scenarios') + api.add_resource(Scenario, '/scenarios/') + api.add_resource(TraceList, '/traces/') + api.add_resource(Trace, '/traces/') + api.add_resource(SchedulerList, '/schedulers/') - flask_response = jsonify(json.loads(response.to_JSON())) - flask_response.status_code = response.status['code'] - return flask_response + @app.errorhandler(AuthError) + def handle_auth_error(ex): + response = jsonify(ex.error) + response.status_code = ex.status_code + return response + @app.errorhandler(ValidationError) + def handle_validation_error(ex): + return {'message': 'Input validation failed', 'errors': ex.messages}, 400 -def _process_message(message): - """Process a request message and return the response.""" + return api - try: - req = rest.Request(message) - res = req.process() - return req, res +def create_app(testing=False): + app = Flask(__name__) + app.config['TESTING'] = testing + app.config['SECRET_KEY'] = os.environ['OPENDC_FLASK_SECRET'] + app.config['RESTFUL_JSON'] = {'cls': JSONEncoder} + app.json_encoder = JSONEncoder - except AuthorizationTokenError: - res = rest.Response(401, 'Authorization error') - res.id = message['id'] + # Setup Sentry if DSN is specified + setup_sentry() - except RequestInitializationError as e: - res = rest.Response(400, str(e)) - res.id = message['id'] + # Set up CORS support + CORS(app) - if not 'method' in message: - message['method'] = 'UNSPECIFIED' - if not 'path' in message: - message['path'] = 'UNSPECIFIED' + # Setup compression + compress = Compress() + compress.init_app(app) - except Exception: - res = rest.Response(500, 'Internal server error') - if 'id' in message: - res.id = message['id'] - traceback.print_exc() + # Setup API + setup_api(app) - req = rest.Request() - req.method = message['method'] - req.path = message['path'] + return app - return req, res +application = create_app(testing="OPENDC_FLASK_TESTING" in os.environ) if __name__ == '__main__': - app.run() + application.run() diff --git a/opendc-web/opendc-web-api/conftest.py b/opendc-web/opendc-web-api/conftest.py index c502c078..430262f1 100644 --- a/opendc-web/opendc-web-api/conftest.py +++ b/opendc-web/opendc-web-api/conftest.py @@ -4,10 +4,11 @@ Configuration file for all unit tests. from functools import wraps import pytest -from flask import _request_ctx_stack +from flask import _request_ctx_stack, g +from opendc.database import Database -def decorator(self, f): +def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): _request_ctx_stack.top.current_user = {'sub': 'test'} @@ -20,12 +21,14 @@ def client(): """Returns a Flask API client to interact with.""" # Disable authorization for test API endpoints - from opendc.util.auth import AuthManager - AuthManager.require = decorator + from opendc import exts + exts.requires_auth = decorator - from app import app + from app import create_app - app.config['TESTING'] = True + app = create_app(testing=True) - with app.test_client() as client: - yield client + with app.app_context(): + g.db = Database() + with app.test_client() as client: + yield client diff --git a/opendc-web/opendc-web-api/opendc/api/portfolios.py b/opendc-web/opendc-web-api/opendc/api/portfolios.py new file mode 100644 index 00000000..b07e9da5 --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/portfolios.py @@ -0,0 +1,135 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from flask import request +from flask_restful import Resource +from marshmallow import Schema, fields + +from opendc.exts import requires_auth, current_user +from opendc.models.portfolio import Portfolio as PortfolioModel, PortfolioSchema +from opendc.models.project import Project +from opendc.models.scenario import ScenarioSchema, Scenario +from opendc.models.topology import Topology + + +class Portfolio(Resource): + """ + Resource representing a portfolio. + """ + method_decorators = [requires_auth] + + def get(self, portfolio_id): + """ + Get a portfolio by identifier. + """ + portfolio = PortfolioModel.from_id(portfolio_id) + + portfolio.check_exists() + portfolio.check_user_access(current_user['sub'], False) + + data = portfolio.obj + return {'data': data} + + def put(self, portfolio_id): + """ + Replace the portfolio. + """ + schema = Portfolio.PutSchema() + result = schema.load(request.json) + + portfolio = PortfolioModel.from_id(portfolio_id) + portfolio.check_exists() + portfolio.check_user_access(current_user['sub'], True) + + portfolio.set_property('name', result['portfolio']['name']) + portfolio.set_property('targets.enabledMetrics', result['portfolio']['targets']['enabledMetrics']) + portfolio.set_property('targets.repeatsPerScenario', result['portfolio']['targets']['repeatsPerScenario']) + + portfolio.update() + data = portfolio.obj + return {'data': data} + + def delete(self, portfolio_id): + """ + Delete a portfolio. + """ + portfolio = PortfolioModel.from_id(portfolio_id) + + portfolio.check_exists() + portfolio.check_user_access(current_user['sub'], True) + + portfolio_id = portfolio.get_id() + + project = Project.from_id(portfolio.obj['projectId']) + project.check_exists() + if portfolio_id in project.obj['portfolioIds']: + project.obj['portfolioIds'].remove(portfolio_id) + project.update() + + old_object = portfolio.delete() + return {'data': old_object} + + class PutSchema(Schema): + """ + Schema for the PUT operation on a portfolio. + """ + portfolio = fields.Nested(PortfolioSchema, required=True) + + +class PortfolioScenarios(Resource): + """ + Resource representing the scenarios of a portfolio. + """ + method_decorators = [requires_auth] + + def post(self, portfolio_id): + """ + Add a new scenario to this portfolio + """ + schema = PortfolioScenarios.PostSchema() + result = schema.load(request.json) + + portfolio = PortfolioModel.from_id(portfolio_id) + + portfolio.check_exists() + portfolio.check_user_access(current_user['sub'], True) + + scenario = Scenario(result['scenario']) + + topology = Topology.from_id(scenario.obj['topology']['topologyId']) + topology.check_exists() + topology.check_user_access(current_user['sub'], True) + + scenario.set_property('portfolioId', portfolio.get_id()) + scenario.set_property('simulation', {'state': 'QUEUED'}) + scenario.set_property('topology.topologyId', topology.get_id()) + + scenario.insert() + + portfolio.obj['scenarioIds'].append(scenario.get_id()) + portfolio.update() + data = scenario.obj + return {'data': data} + + class PostSchema(Schema): + """ + Schema for the POST operation on a portfolio's scenarios. + """ + scenario = fields.Nested(ScenarioSchema, required=True) diff --git a/opendc-web/opendc-web-api/opendc/api/prefabs.py b/opendc-web/opendc-web-api/opendc/api/prefabs.py new file mode 100644 index 00000000..7bb17e7d --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/prefabs.py @@ -0,0 +1,120 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from datetime import datetime +from flask import request +from flask_restful import Resource +from marshmallow import Schema, fields + +from opendc.models.prefab import Prefab as PrefabModel, PrefabSchema +from opendc.database import Database +from opendc.exts import current_user, requires_auth, db + + +class PrefabList(Resource): + """ + Resource for the list of prefabs available to the user. + """ + method_decorators = [requires_auth] + + def get(self): + """ + Get the available prefabs for a user. + """ + user_id = current_user['sub'] + + own_prefabs = db.fetch_all({'authorId': user_id}, PrefabModel.collection_name) + public_prefabs = db.fetch_all({'visibility': 'public'}, PrefabModel.collection_name) + + authorizations = {"authorizations": []} + authorizations["authorizations"].append(own_prefabs) + authorizations["authorizations"].append(public_prefabs) + return {'data': authorizations} + + def post(self): + """ + Create a new prefab. + """ + schema = PrefabList.PostSchema() + result = schema.load(request.json) + + prefab = PrefabModel(result['prefab']) + prefab.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) + prefab.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + + user_id = current_user['sub'] + prefab.set_property('authorId', user_id) + + prefab.insert() + return {'data': prefab.obj} + + class PostSchema(Schema): + """ + Schema for the POST operation on the prefab list. + """ + prefab = fields.Nested(PrefabSchema, required=True) + + +class Prefab(Resource): + """ + Resource representing a single prefab. + """ + method_decorators = [requires_auth] + + def get(self, prefab_id): + """Get this Prefab.""" + prefab = PrefabModel.from_id(prefab_id) + prefab.check_exists() + prefab.check_user_access(current_user['sub']) + return {'data': prefab.obj} + + def put(self, prefab_id): + """Update a prefab's name and/or contents.""" + + schema = Prefab.PutSchema() + result = schema.load(request.json) + + prefab = PrefabModel.from_id(prefab_id) + prefab.check_exists() + prefab.check_user_access(current_user['sub']) + + prefab.set_property('name', result['prefab']['name']) + prefab.set_property('rack', result['prefab']['rack']) + prefab.set_property('datetime_last_edited', Database.datetime_to_string(datetime.now())) + prefab.update() + + return {'data': prefab.obj} + + def delete(self, prefab_id): + """Delete this Prefab.""" + prefab = PrefabModel.from_id(prefab_id) + + prefab.check_exists() + prefab.check_user_access(current_user['sub']) + + old_object = prefab.delete() + + return {'data': old_object} + + class PutSchema(Schema): + """ + Schema for the PUT operation on a prefab. + """ + prefab = fields.Nested(PrefabSchema, required=True) diff --git a/opendc-web/opendc-web-api/opendc/api/projects.py b/opendc-web/opendc-web-api/opendc/api/projects.py new file mode 100644 index 00000000..8c44b680 --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/projects.py @@ -0,0 +1,195 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from datetime import datetime +from flask import request +from flask_restful import Resource +from marshmallow import Schema, fields + +from opendc.models.portfolio import Portfolio, PortfolioSchema +from opendc.models.topology import Topology, TopologySchema +from opendc.models.project import Project as ProjectModel, ProjectSchema +from opendc.exts import current_user, requires_auth +from opendc.database import Database + + +class ProjectList(Resource): + """ + Resource representing the list of projects available to a user. + """ + method_decorators = [requires_auth] + + def get(self): + """Get the authorized projects of the user""" + user_id = current_user['sub'] + projects = ProjectModel.get_for_user(user_id) + return {'data': projects} + + def post(self): + """Create a new project, and return that new project.""" + user_id = current_user['sub'] + + schema = Project.PutSchema() + result = schema.load(request.json) + + topology = Topology({'name': 'Default topology', 'rooms': []}) + topology.insert() + + project = ProjectModel(result['project']) + project.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) + project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + project.set_property('topologyIds', [topology.get_id()]) + project.set_property('portfolioIds', []) + project.set_property('authorizations', [{'userId': user_id, 'level': 'OWN'}]) + project.insert() + + topology.set_property('projectId', project.get_id()) + topology.update() + + return {'data': project.obj} + + +class Project(Resource): + """ + Resource representing a single project. + """ + method_decorators = [requires_auth] + + def get(self, project_id): + """Get this Project.""" + project = ProjectModel.from_id(project_id) + + project.check_exists() + project.check_user_access(current_user['sub'], False) + + return {'data': project.obj} + + def put(self, project_id): + """Update a project's name.""" + schema = Project.PutSchema() + result = schema.load(request.json) + + project = ProjectModel.from_id(project_id) + + project.check_exists() + project.check_user_access(current_user['sub'], True) + + project.set_property('name', result['project']['name']) + project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + project.update() + + return {'data': project.obj} + + def delete(self, project_id): + """Delete this Project.""" + project = ProjectModel.from_id(project_id) + + project.check_exists() + project.check_user_access(current_user['sub'], True) + + for topology_id in project.obj['topologyIds']: + topology = Topology.from_id(topology_id) + topology.delete() + + for portfolio_id in project.obj['portfolioIds']: + portfolio = Portfolio.from_id(portfolio_id) + portfolio.delete() + + old_object = project.delete() + + return {'data': old_object} + + class PutSchema(Schema): + """ + Schema for the PUT operation on a project. + """ + project = fields.Nested(ProjectSchema, required=True) + + +class ProjectTopologies(Resource): + """ + Resource representing the topologies of a project. + """ + method_decorators = [requires_auth] + + def post(self, project_id): + """Add a new Topology to the specified project and return it""" + schema = ProjectTopologies.PutSchema() + result = schema.load(request.json) + + project = ProjectModel.from_id(project_id) + + project.check_exists() + project.check_user_access(current_user['sub'], True) + + topology = Topology({ + 'projectId': project.get_id(), + 'name': result['topology']['name'], + 'rooms': result['topology']['rooms'], + }) + + topology.insert() + + project.obj['topologyIds'].append(topology.get_id()) + project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + project.update() + + return {'data': topology.obj} + + class PutSchema(Schema): + """ + Schema for the PUT operation on a project topology. + """ + topology = fields.Nested(TopologySchema, required=True) + + +class ProjectPortfolios(Resource): + """ + Resource representing the portfolios of a project. + """ + method_decorators = [requires_auth] + + def post(self, project_id): + """Add a new Portfolio for this Project.""" + schema = ProjectPortfolios.PutSchema() + result = schema.load(request.json) + + project = ProjectModel.from_id(project_id) + + project.check_exists() + project.check_user_access(current_user['sub'], True) + + portfolio = Portfolio(result['portfolio']) + + portfolio.set_property('projectId', project.get_id()) + portfolio.set_property('scenarioIds', []) + + portfolio.insert() + + project.obj['portfolioIds'].append(portfolio.get_id()) + project.update() + + return {'data': portfolio.obj} + + class PutSchema(Schema): + """ + Schema for the PUT operation on a project portfolio. + """ + portfolio = fields.Nested(PortfolioSchema, required=True) diff --git a/opendc-web/opendc-web-api/opendc/api/scenarios.py b/opendc-web/opendc-web-api/opendc/api/scenarios.py new file mode 100644 index 00000000..b566950a --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/scenarios.py @@ -0,0 +1,81 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from flask import request +from flask_restful import Resource +from marshmallow import Schema, fields + +from opendc.models.scenario import Scenario as ScenarioModel, ScenarioSchema +from opendc.models.portfolio import Portfolio +from opendc.exts import current_user, requires_auth + + +class Scenario(Resource): + """ + A Scenario resource. + """ + method_decorators = [requires_auth] + + def get(self, scenario_id): + """Get scenario by identifier.""" + scenario = ScenarioModel.from_id(scenario_id) + scenario.check_exists() + scenario.check_user_access(current_user['sub'], False) + data = scenario.obj + return {'data': data} + + def put(self, scenario_id): + """Update this Scenarios name.""" + schema = Scenario.PutSchema() + result = schema.load(request.json) + + scenario = ScenarioModel.from_id(scenario_id) + + scenario.check_exists() + scenario.check_user_access(current_user['sub'], True) + + scenario.set_property('name', result['scenario']['name']) + + scenario.update() + data = scenario.obj + return {'data': data} + + def delete(self, scenario_id): + """Delete this Scenario.""" + scenario = ScenarioModel.from_id(scenario_id) + scenario.check_exists() + scenario.check_user_access(current_user['sub'], True) + + scenario_id = scenario.get_id() + + portfolio = Portfolio.from_id(scenario.obj['portfolioId']) + portfolio.check_exists() + if scenario_id in portfolio.obj['scenarioIds']: + portfolio.obj['scenarioIds'].remove(scenario_id) + portfolio.update() + + old_object = scenario.delete() + return {'data': old_object} + + class PutSchema(Schema): + """ + Schema for the put operation. + """ + scenario = fields.Nested(ScenarioSchema, required=True) diff --git a/opendc-web/opendc-web-api/opendc/api/schedulers.py b/opendc-web/opendc-web-api/opendc/api/schedulers.py new file mode 100644 index 00000000..b00d8c31 --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/schedulers.py @@ -0,0 +1,46 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +from flask_restful import Resource +from opendc.exts import requires_auth + +SCHEDULERS = [ + 'mem', + 'mem-inv', + 'core-mem', + 'core-mem-inv', + 'active-servers', + 'active-servers-inv', + 'provisioned-cores', + 'provisioned-cores-inv', + 'random' +] + + +class SchedulerList(Resource): + """ + Resource for the list of schedulers to pick from. + """ + method_decorators = [requires_auth] + + def get(self): + """Get all available Traces.""" + return {'data': [{'name': name} for name in SCHEDULERS]} diff --git a/opendc-web/opendc-web-api/opendc/api/topologies.py b/opendc-web/opendc-web-api/opendc/api/topologies.py new file mode 100644 index 00000000..eedf049d --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/topologies.py @@ -0,0 +1,93 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from datetime import datetime + +from flask import request +from flask_restful import Resource +from marshmallow import Schema, fields + +from opendc.database import Database +from opendc.models.project import Project +from opendc.models.topology import Topology as TopologyModel, TopologySchema +from opendc.exts import current_user, requires_auth + + +class Topology(Resource): + """ + Resource representing a single topology. + """ + method_decorators = [requires_auth] + + def get(self, topology_id): + """ + Get a single topology. + """ + topology = TopologyModel.from_id(topology_id) + topology.check_exists() + topology.check_user_access(current_user['sub'], False) + data = topology.obj + return {'data': data} + + def put(self, topology_id): + """ + Replace the topology. + """ + topology = TopologyModel.from_id(topology_id) + + schema = Topology.PutSchema() + result = schema.load(request.json) + + topology.check_exists() + topology.check_user_access(current_user['sub'], True) + + topology.set_property('name', result['topology']['name']) + topology.set_property('rooms', result['topology']['rooms']) + topology.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + + topology.update() + data = topology.obj + return {'data': data} + + def delete(self, topology_id): + """ + Delete a topology. + """ + topology = TopologyModel.from_id(topology_id) + + topology.check_exists() + topology.check_user_access(current_user['sub'], True) + + topology_id = topology.get_id() + + project = Project.from_id(topology.obj['projectId']) + project.check_exists() + if topology_id in project.obj['topologyIds']: + project.obj['topologyIds'].remove(topology_id) + project.update() + + old_object = topology.delete() + return {'data': old_object} + + class PutSchema(Schema): + """ + Schema for the PUT operation on a topology. + """ + topology = fields.Nested(TopologySchema, required=True) diff --git a/opendc-web/opendc-web-api/opendc/api/traces.py b/opendc-web/opendc-web-api/opendc/api/traces.py new file mode 100644 index 00000000..f685f00c --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/api/traces.py @@ -0,0 +1,51 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from flask_restful import Resource + +from opendc.exts import requires_auth +from opendc.models.trace import Trace as TraceModel + + +class TraceList(Resource): + """ + Resource for the list of traces to pick from. + """ + method_decorators = [requires_auth] + + def get(self): + """Get all available Traces.""" + traces = TraceModel.get_all() + data = traces.obj + return {'data': data} + + +class Trace(Resource): + """ + Resource representing a single trace. + """ + method_decorators = [requires_auth] + + def get(self, trace_id): + """Get trace information by identifier.""" + trace = TraceModel.from_id(trace_id) + trace.check_exists() + data = trace.obj + return {'data': data} diff --git a/opendc-web/opendc-web-api/opendc/api/v2/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/paths.json b/opendc-web/opendc-web-api/opendc/api/v2/paths.json deleted file mode 100644 index 652be5bc..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/paths.json +++ /dev/null @@ -1,19 +0,0 @@ -[ - "/users", - "/users/{userId}", - "/projects", - "/projects/{projectId}", - "/projects/{projectId}/authorizations", - "/projects/{projectId}/topologies", - "/projects/{projectId}/portfolios", - "/topologies/{topologyId}", - "/portfolios/{portfolioId}", - "/portfolios/{portfolioId}/scenarios", - "/scenarios/{scenarioId}", - "/schedulers", - "/traces", - "/traces/{traceId}", - "/prefabs", - "/prefabs/{prefabId}", - "/prefabs/authorizations" -] diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py deleted file mode 100644 index c856f4ce..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/endpoint.py +++ /dev/null @@ -1,67 +0,0 @@ -from opendc.models.portfolio import Portfolio -from opendc.models.project import Project -from opendc.util.rest import Response - - -def GET(request): - """Get this Portfolio.""" - - request.check_required_parameters(path={'portfolioId': 'string'}) - - portfolio = Portfolio.from_id(request.params_path['portfolioId']) - - portfolio.check_exists() - portfolio.check_user_access(request.current_user['sub'], False) - - return Response(200, 'Successfully retrieved portfolio.', portfolio.obj) - - -def PUT(request): - """Update this Portfolio.""" - - request.check_required_parameters(path={'portfolioId': 'string'}, body={'portfolio': { - 'name': 'string', - 'targets': { - 'enabledMetrics': 'list', - 'repeatsPerScenario': 'int', - }, - }}) - - portfolio = Portfolio.from_id(request.params_path['portfolioId']) - - portfolio.check_exists() - portfolio.check_user_access(request.current_user['sub'], True) - - portfolio.set_property('name', - request.params_body['portfolio']['name']) - portfolio.set_property('targets.enabledMetrics', - request.params_body['portfolio']['targets']['enabledMetrics']) - portfolio.set_property('targets.repeatsPerScenario', - request.params_body['portfolio']['targets']['repeatsPerScenario']) - - portfolio.update() - - return Response(200, 'Successfully updated portfolio.', portfolio.obj) - - -def DELETE(request): - """Delete this Portfolio.""" - - request.check_required_parameters(path={'portfolioId': 'string'}) - - portfolio = Portfolio.from_id(request.params_path['portfolioId']) - - portfolio.check_exists() - portfolio.check_user_access(request.current_user['sub'], True) - - portfolio_id = portfolio.get_id() - - project = Project.from_id(portfolio.obj['projectId']) - project.check_exists() - if portfolio_id in project.obj['portfolioIds']: - project.obj['portfolioIds'].remove(portfolio_id) - project.update() - - old_object = portfolio.delete() - - return Response(200, 'Successfully deleted portfolio.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py deleted file mode 100644 index b12afce3..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py +++ /dev/null @@ -1,49 +0,0 @@ -from opendc.models.portfolio import Portfolio -from opendc.models.scenario import Scenario -from opendc.models.topology import Topology -from opendc.util.rest import Response - - -def POST(request): - """Add a new Scenario for this Portfolio.""" - - request.check_required_parameters(path={'portfolioId': 'string'}, - body={ - 'scenario': { - 'name': 'string', - 'trace': { - 'traceId': 'string', - 'loadSamplingFraction': 'float', - }, - 'topology': { - 'topologyId': 'string', - }, - 'operational': { - 'failuresEnabled': 'bool', - 'performanceInterferenceEnabled': 'bool', - 'schedulerName': 'string', - }, - } - }) - - portfolio = Portfolio.from_id(request.params_path['portfolioId']) - - portfolio.check_exists() - portfolio.check_user_access(request.current_user['sub'], True) - - scenario = Scenario(request.params_body['scenario']) - - topology = Topology.from_id(scenario.obj['topology']['topologyId']) - topology.check_exists() - topology.check_user_access(request.current_user['sub'], True) - - scenario.set_property('portfolioId', portfolio.get_id()) - scenario.set_property('simulation', {'state': 'QUEUED'}) - scenario.set_property('topology.topologyId', topology.get_id()) - - scenario.insert() - - portfolio.obj['scenarioIds'].append(scenario.get_id()) - portfolio.update() - - return Response(200, 'Successfully added Scenario.', scenario.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py deleted file mode 100644 index ff1666c0..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py +++ /dev/null @@ -1,125 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_add_scenario_missing_parameter(client): - assert '400' in client.post('/v2/portfolios/1/scenarios').status - - -def test_add_scenario_non_existing_portfolio(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.post(f'/v2/portfolios/{test_id}/scenarios', - json={ - 'scenario': { - 'name': 'test', - 'trace': { - 'traceId': test_id, - 'loadSamplingFraction': 1.0, - }, - 'topology': { - 'topologyId': test_id, - }, - 'operational': { - 'failuresEnabled': True, - 'performanceInterferenceEnabled': False, - 'schedulerName': 'DEFAULT', - }, - } - }).status - - -def test_add_scenario_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }] - }) - assert '403' in client.post(f'/v2/portfolios/{test_id}/scenarios', - json={ - 'scenario': { - 'name': 'test', - 'trace': { - 'traceId': test_id, - 'loadSamplingFraction': 1.0, - }, - 'topology': { - 'topologyId': test_id, - }, - 'operational': { - 'failuresEnabled': True, - 'performanceInterferenceEnabled': False, - 'schedulerName': 'DEFAULT', - }, - } - }).status - - -def test_add_scenario(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioId': test_id, - 'portfolioIds': [test_id], - 'scenarioIds': [test_id], - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'EDIT' - }], - 'simulation': { - 'state': 'QUEUED', - }, - }) - mocker.patch.object(DB, - 'insert', - return_value={ - '_id': test_id, - 'name': 'test', - 'trace': { - 'traceId': test_id, - 'loadSamplingFraction': 1.0, - }, - 'topology': { - 'topologyId': test_id, - }, - 'operational': { - 'failuresEnabled': True, - 'performanceInterferenceEnabled': False, - 'schedulerName': 'DEFAULT', - }, - 'portfolioId': test_id, - 'simulationState': { - 'state': 'QUEUED', - }, - }) - mocker.patch.object(DB, 'update', return_value=None) - res = client.post( - f'/v2/portfolios/{test_id}/scenarios', - json={ - 'scenario': { - 'name': 'test', - 'trace': { - 'traceId': test_id, - 'loadSamplingFraction': 1.0, - }, - 'topology': { - 'topologyId': test_id, - }, - 'operational': { - 'failuresEnabled': True, - 'performanceInterferenceEnabled': False, - 'schedulerName': 'DEFAULT', - }, - } - }) - assert 'portfolioId' in res.json['content'] - assert 'simulation' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py deleted file mode 100644 index 1a44c63d..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py +++ /dev/null @@ -1,149 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' -test_id_2 = 24 * '2' - - -def test_get_portfolio_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get(f'/v2/portfolios/{test_id}').status - - -def test_get_portfolio_no_authorizations(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'projectId': test_id, 'authorizations': []}) - res = client.get(f'/v2/portfolios/{test_id}') - assert '403' in res.status - - -def test_get_portfolio_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - 'projectId': test_id, - '_id': test_id, - 'authorizations': [] - }) - res = client.get(f'/v2/portfolios/{test_id}') - assert '403' in res.status - - -def test_get_portfolio(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - 'projectId': test_id, - '_id': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'EDIT' - }] - }) - res = client.get(f'/v2/portfolios/{test_id}') - assert '200' in res.status - - -def test_update_portfolio_missing_parameter(client): - assert '400' in client.put(f'/v2/portfolios/{test_id}').status - - -def test_update_portfolio_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put(f'/v2/portfolios/{test_id}', json={ - 'portfolio': { - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - } - } - }).status - - -def test_update_portfolio_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }] - }) - mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put(f'/v2/portfolios/{test_id}', json={ - 'portfolio': { - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - } - } - }).status - - -def test_update_portfolio(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }], - 'targets': { - 'enabledMetrics': [], - 'repeatsPerScenario': 1 - } - }) - mocker.patch.object(DB, 'update', return_value={}) - - res = client.put(f'/v2/portfolios/{test_id}', json={'portfolio': { - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - } - }}) - assert '200' in res.status - - -def test_delete_project_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete(f'/v2/portfolios/{test_id}').status - - -def test_delete_project_different_user(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'googleId': 'other_test', - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }] - }) - mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete(f'/v2/portfolios/{test_id}').status - - -def test_delete_project(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'googleId': 'test', - 'portfolioIds': [test_id], - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'delete_one', return_value={}) - mocker.patch.object(DB, 'update', return_value=None) - res = client.delete(f'/v2/portfolios/{test_id}') - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py deleted file mode 100644 index 5a8d367f..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py +++ /dev/null @@ -1,19 +0,0 @@ -from opendc.models.prefab import Prefab -from opendc.util.database import DB -from opendc.util.rest import Response - - -def GET(request): - """Return all prefabs the user is authorized to access""" - - user_id = request.current_user['sub'] - - own_prefabs = DB.fetch_all({'authorId': user_id}, Prefab.collection_name) - public_prefabs = DB.fetch_all({'visibility': 'public'}, Prefab.collection_name) - - authorizations = {"authorizations": []} - - authorizations["authorizations"].append(own_prefabs) - authorizations["authorizations"].append(public_prefabs) - - return Response(200, 'Successfully fetched authorizations.', authorizations) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/test_endpoint.py deleted file mode 100644 index 6d36d428..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/test_endpoint.py +++ /dev/null @@ -1,71 +0,0 @@ -from opendc.util.database import DB -from unittest.mock import Mock - -test_id = 24 * '1' - - -def test_get_authorizations(client, mocker): - DB.fetch_all = Mock() - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id}) - DB.fetch_all.side_effect = [ - [{ - '_id': test_id, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': test_id, - 'visibility' : 'private' - }, - { - '_id': '2' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': test_id, - 'visibility' : 'private' - }, - { - '_id': '3' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': test_id, - 'visibility' : 'public' - }, - { - '_id': '4' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': test_id, - 'visibility' : 'public' - }], - [{ - '_id': '5' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': '2' * 24, - 'visibility' : 'public' - }, - { - '_id': '6' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': '2' * 24, - 'visibility' : 'public' - }, - { - '_id': '7' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': '2' * 24, - 'visibility' : 'public' - }, - { - '_id': '8' * 24, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': '2' * 24, - 'visibility' : 'public' - }] - ] - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id}) - res = client.get('/v2/prefabs/authorizations') - assert '200' in res.status - diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py deleted file mode 100644 index 4a30f7eb..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py +++ /dev/null @@ -1,22 +0,0 @@ -from datetime import datetime - -from opendc.models.prefab import Prefab -from opendc.util.database import Database -from opendc.util.rest import Response - - -def POST(request): - """Create a new prefab, and return that new prefab.""" - - request.check_required_parameters(body={'prefab': {'name': 'string'}}) - - prefab = Prefab(request.params_body['prefab']) - prefab.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) - prefab.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) - - user_id = request.current_user['sub'] - prefab.set_property('authorId', user_id) - - prefab.insert() - - return Response(200, 'Successfully created prefab.', prefab.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py deleted file mode 100644 index f1cf1fcd..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/endpoint.py +++ /dev/null @@ -1,50 +0,0 @@ -from datetime import datetime - -from opendc.models.prefab import Prefab -from opendc.util.database import Database -from opendc.util.rest import Response - - -def GET(request): - """Get this Prefab.""" - - request.check_required_parameters(path={'prefabId': 'string'}) - - prefab = Prefab.from_id(request.params_path['prefabId']) - prefab.check_exists() - prefab.check_user_access(request.current_user['sub']) - - return Response(200, 'Successfully retrieved prefab', prefab.obj) - - -def PUT(request): - """Update a prefab's name and/or contents.""" - - request.check_required_parameters(body={'prefab': {'name': 'name'}}, path={'prefabId': 'string'}) - - prefab = Prefab.from_id(request.params_path['prefabId']) - - prefab.check_exists() - prefab.check_user_access(request.current_user['sub']) - - prefab.set_property('name', request.params_body['prefab']['name']) - prefab.set_property('rack', request.params_body['prefab']['rack']) - prefab.set_property('datetime_last_edited', Database.datetime_to_string(datetime.now())) - prefab.update() - - return Response(200, 'Successfully updated prefab.', prefab.obj) - - -def DELETE(request): - """Delete this Prefab.""" - - request.check_required_parameters(path={'prefabId': 'string'}) - - prefab = Prefab.from_id(request.params_path['prefabId']) - - prefab.check_exists() - prefab.check_user_access(request.current_user['sub']) - - old_object = prefab.delete() - - return Response(200, 'Successfully deleted prefab.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py deleted file mode 100644 index bc3b1a32..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py +++ /dev/null @@ -1,145 +0,0 @@ -from opendc.util.database import DB -from unittest.mock import Mock - -test_id = 24 * '1' -test_id_2 = 24 * '2' - - -def test_get_prefab_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get(f'/v2/prefabs/{test_id}').status - - -def test_get_private_prefab_not_authorized(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': test_id_2, - 'visibility': 'private', - 'rack': {} - }, - { - '_id': test_id - } - ] - res = client.get(f'/v2/prefabs/{test_id}') - assert '403' in res.status - - -def test_get_private_prefab(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': 'test', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': test_id - } - ] - res = client.get(f'/v2/prefabs/{test_id}') - assert '200' in res.status - - -def test_get_public_prefab(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': test_id_2, - 'visibility': 'public', - 'rack': {} - }, - { - '_id': test_id - } - ] - res = client.get(f'/v2/prefabs/{test_id}') - assert '200' in res.status - - -def test_update_prefab_missing_parameter(client): - assert '400' in client.put(f'/v2/prefabs/{test_id}').status - - -def test_update_prefab_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put(f'/v2/prefabs/{test_id}', json={'prefab': {'name': 'S'}}).status - - -def test_update_prefab_not_authorized(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': test_id_2, - 'visibility': 'private', - 'rack': {} - }, - { - '_id': test_id - } - ] - mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put(f'/v2/prefabs/{test_id}', json={'prefab': {'name': 'test prefab', 'rack': {}}}).status - - -def test_update_prefab(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': 'test', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': test_id - } - ] - mocker.patch.object(DB, 'update', return_value={}) - res = client.put(f'/v2/prefabs/{test_id}', json={'prefab': {'name': 'test prefab', 'rack': {}}}) - assert '200' in res.status - - -def test_delete_prefab_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete(f'/v2/prefabs/{test_id}').status - - -def test_delete_prefab_different_user(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': test_id_2, - 'visibility': 'private', - 'rack': {} - }, - { - '_id': test_id - } - ] - mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete(f'/v2/prefabs/{test_id}').status - - -def test_delete_prefab(client, mocker): - DB.fetch_one = Mock() - DB.fetch_one.side_effect = [{ - '_id': test_id, - 'name': 'test prefab', - 'authorId': 'test', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': test_id - } - ] - mocker.patch.object(DB, 'delete_one', return_value={'prefab': {'name': 'name'}}) - res = client.delete(f'/v2/prefabs/{test_id}') - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/test_endpoint.py deleted file mode 100644 index 39a78c21..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/test_endpoint.py +++ /dev/null @@ -1,24 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_add_prefab_missing_parameter(client): - assert '400' in client.post('/v2/prefabs').status - - -def test_add_prefab(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'authorizations': []}) - mocker.patch.object(DB, - 'insert', - return_value={ - '_id': test_id, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'authorId': test_id - }) - res = client.post('/v2/prefabs', json={'prefab': {'name': 'test prefab'}}) - assert 'datetimeCreated' in res.json['content'] - assert 'datetimeLastEdited' in res.json['content'] - assert 'authorId' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py deleted file mode 100644 index b381d689..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py +++ /dev/null @@ -1,36 +0,0 @@ -from datetime import datetime - -from opendc.models.project import Project -from opendc.models.topology import Topology -from opendc.util.database import Database -from opendc.util.rest import Response - - -def GET(request): - """Get the authorized projects of the user""" - user_id = request.current_user['sub'] - projects = Project.get_for_user(user_id) - return Response(200, 'Successfully retrieved projects', projects) - - -def POST(request): - """Create a new project, and return that new project.""" - - request.check_required_parameters(body={'project': {'name': 'string'}}) - user_id = request.current_user['sub'] - - topology = Topology({'name': 'Default topology', 'rooms': []}) - topology.insert() - - project = Project(request.params_body['project']) - project.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) - project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) - project.set_property('topologyIds', [topology.get_id()]) - project.set_property('portfolioIds', []) - project.set_property('authorizations', [{'userId': user_id, 'authorizationLevel': 'OWN'}]) - project.insert() - - topology.set_property('projectId', project.get_id()) - topology.update() - - return Response(200, 'Successfully created project.', project.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py deleted file mode 100644 index fa53ce6b..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py +++ /dev/null @@ -1,60 +0,0 @@ -from datetime import datetime - -from opendc.models.portfolio import Portfolio -from opendc.models.project import Project -from opendc.models.topology import Topology -from opendc.util.database import Database -from opendc.util.rest import Response - - -def GET(request): - """Get this Project.""" - - request.check_required_parameters(path={'projectId': 'string'}) - - project = Project.from_id(request.params_path['projectId']) - - project.check_exists() - project.check_user_access(request.current_user['sub'], False) - - return Response(200, 'Successfully retrieved project', project.obj) - - -def PUT(request): - """Update a project's name.""" - - request.check_required_parameters(body={'project': {'name': 'name'}}, path={'projectId': 'string'}) - - project = Project.from_id(request.params_path['projectId']) - - project.check_exists() - project.check_user_access(request.current_user['sub'], True) - - project.set_property('name', request.params_body['project']['name']) - project.set_property('datetime_last_edited', Database.datetime_to_string(datetime.now())) - project.update() - - return Response(200, 'Successfully updated project.', project.obj) - - -def DELETE(request): - """Delete this Project.""" - - request.check_required_parameters(path={'projectId': 'string'}) - - project = Project.from_id(request.params_path['projectId']) - - project.check_exists() - project.check_user_access(request.current_user['sub'], True) - - for topology_id in project.obj['topologyIds']: - topology = Topology.from_id(topology_id) - topology.delete() - - for portfolio_id in project.obj['portfolioIds']: - portfolio = Portfolio.from_id(portfolio_id) - portfolio.delete() - - old_object = project.delete() - - return Response(200, 'Successfully deleted project.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py deleted file mode 100644 index 18b4d007..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/endpoint.py +++ /dev/null @@ -1,35 +0,0 @@ -from opendc.models.portfolio import Portfolio -from opendc.models.project import Project -from opendc.util.rest import Response - - -def POST(request): - """Add a new Portfolio for this Project.""" - - request.check_required_parameters(path={'projectId': 'string'}, - body={ - 'portfolio': { - 'name': 'string', - 'targets': { - 'enabledMetrics': 'list', - 'repeatsPerScenario': 'int', - }, - } - }) - - project = Project.from_id(request.params_path['projectId']) - - project.check_exists() - project.check_user_access(request.current_user['sub'], True) - - portfolio = Portfolio(request.params_body['portfolio']) - - portfolio.set_property('projectId', project.get_id()) - portfolio.set_property('scenarioIds', []) - - portfolio.insert() - - project.obj['portfolioIds'].append(portfolio.get_id()) - project.update() - - return Response(200, 'Successfully added Portfolio.', portfolio.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py deleted file mode 100644 index 7ddfe0ce..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py +++ /dev/null @@ -1,85 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_add_portfolio_missing_parameter(client): - assert '400' in client.post(f'/v2/projects/{test_id}/portfolios').status - - -def test_add_portfolio_non_existing_project(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.post(f'/v2/projects/{test_id}/portfolios', - json={ - 'portfolio': { - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - } - } - }).status - - -def test_add_portfolio_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }] - }) - assert '403' in client.post(f'/v2/projects/{test_id}/portfolios', - json={ - 'portfolio': { - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - } - } - }).status - - -def test_add_portfolio(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioIds': [test_id], - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'EDIT' - }] - }) - mocker.patch.object(DB, - 'insert', - return_value={ - '_id': test_id, - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - }, - 'projectId': test_id, - 'scenarioIds': [], - }) - mocker.patch.object(DB, 'update', return_value=None) - res = client.post( - f'/v2/projects/{test_id}/portfolios', - json={ - 'portfolio': { - 'name': 'test', - 'targets': { - 'enabledMetrics': ['test'], - 'repeatsPerScenario': 2 - } - } - }) - assert 'projectId' in res.json['content'] - assert 'scenarioIds' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py deleted file mode 100644 index 03e6758b..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py +++ /dev/null @@ -1,119 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' -test_id_2 = 24 * '2' - - -def test_get_project_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get(f'/v2/projects/{test_id}').status - - -def test_get_project_no_authorizations(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'authorizations': []}) - res = client.get(f'/v2/projects/{test_id}') - assert '403' in res.status - - -def test_get_project_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'authorizations': [] - }) - res = client.get(f'/v2/projects/{test_id}') - assert '403' in res.status - - -def test_get_project(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'EDIT' - }] - }) - res = client.get(f'/v2/projects/{test_id}') - assert '200' in res.status - - -def test_update_project_missing_parameter(client): - assert '400' in client.put(f'/v2/projects/{test_id}').status - - -def test_update_project_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put(f'/v2/projects/{test_id}', json={'project': {'name': 'S'}}).status - - -def test_update_project_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }] - }) - mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put(f'/v2/projects/{test_id}', json={'project': {'name': 'S'}}).status - - -def test_update_project(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'update', return_value={}) - - res = client.put(f'/v2/projects/{test_id}', json={'project': {'name': 'S'}}) - assert '200' in res.status - - -def test_delete_project_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete(f'/v2/projects/{test_id}').status - - -def test_delete_project_different_user(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'googleId': 'other_test', - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }], - 'topologyIds': [] - }) - mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete(f'/v2/projects/{test_id}').status - - -def test_delete_project(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'googleId': 'test', - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }], - 'topologyIds': [], - 'portfolioIds': [], - }) - mocker.patch.object(DB, 'update', return_value=None) - mocker.patch.object(DB, 'delete_one', return_value={'googleId': 'test'}) - res = client.delete(f'/v2/projects/{test_id}') - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py deleted file mode 100644 index 47f2a207..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/endpoint.py +++ /dev/null @@ -1,31 +0,0 @@ -from datetime import datetime - -from opendc.models.project import Project -from opendc.models.topology import Topology -from opendc.util.rest import Response -from opendc.util.database import Database - - -def POST(request): - """Add a new Topology to the specified project and return it""" - - request.check_required_parameters(path={'projectId': 'string'}, body={'topology': {'name': 'string'}}) - - project = Project.from_id(request.params_path['projectId']) - - project.check_exists() - project.check_user_access(request.current_user['sub'], True) - - topology = Topology({ - 'projectId': project.get_id(), - 'name': request.params_body['topology']['name'], - 'rooms': request.params_body['topology']['rooms'], - }) - - topology.insert() - - project.obj['topologyIds'].append(topology.get_id()) - project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) - project.update() - - return Response(200, 'Successfully inserted topology.', topology.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py deleted file mode 100644 index 2e872415..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py +++ /dev/null @@ -1,52 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_add_topology_missing_parameter(client): - assert '400' in client.post(f'/v2/projects/{test_id}/topologies').status - - -def test_add_topology(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }], - 'topologyIds': [] - }) - mocker.patch.object(DB, - 'insert', - return_value={ - '_id': test_id, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'topologyIds': [] - }) - mocker.patch.object(DB, 'update', return_value={}) - res = client.post(f'/v2/projects/{test_id}/topologies', json={'topology': {'name': 'test project', 'rooms': []}}) - assert 'rooms' in res.json['content'] - assert '200' in res.status - - -def test_add_topology_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'VIEW' - }] - }) - assert '403' in client.post(f'/v2/projects/{test_id}/topologies', - json={ - 'topology': { - 'name': 'test_topology', - 'rooms': {} - } - }).status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py deleted file mode 100644 index db768f28..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py +++ /dev/null @@ -1,32 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_get_user_projects(client, mocker): - mocker.patch.object(DB, 'fetch_all', return_value={'_id': test_id, 'authorizations': [{'userId': 'test', - 'authorizationLevel': 'OWN'}]}) - res = client.get('/v2/projects') - assert '200' in res.status - - -def test_add_project_missing_parameter(client): - assert '400' in client.post('/v2/projects').status - - -def test_add_project(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'authorizations': []}) - mocker.patch.object(DB, - 'insert', - return_value={ - '_id': test_id, - 'datetimeCreated': '000', - 'datetimeLastEdited': '000', - 'topologyIds': [] - }) - mocker.patch.object(DB, 'update', return_value={}) - res = client.post('/v2/projects', json={'project': {'name': 'test project'}}) - assert 'datetimeCreated' in res.json['content'] - assert 'datetimeLastEdited' in res.json['content'] - assert 'topologyIds' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py deleted file mode 100644 index 7399f98c..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py +++ /dev/null @@ -1,59 +0,0 @@ -from opendc.models.scenario import Scenario -from opendc.models.portfolio import Portfolio -from opendc.util.rest import Response - - -def GET(request): - """Get this Scenario.""" - - request.check_required_parameters(path={'scenarioId': 'string'}) - - scenario = Scenario.from_id(request.params_path['scenarioId']) - - scenario.check_exists() - scenario.check_user_access(request.current_user['sub'], False) - - return Response(200, 'Successfully retrieved scenario.', scenario.obj) - - -def PUT(request): - """Update this Scenarios name.""" - - request.check_required_parameters(path={'scenarioId': 'string'}, body={'scenario': { - 'name': 'string', - }}) - - scenario = Scenario.from_id(request.params_path['scenarioId']) - - scenario.check_exists() - scenario.check_user_access(request.current_user['sub'], True) - - scenario.set_property('name', - request.params_body['scenario']['name']) - - scenario.update() - - return Response(200, 'Successfully updated scenario.', scenario.obj) - - -def DELETE(request): - """Delete this Scenario.""" - - request.check_required_parameters(path={'scenarioId': 'string'}) - - scenario = Scenario.from_id(request.params_path['scenarioId']) - - scenario.check_exists() - scenario.check_user_access(request.current_user['sub'], True) - - scenario_id = scenario.get_id() - - portfolio = Portfolio.from_id(scenario.obj['portfolioId']) - portfolio.check_exists() - if scenario_id in portfolio.obj['scenarioIds']: - portfolio.obj['scenarioIds'].remove(scenario_id) - portfolio.update() - - old_object = scenario.delete() - - return Response(200, 'Successfully deleted scenario.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py deleted file mode 100644 index 24b38671..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py +++ /dev/null @@ -1,115 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' -test_id_2 = 24 * '2' - - -def test_get_scenario_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get(f'/v2/scenarios/{test_id}').status - - -def test_get_scenario_no_authorizations(client, mocker): - m = mocker.MagicMock() - m.side_effect = ({'portfolioId': test_id}, {'projectId': test_id}, {'authorizations': []}) - mocker.patch.object(DB, 'fetch_one', m) - res = client.get(f'/v2/scenarios/{test_id}') - assert '403' in res.status - - -def test_get_scenario(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - side_effect=[ - {'portfolioId': test_id}, - {'projectId': test_id}, - {'authorizations': - [{'userId': 'test', 'authorizationLevel': 'OWN'}] - }]) - res = client.get(f'/v2/scenarios/{test_id}') - assert '200' in res.status - - -def test_update_scenario_missing_parameter(client): - assert '400' in client.put(f'/v2/scenarios/{test_id}').status - - -def test_update_scenario_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put(f'/v2/scenarios/{test_id}', json={ - 'scenario': { - 'name': 'test', - } - }).status - - -def test_update_scenario_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - side_effect=[ - {'portfolioId': test_id}, - {'projectId': test_id}, - {'authorizations': - [{'userId': 'test', 'authorizationLevel': 'VIEW'}] - }]) - mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put(f'/v2/scenarios/{test_id}', json={ - 'scenario': { - 'name': 'test', - } - }).status - - -def test_update_scenario(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - side_effect=[ - {'_id': test_id, 'portfolioId': test_id}, - {'projectId': test_id}, - {'authorizations': - [{'userId': 'test', 'authorizationLevel': 'OWN'}] - }]) - mocker.patch.object(DB, 'update', return_value={}) - - res = client.put(f'/v2/scenarios/{test_id}', json={'scenario': { - 'name': 'test', - }}) - assert '200' in res.status - - -def test_delete_project_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete(f'/v2/scenarios/{test_id}').status - - -def test_delete_project_different_user(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - side_effect=[ - {'_id': test_id, 'portfolioId': test_id}, - {'projectId': test_id}, - {'authorizations': - [{'userId': 'test', 'authorizationLevel': 'VIEW'}] - }]) - mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete(f'/v2/scenarios/{test_id}').status - - -def test_delete_project(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'portfolioId': test_id, - 'googleId': 'test', - 'scenarioIds': [test_id], - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'delete_one', return_value={}) - mocker.patch.object(DB, 'update', return_value=None) - res = client.delete(f'/v2/scenarios/{test_id}') - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/schedulers/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/schedulers/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/schedulers/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/schedulers/endpoint.py deleted file mode 100644 index f33159bf..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/schedulers/endpoint.py +++ /dev/null @@ -1,19 +0,0 @@ -from opendc.util.rest import Response - -SCHEDULERS = [ - 'mem', - 'mem-inv', - 'core-mem', - 'core-mem-inv', - 'active-servers', - 'active-servers-inv', - 'provisioned-cores', - 'provisioned-cores-inv', - 'random' -] - - -def GET(_): - """Get all available Schedulers.""" - - return Response(200, 'Successfully retrieved Schedulers.', [{'name': name} for name in SCHEDULERS]) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/schedulers/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/schedulers/test_endpoint.py deleted file mode 100644 index 4950ca4c..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/schedulers/test_endpoint.py +++ /dev/null @@ -1,2 +0,0 @@ -def test_get_schedulers(client): - assert '200' in client.get('/v2/schedulers').status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py deleted file mode 100644 index 80618190..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/endpoint.py +++ /dev/null @@ -1,58 +0,0 @@ -from datetime import datetime - -from opendc.util.database import Database -from opendc.models.project import Project -from opendc.models.topology import Topology -from opendc.util.rest import Response - - -def GET(request): - """Get this Topology.""" - - request.check_required_parameters(path={'topologyId': 'string'}) - - topology = Topology.from_id(request.params_path['topologyId']) - - topology.check_exists() - topology.check_user_access(request.current_user['sub'], False) - - return Response(200, 'Successfully retrieved topology.', topology.obj) - - -def PUT(request): - """Update this topology""" - request.check_required_parameters(path={'topologyId': 'string'}, body={'topology': {'name': 'string', 'rooms': {}}}) - topology = Topology.from_id(request.params_path['topologyId']) - - topology.check_exists() - topology.check_user_access(request.current_user['sub'], True) - - topology.set_property('name', request.params_body['topology']['name']) - topology.set_property('rooms', request.params_body['topology']['rooms']) - topology.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) - - topology.update() - - return Response(200, 'Successfully updated topology.', topology.obj) - - -def DELETE(request): - """Delete this topology""" - request.check_required_parameters(path={'topologyId': 'string'}) - - topology = Topology.from_id(request.params_path['topologyId']) - - topology.check_exists() - topology.check_user_access(request.current_user['sub'], True) - - topology_id = topology.get_id() - - project = Project.from_id(topology.obj['projectId']) - project.check_exists() - if topology_id in project.obj['topologyIds']: - project.obj['topologyIds'].remove(topology_id) - project.update() - - old_object = topology.delete() - - return Response(200, 'Successfully deleted topology.', old_object) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py deleted file mode 100644 index 96d2e08e..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py +++ /dev/null @@ -1,113 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' -test_id_2 = 24 * '2' - - -def test_get_topology(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'EDIT' - }] - }) - res = client.get(f'/v2/topologies/{test_id}') - assert '200' in res.status - - -def test_get_topology_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/v2/topologies/1').status - - -def test_get_topology_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [] - }) - res = client.get(f'/v2/topologies/{test_id}') - assert '403' in res.status - - -def test_get_topology_no_authorizations(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'projectId': test_id, 'authorizations': []}) - res = client.get(f'/v2/topologies/{test_id}') - assert '403' in res.status - - -def test_update_topology_missing_parameter(client): - assert '400' in client.put(f'/v2/topologies/{test_id}').status - - -def test_update_topology_non_existent(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put(f'/v2/topologies/{test_id}', json={'topology': {'name': 'test_topology', 'rooms': {}}}).status - - -def test_update_topology_not_authorized(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [] - }) - mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put(f'/v2/topologies/{test_id}', json={ - 'topology': { - 'name': 'updated_topology', - 'rooms': {} - } - }).status - - -def test_update_topology(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'update', return_value={}) - - assert '200' in client.put(f'/v2/topologies/{test_id}', json={ - 'topology': { - 'name': 'updated_topology', - 'rooms': {} - } - }).status - - -def test_delete_topology(client, mocker): - mocker.patch.object(DB, - 'fetch_one', - return_value={ - '_id': test_id, - 'projectId': test_id, - 'googleId': 'test', - 'topologyIds': [test_id], - 'authorizations': [{ - 'userId': 'test', - 'authorizationLevel': 'OWN' - }] - }) - mocker.patch.object(DB, 'delete_one', return_value={}) - mocker.patch.object(DB, 'update', return_value=None) - res = client.delete(f'/v2/topologies/{test_id}') - assert '200' in res.status - - -def test_delete_nonexistent_topology(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete(f'/v2/topologies/{test_id}').status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/traces/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/traces/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/traces/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/traces/endpoint.py deleted file mode 100644 index ee699e02..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/traces/endpoint.py +++ /dev/null @@ -1,10 +0,0 @@ -from opendc.models.trace import Trace -from opendc.util.rest import Response - - -def GET(_): - """Get all available Traces.""" - - traces = Trace.get_all() - - return Response(200, 'Successfully retrieved Traces', traces.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/traces/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/traces/test_endpoint.py deleted file mode 100644 index 36846bd9..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/traces/test_endpoint.py +++ /dev/null @@ -1,6 +0,0 @@ -from opendc.util.database import DB - - -def test_get_traces(client, mocker): - mocker.patch.object(DB, 'fetch_all', return_value=[]) - assert '200' in client.get('/v2/traces').status diff --git a/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/endpoint.py deleted file mode 100644 index 670f88d1..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/endpoint.py +++ /dev/null @@ -1,14 +0,0 @@ -from opendc.models.trace import Trace -from opendc.util.rest import Response - - -def GET(request): - """Get this Trace.""" - - request.check_required_parameters(path={'traceId': 'string'}) - - trace = Trace.from_id(request.params_path['traceId']) - - trace.check_exists() - - return Response(200, 'Successfully retrieved trace.', trace.obj) diff --git a/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/test_endpoint.py deleted file mode 100644 index 0c51538b..00000000 --- a/opendc-web/opendc-web-api/opendc/api/v2/traces/traceId/test_endpoint.py +++ /dev/null @@ -1,15 +0,0 @@ -from opendc.util.database import DB - -test_id = 24 * '1' - - -def test_get_trace_non_existing(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get(f'/v2/traces/{test_id}').status - - -def test_get_trace(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'name': 'test trace'}) - res = client.get(f'/v2/traces/{test_id}') - assert 'name' in res.json['content'] - assert '200' in res.status diff --git a/opendc-web/opendc-web-api/opendc/auth.py b/opendc-web/opendc-web-api/opendc/auth.py new file mode 100644 index 00000000..1870f01c --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/auth.py @@ -0,0 +1,240 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import json +import time + +import urllib3 +from flask import request +from jose import jwt, JWTError + + +def get_token(): + """ + Obtain the Access Token from the Authorization Header + """ + auth = request.headers.get("Authorization", None) + if not auth: + raise AuthError({ + "code": "authorization_header_missing", + "description": "Authorization header is expected" + }, 401) + + parts = auth.split() + + if parts[0].lower() != "bearer": + raise AuthError({ + "code": "invalid_header", + "description": "Authorization header must start with" + " Bearer" + }, 401) + if len(parts) == 1: + raise AuthError({"code": "invalid_header", "description": "Token not found"}, 401) + if len(parts) > 2: + raise AuthError({"code": "invalid_header", "description": "Authorization header must be" " Bearer token"}, 401) + + token = parts[1] + return token + + +class AuthError(Exception): + """ + This error is thrown when the request failed to authorize. + """ + def __init__(self, error, status_code): + Exception.__init__(self, error) + self.error = error + self.status_code = status_code + + +class AuthContext: + """ + This class handles the authorization of requests. + """ + def __init__(self, alg, issuer, audience): + self._alg = alg + self._issuer = issuer + self._audience = audience + + def validate(self, token): + """ + Validate the specified JWT token. + :param token: The authorization token specified by the user. + :return: The token payload on success, otherwise `AuthError`. + """ + try: + header = jwt.get_unverified_header(token) + except JWTError as e: + raise AuthError({"code": "invalid_token", "message": str(e)}, 401) + + alg = header.get('alg', None) + if alg != self._alg.algorithm: + raise AuthError( + { + "code": + "invalid_header", + "message": + f"Signature algorithm of {alg} is not supported. Expected the ID token " + f"to be signed with {self._alg.algorithm}" + }, 401) + + kid = header.get('kid', None) + try: + secret_or_certificate = self._alg.get_key(key_id=kid) + except TokenValidationError as e: + raise AuthError({"code": "invalid_header", "message": str(e)}, 401) + try: + payload = jwt.decode(token, + key=secret_or_certificate, + algorithms=[self._alg.algorithm], + audience=self._audience, + issuer=self._issuer) + return payload + except jwt.ExpiredSignatureError: + raise AuthError({"code": "token_expired", "message": "Token is expired"}, 401) + except jwt.JWTClaimsError: + raise AuthError( + { + "code": "invalid_claims", + "message": "Incorrect claims, please check the audience and issuer" + }, 401) + except Exception as e: + print(e) + raise AuthError({"code": "invalid_header", "message": "Unable to parse authentication token."}, 401) + + +class SymmetricJwtAlgorithm: + """Verifier for HMAC signatures, which rely on shared secrets. + Args: + shared_secret (str): The shared secret used to decode the token. + algorithm (str, optional): The expected signing algorithm. Defaults to "HS256". + """ + def __init__(self, shared_secret, algorithm="HS256"): + self.algorithm = algorithm + self._shared_secret = shared_secret + + # pylint: disable=W0613 + def get_key(self, key_id=None): + """ + Obtain the key for this algorithm. + :param key_id: The identifier of the key. + :return: The JWK key. + """ + return self._shared_secret + + +class AsymmetricJwtAlgorithm: + """Verifier for RSA signatures, which rely on public key certificates. + Args: + jwks_url (str): The url where the JWK set is located. + algorithm (str, optional): The expected signing algorithm. Defaults to "RS256". + """ + def __init__(self, jwks_url, algorithm="RS256"): + self.algorithm = algorithm + self._fetcher = JwksFetcher(jwks_url) + + def get_key(self, key_id=None): + """ + Obtain the key for this algorithm. + :param key_id: The identifier of the key. + :return: The JWK key. + """ + return self._fetcher.get_key(key_id) + + +class TokenValidationError(Exception): + """ + Error thrown when the token cannot be validated + """ + + +class JwksFetcher: + """Class that fetches and holds a JSON web key set. + This class makes use of an in-memory cache. For it to work properly, define this instance once and re-use it. + Args: + jwks_url (str): The url where the JWK set is located. + cache_ttl (str, optional): The lifetime of the JWK set cache in seconds. Defaults to 600 seconds. + """ + CACHE_TTL = 600 # 10 min cache lifetime + + def __init__(self, jwks_url, cache_ttl=CACHE_TTL): + self._jwks_url = jwks_url + self._http = urllib3.PoolManager() + self._cache_value = {} + self._cache_date = 0 + self._cache_ttl = cache_ttl + self._cache_is_fresh = False + + def _fetch_jwks(self, force=False): + """Attempts to obtain the JWK set from the cache, as long as it's still valid. + When not, it will perform a network request to the jwks_url to obtain a fresh result + and update the cache value with it. + Args: + force (bool, optional): whether to ignore the cache and force a network request or not. Defaults to False. + """ + has_expired = self._cache_date + self._cache_ttl < time.time() + + if not force and not has_expired: + # Return from cache + self._cache_is_fresh = False + return self._cache_value + + # Invalidate cache and fetch fresh data + self._cache_value = {} + response = self._http.request('GET', self._jwks_url) + + if response.status == 200: + # Update cache + jwks = json.loads(response.data.decode('utf-8')) + self._cache_value = self._parse_jwks(jwks) + self._cache_is_fresh = True + self._cache_date = time.time() + return self._cache_value + + @staticmethod + def _parse_jwks(jwks): + """Converts a JWK string representation into a binary certificate in PEM format. + """ + keys = {} + + for key in jwks['keys']: + keys[key["kid"]] = key + return keys + + def get_key(self, key_id): + """Obtains the JWK associated with the given key id. + Args: + key_id (str): The id of the key to fetch. + Returns: + the JWK associated with the given key id. + + Raises: + TokenValidationError: when a key with that id cannot be found + """ + keys = self._fetch_jwks() + + if keys and key_id in keys: + return keys[key_id] + + if not self._cache_is_fresh: + keys = self._fetch_jwks(force=True) + if keys and key_id in keys: + return keys[key_id] + raise TokenValidationError(f"RSA Public Key with ID {key_id} was not found.") diff --git a/opendc-web/opendc-web-api/opendc/database.py b/opendc-web/opendc-web-api/opendc/database.py new file mode 100644 index 00000000..f9a33b66 --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/database.py @@ -0,0 +1,102 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import urllib.parse +from datetime import datetime + +from pymongo import MongoClient + +DATETIME_STRING_FORMAT = '%Y-%m-%dT%H:%M:%S' +CONNECTION_POOL = None + + +class Database: + """Object holding functionality for database access.""" + def __init__(self, db=None): + """Initializes the database connection.""" + self.opendc_db = db + + @classmethod + def from_credentials(cls, user, password, database, host): + """ + Construct a database instance from the specified credentials. + :param user: The username to connect with. + :param password: The password to connect with. + :param database: The database name to connect to. + :param host: The host to connect to. + :return: The database instance. + """ + user = urllib.parse.quote_plus(user) + password = urllib.parse.quote_plus(password) + database = urllib.parse.quote_plus(database) + host = urllib.parse.quote_plus(host) + + client = MongoClient('mongodb://%s:%s@%s/default_db?authSource=%s' % (user, password, host, database)) + return cls(client.opendc) + + def fetch_one(self, query, collection): + """Uses existing mongo connection to return a single (the first) document in a collection matching the given + query as a JSON object. + + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + return getattr(self.opendc_db, collection).find_one(query) + + def fetch_all(self, query, collection): + """Uses existing mongo connection to return all documents matching a given query, as a list of JSON objects. + + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + cursor = getattr(self.opendc_db, collection).find(query) + return list(cursor) + + def insert(self, obj, collection): + """Updates an existing object.""" + bson = getattr(self.opendc_db, collection).insert(obj) + + return bson + + def update(self, _id, obj, collection): + """Updates an existing object.""" + return getattr(self.opendc_db, collection).update({'_id': _id}, obj) + + def delete_one(self, query, collection): + """Deletes one object matching the given query. + + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + getattr(self.opendc_db, collection).delete_one(query) + + def delete_all(self, query, collection): + """Deletes all objects matching the given query. + + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + getattr(self.opendc_db, collection).delete_many(query) + + @staticmethod + def datetime_to_string(datetime_to_convert): + """Return a database-compatible string representation of the given datetime object.""" + return datetime_to_convert.strftime(DATETIME_STRING_FORMAT) + + @staticmethod + def string_to_datetime(string_to_convert): + """Return a datetime corresponding to the given string representation.""" + return datetime.strptime(string_to_convert, DATETIME_STRING_FORMAT) diff --git a/opendc-web/opendc-web-api/opendc/exts.py b/opendc-web/opendc-web-api/opendc/exts.py new file mode 100644 index 00000000..f088a29c --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/exts.py @@ -0,0 +1,60 @@ +import os +from functools import wraps + +from flask import g, _request_ctx_stack +from werkzeug.local import LocalProxy + +from opendc.database import Database +from opendc.auth import AuthContext, AsymmetricJwtAlgorithm, get_token + + +def get_db(): + """ + Return the configured database instance for the application. + """ + _db = getattr(g, 'db', None) + if _db is None: + _db = Database.from_credentials(user=os.environ['OPENDC_DB_USERNAME'], + password=os.environ['OPENDC_DB_PASSWORD'], + database=os.environ['OPENDC_DB'], + host=os.environ.get('OPENDC_DB_HOST', 'localhost')) + g.db = _db + return _db + + +db = LocalProxy(get_db) + + +def get_auth_context(): + """ + Return the configured auth context for the application. + """ + _auth_context = getattr(g, 'auth_context', None) + if _auth_context is None: + _auth_context = AuthContext( + alg=AsymmetricJwtAlgorithm(jwks_url=f"https://{os.environ['AUTH0_DOMAIN']}/.well-known/jwks.json"), + issuer=f"https://{os.environ['AUTH0_DOMAIN']}/", + audience=os.environ['AUTH0_AUDIENCE'] + ) + g.auth_context = _auth_context + return _auth_context + + +auth_context = LocalProxy(get_auth_context) + + +def requires_auth(f): + """Decorator to determine if the Access Token is valid. + """ + + @wraps(f) + def decorated(*args, **kwargs): + token = get_token() + payload = auth_context.validate(token) + _request_ctx_stack.top.current_user = payload + return f(*args, **kwargs) + + return decorated + + +current_user = LocalProxy(lambda: getattr(_request_ctx_stack.top, 'current_user', None)) diff --git a/opendc-web/opendc-web-api/opendc/models/model.py b/opendc-web/opendc-web-api/opendc/models/model.py index f9dfc9ad..28299453 100644 --- a/opendc-web/opendc-web-api/opendc/models/model.py +++ b/opendc-web/opendc-web-api/opendc/models/model.py @@ -1,8 +1,7 @@ from bson.objectid import ObjectId +from werkzeug.exceptions import NotFound -from opendc.util.database import DB -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response +from opendc.exts import db class Model: @@ -15,15 +14,13 @@ class Model: """Fetches the document with given ID from the collection.""" if isinstance(_id, str) and len(_id) == 24: _id = ObjectId(_id) - elif not isinstance(_id, ObjectId): - return cls(None) - return cls(DB.fetch_one({'_id': _id}, cls.collection_name)) + return cls(db.fetch_one({'_id': _id}, cls.collection_name)) @classmethod def get_all(cls): """Fetches all documents from the collection.""" - return cls(DB.fetch_all({}, cls.collection_name)) + return cls(db.fetch_all({}, cls.collection_name)) def __init__(self, obj): self.obj = obj @@ -35,7 +32,7 @@ class Model: def check_exists(self): """Raises an error if the enclosed object does not exist.""" if self.obj is None: - raise ClientError(Response(404, 'Not found.')) + raise NotFound('Entity not found.') def set_property(self, key, value): """Sets the given property on the enclosed object, with support for simple nested access.""" @@ -48,11 +45,11 @@ class Model: def insert(self): """Inserts the enclosed object and generates a UUID for it.""" self.obj['_id'] = ObjectId() - DB.insert(self.obj, self.collection_name) + db.insert(self.obj, self.collection_name) def update(self): """Updates the enclosed object and updates the internal reference to the newly inserted object.""" - DB.update(self.get_id(), self.obj, self.collection_name) + db.update(self.get_id(), self.obj, self.collection_name) def delete(self): """Deletes the enclosed object in the database, if it existed.""" @@ -60,5 +57,5 @@ class Model: return None old_object = self.obj.copy() - DB.delete_one({'_id': self.get_id()}, self.collection_name) + db.delete_one({'_id': self.get_id()}, self.collection_name) return old_object diff --git a/opendc-web/opendc-web-api/opendc/models/portfolio.py b/opendc-web/opendc-web-api/opendc/models/portfolio.py index 8e3f2a52..aff1d3f0 100644 --- a/opendc-web/opendc-web-api/opendc/models/portfolio.py +++ b/opendc-web/opendc-web-api/opendc/models/portfolio.py @@ -1,7 +1,28 @@ +from marshmallow import Schema, fields + from opendc.models.project import Project from opendc.models.model import Model +class TargetSchema(Schema): + """ + Schema representing a target. + """ + enabledMetrics = fields.List(fields.String()) + repeatsPerScenario = fields.Integer(required=True) + + +class PortfolioSchema(Schema): + """ + Schema representing a portfolio. + """ + _id = fields.String() + projectId = fields.String() + name = fields.String(required=True) + scenarioIds = fields.List(fields.String()) + targets = fields.Nested(TargetSchema) + + class Portfolio(Model): """Model representing a Portfolio.""" diff --git a/opendc-web/opendc-web-api/opendc/models/prefab.py b/opendc-web/opendc-web-api/opendc/models/prefab.py index 05356358..d83ef4cb 100644 --- a/opendc-web/opendc-web-api/opendc/models/prefab.py +++ b/opendc-web/opendc-web-api/opendc/models/prefab.py @@ -1,17 +1,30 @@ +from marshmallow import Schema, fields +from werkzeug.exceptions import Forbidden + +from opendc.models.topology import ObjectSchema from opendc.models.model import Model -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response + + +class PrefabSchema(Schema): + """ + Schema for a Prefab. + """ + _id = fields.String() + name = fields.String(required=True) + datetimeCreated = fields.DateTime() + datetimeLastEdited = fields.DateTime() + rack = fields.Nested(ObjectSchema) class Prefab(Model): - """Model representing a Project.""" + """Model representing a Prefab.""" collection_name = 'prefabs' def check_user_access(self, user_id): """Raises an error if the user with given [user_id] has insufficient access to view this prefab. - :param user_id: The Google ID of the user. + :param user_id: The user ID of the user. """ if self.obj['authorId'] != user_id and self.obj['visibility'] == "private": - raise ClientError(Response(403, "Forbidden from retrieving prefab.")) + raise Forbidden("Forbidden from retrieving prefab.") diff --git a/opendc-web/opendc-web-api/opendc/models/project.py b/opendc-web/opendc-web-api/opendc/models/project.py index 2b3fd5f4..ee84c73e 100644 --- a/opendc-web/opendc-web-api/opendc/models/project.py +++ b/opendc-web/opendc-web-api/opendc/models/project.py @@ -1,7 +1,20 @@ +from marshmallow import Schema, fields +from werkzeug.exceptions import Forbidden + from opendc.models.model import Model -from opendc.util.database import DB -from opendc.util.exceptions import ClientError -from opendc.util.rest import Response +from opendc.exts import db + + +class ProjectSchema(Schema): + """ + Schema representing a Project. + """ + _id = fields.String() + name = fields.String(required=True) + datetimeCreated = fields.DateTime() + datetimeLastEdited = fields.DateTime() + topologyIds = fields.List(fields.String()) + portfolioIds = fields.List(fields.String()) class Project(Model): @@ -16,13 +29,11 @@ class Project(Model): :param edit_access: True when edit access should be checked, otherwise view access. """ for authorization in self.obj['authorizations']: - if user_id == authorization['userId'] and authorization['authorizationLevel'] != 'VIEW' or not edit_access: + if user_id == authorization['userId'] and authorization['level'] != 'VIEW' or not edit_access: return - raise ClientError(Response(403, "Forbidden from retrieving project.")) + raise Forbidden("Forbidden from retrieving project.") @classmethod def get_for_user(cls, user_id): """Get all projects for the specified user id.""" - return DB.fetch_all({'authorizations': { - 'userId': user_id - }}, Project.collection_name) + return db.fetch_all({'authorizations.userId': user_id}, Project.collection_name) diff --git a/opendc-web/opendc-web-api/opendc/models/scenario.py b/opendc-web/opendc-web-api/opendc/models/scenario.py index 3dfde012..2911b1ae 100644 --- a/opendc-web/opendc-web-api/opendc/models/scenario.py +++ b/opendc-web/opendc-web-api/opendc/models/scenario.py @@ -1,7 +1,52 @@ +from marshmallow import Schema, fields from opendc.models.model import Model from opendc.models.portfolio import Portfolio +class SimulationSchema(Schema): + """ + Simulation details. + """ + state = fields.String() + + +class TraceSchema(Schema): + """ + Schema for specifying the trace of a scenario. + """ + traceId = fields.String() + loadSamplingFraction = fields.Float() + + +class TopologySchema(Schema): + """ + Schema for topology specification for a scenario. + """ + topologyId = fields.String() + + +class OperationalSchema(Schema): + """ + Schema for the operational phenomena for a scenario. + """ + failuresEnabled = fields.Boolean() + performanceInterferenceEnabled = fields.Boolean() + schedulerName = fields.String() + + +class ScenarioSchema(Schema): + """ + Schema representing a scenario. + """ + _id = fields.String() + portfolioId = fields.String() + name = fields.String(required=True) + simulation = fields.Nested(SimulationSchema) + trace = fields.Nested(TraceSchema) + topology = fields.Nested(TopologySchema) + operational = fields.Nested(OperationalSchema) + + class Scenario(Model): """Model representing a Scenario.""" @@ -16,5 +61,4 @@ class Scenario(Model): :param edit_access: True when edit access should be checked, otherwise view access. """ portfolio = Portfolio.from_id(self.obj['portfolioId']) - print(portfolio.obj) portfolio.check_user_access(user_id, edit_access) diff --git a/opendc-web/opendc-web-api/opendc/models/topology.py b/opendc-web/opendc-web-api/opendc/models/topology.py index 3ebec16d..c6354ae6 100644 --- a/opendc-web/opendc-web-api/opendc/models/topology.py +++ b/opendc-web/opendc-web-api/opendc/models/topology.py @@ -1,7 +1,83 @@ +from marshmallow import Schema, fields + from opendc.models.project import Project from opendc.models.model import Model +class MemorySchema(Schema): + """ + Schema representing a memory unit. + """ + _id = fields.String() + name = fields.String() + speedMbPerS = fields.Integer() + sizeMb = fields.Integer() + energyConsumptionW = fields.Integer() + + +class PuSchema(Schema): + """ + Schema representing a processing unit. + """ + _id = fields.String() + name = fields.String() + clockRateMhz = fields.Integer() + numberOfCores = fields.Integer() + energyConsumptionW = fields.Integer() + + +class MachineSchema(Schema): + """ + Schema representing a machine. + """ + _id = fields.String() + position = fields.Integer() + cpus = fields.List(fields.Nested(PuSchema)) + gpus = fields.List(fields.Nested(PuSchema)) + memories = fields.List(fields.Nested(MemorySchema)) + storages = fields.List(fields.Nested(MemorySchema)) + + +class ObjectSchema(Schema): + """ + Schema representing a room object. + """ + _id = fields.String() + name = fields.String() + capacity = fields.Integer() + powerCapacityW = fields.Integer() + machines = fields.List(fields.Nested(MachineSchema)) + + +class TileSchema(Schema): + """ + Schema representing a room tile. + """ + _id = fields.String() + positionX = fields.Integer() + positionY = fields.Integer() + rack = fields.Nested(ObjectSchema) + + +class RoomSchema(Schema): + """ + Schema representing a room. + """ + _id = fields.String() + name = fields.String(required=True) + tiles = fields.List(fields.Nested(TileSchema), required=True) + + +class TopologySchema(Schema): + """ + Schema representing a datacenter topology. + """ + _id = fields.String() + projectId = fields.String() + name = fields.String(required=True) + rooms = fields.List(fields.Nested(RoomSchema), required=True) + + class Topology(Model): """Model representing a Project.""" diff --git a/opendc-web/opendc-web-api/opendc/util.py b/opendc-web/opendc-web-api/opendc/util.py new file mode 100644 index 00000000..e7dc07a4 --- /dev/null +++ b/opendc-web/opendc-web-api/opendc/util.py @@ -0,0 +1,32 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import flask +from bson.objectid import ObjectId + + +class JSONEncoder(flask.json.JSONEncoder): + """ + A customized JSON encoder to handle unsupported types. + """ + def default(self, o): + if isinstance(o, ObjectId): + return str(o) + return flask.json.JSONEncoder.default(self, o) diff --git a/opendc-web/opendc-web-api/opendc/util/__init__.py b/opendc-web/opendc-web-api/opendc/util/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/opendc-web/opendc-web-api/opendc/util/auth.py b/opendc-web/opendc-web-api/opendc/util/auth.py deleted file mode 100644 index 810b582a..00000000 --- a/opendc-web/opendc-web-api/opendc/util/auth.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright (c) 2021 AtLarge Research -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -import json -import time -from functools import wraps - -import urllib3 -from flask import request, _request_ctx_stack -from jose import jwt, JWTError -from werkzeug.local import LocalProxy - -current_user = LocalProxy(lambda: getattr(_request_ctx_stack.top, 'current_user', None)) - - -class AuthError(Exception): - """ - This error is thrown when the request failed to authorize. - """ - - def __init__(self, error, status_code): - Exception.__init__(self, error) - self.error = error - self.status_code = status_code - - -class AuthManager: - """ - This class handles the authorization of requests. - """ - - def __init__(self, alg, issuer, audience): - self._alg = alg - self._issuer = issuer - self._audience = audience - - def require(self, f): - """Determines if the Access Token is valid - """ - - @wraps(f) - def decorated(*args, **kwargs): - token = _get_token() - try: - header = jwt.get_unverified_header(token) - except JWTError as e: - raise AuthError({"code": "invalid_token", - "description": str(e)}, 401) - - alg = header.get('alg', None) - if alg != self._alg.algorithm: - raise AuthError({"code": "invalid_header", - "description": f"Signature algorithm of {alg} is not supported. Expected the ID token " - f"to be signed with {self._alg.algorithm}"}, 401) - - kid = header.get('kid', None) - try: - secret_or_certificate = self._alg.get_key(key_id=kid) - except TokenValidationError as e: - raise AuthError({"code": "invalid_header", - "description": str(e)}, 401) - try: - payload = jwt.decode(token, - key=secret_or_certificate, - algorithms=[self._alg.algorithm], - audience=self._audience, - issuer=self._issuer) - _request_ctx_stack.top.current_user = payload - return f(*args, **kwargs) - except jwt.ExpiredSignatureError: - raise AuthError({"code": "token_expired", - "description": "token is expired"}, 401) - except jwt.JWTClaimsError: - raise AuthError({"code": "invalid_claims", - "description": - "incorrect claims," - "please check the audience and issuer"}, 401) - except Exception as e: - print(e) - raise AuthError({"code": "invalid_header", - "description": - "Unable to parse authentication" - " token."}, 401) - - return decorated - - -def _get_token(): - """ - Obtain the Access Token from the Authorization Header - """ - auth = request.headers.get("Authorization", None) - if not auth: - raise AuthError({"code": "authorization_header_missing", - "description": - "Authorization header is expected"}, 401) - - parts = auth.split() - - if parts[0].lower() != "bearer": - raise AuthError({"code": "invalid_header", - "description": - "Authorization header must start with" - " Bearer"}, 401) - if len(parts) == 1: - raise AuthError({"code": "invalid_header", - "description": "Token not found"}, 401) - if len(parts) > 2: - raise AuthError({"code": "invalid_header", - "description": - "Authorization header must be" - " Bearer token"}, 401) - - token = parts[1] - return token - - -class SymmetricJwtAlgorithm: - """Verifier for HMAC signatures, which rely on shared secrets. - Args: - shared_secret (str): The shared secret used to decode the token. - algorithm (str, optional): The expected signing algorithm. Defaults to "HS256". - """ - - def __init__(self, shared_secret, algorithm="HS256"): - self.algorithm = algorithm - self._shared_secret = shared_secret - - # pylint: disable=W0613 - def get_key(self, key_id=None): - """ - Obtain the key for this algorithm. - :param key_id: The identifier of the key. - :return: The JWK key. - """ - return self._shared_secret - - -class AsymmetricJwtAlgorithm: - """Verifier for RSA signatures, which rely on public key certificates. - Args: - jwks_url (str): The url where the JWK set is located. - algorithm (str, optional): The expected signing algorithm. Defaults to "RS256". - """ - - def __init__(self, jwks_url, algorithm="RS256"): - self.algorithm = algorithm - self._fetcher = JwksFetcher(jwks_url) - - def get_key(self, key_id=None): - """ - Obtain the key for this algorithm. - :param key_id: The identifier of the key. - :return: The JWK key. - """ - return self._fetcher.get_key(key_id) - - -class TokenValidationError(Exception): - """ - Error thrown when the token cannot be validated - """ - - -class JwksFetcher: - """Class that fetches and holds a JSON web key set. - This class makes use of an in-memory cache. For it to work properly, define this instance once and re-use it. - Args: - jwks_url (str): The url where the JWK set is located. - cache_ttl (str, optional): The lifetime of the JWK set cache in seconds. Defaults to 600 seconds. - """ - CACHE_TTL = 600 # 10 min cache lifetime - - def __init__(self, jwks_url, cache_ttl=CACHE_TTL): - self._jwks_url = jwks_url - self._http = urllib3.PoolManager() - self._cache_value = {} - self._cache_date = 0 - self._cache_ttl = cache_ttl - self._cache_is_fresh = False - - def _fetch_jwks(self, force=False): - """Attempts to obtain the JWK set from the cache, as long as it's still valid. - When not, it will perform a network request to the jwks_url to obtain a fresh result - and update the cache value with it. - Args: - force (bool, optional): whether to ignore the cache and force a network request or not. Defaults to False. - """ - has_expired = self._cache_date + self._cache_ttl < time.time() - - if not force and not has_expired: - # Return from cache - self._cache_is_fresh = False - return self._cache_value - - # Invalidate cache and fetch fresh data - self._cache_value = {} - response = self._http.request('GET', self._jwks_url) - - if response.status == 200: - # Update cache - jwks = json.loads(response.data.decode('utf-8')) - self._cache_value = self._parse_jwks(jwks) - self._cache_is_fresh = True - self._cache_date = time.time() - return self._cache_value - - @staticmethod - def _parse_jwks(jwks): - """Converts a JWK string representation into a binary certificate in PEM format. - """ - keys = {} - - for key in jwks['keys']: - keys[key["kid"]] = key - return keys - - def get_key(self, key_id): - """Obtains the JWK associated with the given key id. - Args: - key_id (str): The id of the key to fetch. - Returns: - the JWK associated with the given key id. - - Raises: - TokenValidationError: when a key with that id cannot be found - """ - keys = self._fetch_jwks() - - if keys and key_id in keys: - return keys[key_id] - - if not self._cache_is_fresh: - keys = self._fetch_jwks(force=True) - if keys and key_id in keys: - return keys[key_id] - raise TokenValidationError(f"RSA Public Key with ID {key_id} was not found.") diff --git a/opendc-web/opendc-web-api/opendc/util/database.py b/opendc-web/opendc-web-api/opendc/util/database.py deleted file mode 100644 index dd26533d..00000000 --- a/opendc-web/opendc-web-api/opendc/util/database.py +++ /dev/null @@ -1,77 +0,0 @@ -import urllib.parse -from datetime import datetime - -from pymongo import MongoClient - -DATETIME_STRING_FORMAT = '%Y-%m-%dT%H:%M:%S' -CONNECTION_POOL = None - - -class Database: - """Object holding functionality for database access.""" - def __init__(self): - self.opendc_db = None - - def initialize_database(self, user, password, database, host): - """Initializes the database connection.""" - - user = urllib.parse.quote_plus(user) - password = urllib.parse.quote_plus(password) - database = urllib.parse.quote_plus(database) - host = urllib.parse.quote_plus(host) - - client = MongoClient('mongodb://%s:%s@%s/default_db?authSource=%s' % (user, password, host, database)) - self.opendc_db = client.opendc - - def fetch_one(self, query, collection): - """Uses existing mongo connection to return a single (the first) document in a collection matching the given - query as a JSON object. - - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - return getattr(self.opendc_db, collection).find_one(query) - - def fetch_all(self, query, collection): - """Uses existing mongo connection to return all documents matching a given query, as a list of JSON objects. - - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - cursor = getattr(self.opendc_db, collection).find(query) - return list(cursor) - - def insert(self, obj, collection): - """Updates an existing object.""" - bson = getattr(self.opendc_db, collection).insert(obj) - - return bson - - def update(self, _id, obj, collection): - """Updates an existing object.""" - return getattr(self.opendc_db, collection).update({'_id': _id}, obj) - - def delete_one(self, query, collection): - """Deletes one object matching the given query. - - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - getattr(self.opendc_db, collection).delete_one(query) - - def delete_all(self, query, collection): - """Deletes all objects matching the given query. - - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - getattr(self.opendc_db, collection).delete_many(query) - - @staticmethod - def datetime_to_string(datetime_to_convert): - """Return a database-compatible string representation of the given datetime object.""" - return datetime_to_convert.strftime(DATETIME_STRING_FORMAT) - - @staticmethod - def string_to_datetime(string_to_convert): - """Return a datetime corresponding to the given string representation.""" - return datetime.strptime(string_to_convert, DATETIME_STRING_FORMAT) - - -DB = Database() diff --git a/opendc-web/opendc-web-api/opendc/util/exceptions.py b/opendc-web/opendc-web-api/opendc/util/exceptions.py deleted file mode 100644 index 7724a407..00000000 --- a/opendc-web/opendc-web-api/opendc/util/exceptions.py +++ /dev/null @@ -1,64 +0,0 @@ -class RequestInitializationError(Exception): - """Raised when a Request cannot successfully be initialized""" - - -class UnimplementedEndpointError(RequestInitializationError): - """Raised when a Request path does not point to a module.""" - - -class MissingRequestParameterError(RequestInitializationError): - """Raised when a Request does not contain one or more required parameters.""" - - -class UnsupportedMethodError(RequestInitializationError): - """Raised when a Request does not use a supported REST method. - - The method must be in all-caps, supported by REST, and implemented by the module. - """ - - -class AuthorizationTokenError(RequestInitializationError): - """Raised when an authorization token is not correctly verified.""" - - -class ForeignKeyError(Exception): - """Raised when a foreign key constraint is not met.""" - - -class RowNotFoundError(Exception): - """Raised when a database row is not found.""" - def __init__(self, table_name): - super(RowNotFoundError, self).__init__('Row in `{}` table not found.'.format(table_name)) - - self.table_name = table_name - - -class ParameterError(Exception): - """Raised when a parameter is either missing or incorrectly typed.""" - - -class IncorrectParameterError(ParameterError): - """Raised when a parameter is of the wrong type.""" - def __init__(self, parameter_name, parameter_location): - super(IncorrectParameterError, - self).__init__('Incorrectly typed `{}` {} parameter.'.format(parameter_name, parameter_location)) - - self.parameter_name = parameter_name - self.parameter_location = parameter_location - - -class MissingParameterError(ParameterError): - """Raised when a parameter is missing.""" - def __init__(self, parameter_name, parameter_location): - super(MissingParameterError, - self).__init__('Missing required `{}` {} parameter.'.format(parameter_name, parameter_location)) - - self.parameter_name = parameter_name - self.parameter_location = parameter_location - - -class ClientError(Exception): - """Raised when a 4xx response is to be returned.""" - def __init__(self, response): - super(ClientError, self).__init__(str(response)) - self.response = response diff --git a/opendc-web/opendc-web-api/opendc/util/json.py b/opendc-web/opendc-web-api/opendc/util/json.py deleted file mode 100644 index 2ef4f965..00000000 --- a/opendc-web/opendc-web-api/opendc/util/json.py +++ /dev/null @@ -1,12 +0,0 @@ -import flask -from bson.objectid import ObjectId - - -class JSONEncoder(flask.json.JSONEncoder): - """ - A customized JSON encoder to handle unsupported types. - """ - def default(self, o): - if isinstance(o, ObjectId): - return str(o) - return flask.json.JSONEncoder.default(self, o) diff --git a/opendc-web/opendc-web-api/opendc/util/parameter_checker.py b/opendc-web/opendc-web-api/opendc/util/parameter_checker.py deleted file mode 100644 index 14dd1dc0..00000000 --- a/opendc-web/opendc-web-api/opendc/util/parameter_checker.py +++ /dev/null @@ -1,85 +0,0 @@ -from opendc.util import exceptions -from opendc.util.database import Database - - -def _missing_parameter(params_required, params_actual, parent=''): - """Recursively search for the first missing parameter.""" - - for param_name in params_required: - - if param_name not in params_actual: - return '{}.{}'.format(parent, param_name) - - param_required = params_required.get(param_name) - param_actual = params_actual.get(param_name) - - if isinstance(param_required, dict): - - param_missing = _missing_parameter(param_required, param_actual, param_name) - - if param_missing is not None: - return '{}.{}'.format(parent, param_missing) - - return None - - -def _incorrect_parameter(params_required, params_actual, parent=''): - """Recursively make sure each parameter is of the correct type.""" - - for param_name in params_required: - - param_required = params_required.get(param_name) - param_actual = params_actual.get(param_name) - - if isinstance(param_required, dict): - - param_incorrect = _incorrect_parameter(param_required, param_actual, param_name) - - if param_incorrect is not None: - return '{}.{}'.format(parent, param_incorrect) - - else: - - if param_required == 'datetime': - try: - Database.string_to_datetime(param_actual) - except: - return '{}.{}'.format(parent, param_name) - - type_pairs = [ - ('int', (int,)), - ('float', (float, int)), - ('bool', (bool,)), - ('string', (str, int)), - ('list', (list,)), - ] - - for str_type, actual_types in type_pairs: - if param_required == str_type and all(not isinstance(param_actual, t) - for t in actual_types): - return '{}.{}'.format(parent, param_name) - - return None - - -def _format_parameter(parameter): - """Format the output of a parameter check.""" - - parts = parameter.split('.') - inner = ['["{}"]'.format(x) for x in parts[2:]] - return parts[1] + ''.join(inner) - - -def check(request, **kwargs): - """Check if all required parameters are there.""" - - for location, params_required in kwargs.items(): - params_actual = getattr(request, 'params_{}'.format(location)) - - missing_parameter = _missing_parameter(params_required, params_actual) - if missing_parameter is not None: - raise exceptions.MissingParameterError(_format_parameter(missing_parameter), location) - - incorrect_parameter = _incorrect_parameter(params_required, params_actual) - if incorrect_parameter is not None: - raise exceptions.IncorrectParameterError(_format_parameter(incorrect_parameter), location) diff --git a/opendc-web/opendc-web-api/opendc/util/path_parser.py b/opendc-web/opendc-web-api/opendc/util/path_parser.py deleted file mode 100644 index c8452f20..00000000 --- a/opendc-web/opendc-web-api/opendc/util/path_parser.py +++ /dev/null @@ -1,36 +0,0 @@ -import json -import os - - -def parse(version, endpoint_path): - """Map an HTTP endpoint path to an API path""" - - # Get possible paths - with open(os.path.join(os.path.dirname(__file__), '..', 'api', '{}', 'paths.json').format(version)) as paths_file: - paths = json.load(paths_file) - - # Find API path that matches endpoint_path - endpoint_path_parts = endpoint_path.strip('/').split('/') - paths_parts = [x.strip('/').split('/') for x in paths if len(x.strip('/').split('/')) == len(endpoint_path_parts)] - path = None - - for path_parts in paths_parts: - found = True - for (endpoint_part, part) in zip(endpoint_path_parts, path_parts): - if not part.startswith('{') and endpoint_part != part: - found = False - break - if found: - path = path_parts - - if path is None: - return None - - # Extract path parameters - parameters = {} - - for (name, value) in zip(path, endpoint_path_parts): - if name.startswith('{'): - parameters[name.strip('{}')] = value - - return '{}/{}'.format(version, '/'.join(path)), parameters diff --git a/opendc-web/opendc-web-api/opendc/util/rest.py b/opendc-web/opendc-web-api/opendc/util/rest.py deleted file mode 100644 index 63d063b3..00000000 --- a/opendc-web/opendc-web-api/opendc/util/rest.py +++ /dev/null @@ -1,109 +0,0 @@ -import importlib -import json - -from opendc.util import exceptions, parameter_checker -from opendc.util.exceptions import ClientError -from opendc.util.auth import current_user - - -class Request: - """WebSocket message to REST request mapping.""" - def __init__(self, message=None): - """"Initialize a Request from a socket message.""" - - # Get the Request parameters from the message - - if message is None: - return - - try: - self.message = message - - self.id = message['id'] - - self.path = message['path'] - self.method = message['method'] - - self.params_body = message['parameters']['body'] - self.params_path = message['parameters']['path'] - self.params_query = message['parameters']['query'] - - self.token = message['token'] - - except KeyError as exception: - raise exceptions.MissingRequestParameterError(exception) - - # Parse the path and import the appropriate module - - try: - self.path = message['path'].strip('/') - - module_base = 'opendc.api.{}.endpoint' - module_path = self.path.replace('{', '').replace('}', '').replace('/', '.') - - self.module = importlib.import_module(module_base.format(module_path)) - except ImportError as e: - print(e) - raise exceptions.UnimplementedEndpointError('Unimplemented endpoint: {}.'.format(self.path)) - - # Check the method - - if self.method not in ['POST', 'GET', 'PUT', 'PATCH', 'DELETE']: - raise exceptions.UnsupportedMethodError('Non-rest method: {}'.format(self.method)) - - if not hasattr(self.module, self.method): - raise exceptions.UnsupportedMethodError('Unimplemented method at endpoint {}: {}'.format( - self.path, self.method)) - - self.current_user = current_user - - def check_required_parameters(self, **kwargs): - """Raise an error if a parameter is missing or of the wrong type.""" - - try: - parameter_checker.check(self, **kwargs) - except exceptions.ParameterError as e: - raise ClientError(Response(400, str(e))) - - def process(self): - """Process the Request and return a Response.""" - - method = getattr(self.module, self.method) - - try: - response = method(self) - except ClientError as e: - e.response.id = self.id - return e.response - - response.id = self.id - - return response - - def to_JSON(self): - """Return a JSON representation of this Request""" - - self.message['id'] = 0 - self.message['token'] = None - - return json.dumps(self.message) - - -class Response: - """Response to websocket mapping""" - def __init__(self, status_code, status_description, content=None): - """Initialize a new Response.""" - - self.id = 0 - self.status = {'code': status_code, 'description': status_description} - self.content = content - - def to_JSON(self): - """"Return a JSON representation of this Response""" - - data = {'id': self.id, 'status': self.status} - - if self.content is not None: - data['content'] = self.content - - return json.dumps(data, default=str) diff --git a/opendc-web/opendc-web-api/requirements.txt b/opendc-web/opendc-web-api/requirements.txt index a518da47..375ed40c 100644 --- a/opendc-web/opendc-web-api/requirements.txt +++ b/opendc-web/opendc-web-api/requirements.txt @@ -9,6 +9,7 @@ Flask==1.1.2 Flask-Compress==1.5.0 Flask-Cors==3.0.9 Flask-SocketIO==4.3.1 +Flask-Restful==0.3.8 greenlet==0.4.17 httplib2==0.19.0 isort==4.3.21 @@ -16,6 +17,7 @@ itsdangerous==1.1.0 Jinja2==2.11.3 lazy-object-proxy==1.4.3 MarkupSafe==1.1.1 +marshmallow==3.12.1 mccabe==0.6.1 monotonic==1.5 more-itertools==8.6.0 diff --git a/opendc-web/opendc-web-api/tests/api/test_portfolios.py b/opendc-web/opendc-web-api/tests/api/test_portfolios.py new file mode 100644 index 00000000..da7991f6 --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_portfolios.py @@ -0,0 +1,324 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from opendc.exts import db + +test_id = 24 * '1' +test_id_2 = 24 * '2' + + +def test_get_portfolio_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.get(f'/portfolios/{test_id}').status + + +def test_get_portfolio_no_authorizations(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value={'projectId': test_id, 'authorizations': []}) + res = client.get(f'/portfolios/{test_id}') + assert '403' in res.status + + +def test_get_portfolio_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + 'projectId': test_id, + '_id': test_id, + 'authorizations': [] + }) + res = client.get(f'/portfolios/{test_id}') + assert '403' in res.status + + +def test_get_portfolio(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + 'projectId': test_id, + '_id': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'EDIT' + }] + }) + res = client.get(f'/portfolios/{test_id}') + assert '200' in res.status + + +def test_update_portfolio_missing_parameter(client): + assert '400' in client.put(f'/portfolios/{test_id}').status + + +def test_update_portfolio_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.put(f'/portfolios/{test_id}', json={ + 'portfolio': { + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + } + } + }).status + + +def test_update_portfolio_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'VIEW' + }] + }) + mocker.patch.object(db, 'update', return_value={}) + assert '403' in client.put(f'/portfolios/{test_id}', json={ + 'portfolio': { + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + } + } + }).status + + +def test_update_portfolio(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }], + 'targets': { + 'enabledMetrics': [], + 'repeatsPerScenario': 1 + } + }) + mocker.patch.object(db, 'update', return_value={}) + + res = client.put(f'/portfolios/{test_id}', json={'portfolio': { + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + } + }}) + assert '200' in res.status + + +def test_delete_project_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.delete(f'/portfolios/{test_id}').status + + +def test_delete_project_different_user(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'googleId': 'other_test', + 'authorizations': [{ + 'userId': 'test', + 'level': 'VIEW' + }] + }) + mocker.patch.object(db, 'delete_one', return_value=None) + assert '403' in client.delete(f'/portfolios/{test_id}').status + + +def test_delete_project(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'googleId': 'test', + 'portfolioIds': [test_id], + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + mocker.patch.object(db, 'delete_one', return_value={}) + mocker.patch.object(db, 'update', return_value=None) + res = client.delete(f'/portfolios/{test_id}') + assert '200' in res.status + + +def test_add_topology_missing_parameter(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'googleId': 'test', + 'portfolioIds': [test_id], + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + assert '400' in client.post(f'/projects/{test_id}/topologies').status + + +def test_add_topology(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }], + 'topologyIds': [] + }) + mocker.patch.object(db, + 'insert', + return_value={ + '_id': test_id, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'topologyIds': [] + }) + mocker.patch.object(db, 'update', return_value={}) + res = client.post(f'/projects/{test_id}/topologies', json={'topology': {'name': 'test project', 'rooms': []}}) + assert 'rooms' in res.json['data'] + assert '200' in res.status + + +def test_add_topology_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'VIEW' + }] + }) + assert '403' in client.post(f'/projects/{test_id}/topologies', + json={ + 'topology': { + 'name': 'test_topology', + 'rooms': [] + } + }).status + + +def test_add_portfolio_missing_parameter(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'googleId': 'test', + 'portfolioIds': [test_id], + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + assert '400' in client.post(f'/projects/{test_id}/portfolios').status + + +def test_add_portfolio_non_existing_project(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.post(f'/projects/{test_id}/portfolios', + json={ + 'portfolio': { + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + } + } + }).status + + +def test_add_portfolio_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'VIEW' + }] + }) + assert '403' in client.post(f'/projects/{test_id}/portfolios', + json={ + 'portfolio': { + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + } + } + }).status + + +def test_add_portfolio(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'portfolioIds': [test_id], + 'authorizations': [{ + 'userId': 'test', + 'level': 'EDIT' + }] + }) + mocker.patch.object(db, + 'insert', + return_value={ + '_id': test_id, + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + }, + 'projectId': test_id, + 'scenarioIds': [], + }) + mocker.patch.object(db, 'update', return_value=None) + res = client.post( + f'/projects/{test_id}/portfolios', + json={ + 'portfolio': { + 'name': 'test', + 'targets': { + 'enabledMetrics': ['test'], + 'repeatsPerScenario': 2 + } + } + }) + assert 'projectId' in res.json['data'] + assert 'scenarioIds' in res.json['data'] + assert '200' in res.status diff --git a/opendc-web/opendc-web-api/tests/api/test_prefabs.py b/opendc-web/opendc-web-api/tests/api/test_prefabs.py new file mode 100644 index 00000000..ea3d92d6 --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_prefabs.py @@ -0,0 +1,252 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from unittest.mock import Mock +from opendc.exts import db + +test_id = 24 * '1' +test_id_2 = 24 * '2' + + +def test_add_prefab_missing_parameter(client): + assert '400' in client.post('/prefabs/').status + + +def test_add_prefab(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value={'_id': test_id, 'authorizations': []}) + mocker.patch.object(db, + 'insert', + return_value={ + '_id': test_id, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': test_id + }) + res = client.post('/prefabs/', json={'prefab': {'name': 'test prefab'}}) + assert 'datetimeCreated' in res.json['data'] + assert 'datetimeLastEdited' in res.json['data'] + assert 'authorId' in res.json['data'] + assert '200' in res.status + + +def test_get_prefabs(client, mocker): + db.fetch_all = Mock() + mocker.patch.object(db, 'fetch_one', return_value={'_id': test_id}) + db.fetch_all.side_effect = [ + [{ + '_id': test_id, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': test_id, + 'visibility' : 'private' + }, + { + '_id': '2' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': test_id, + 'visibility' : 'private' + }, + { + '_id': '3' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': test_id, + 'visibility' : 'public' + }, + { + '_id': '4' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': test_id, + 'visibility' : 'public' + }], + [{ + '_id': '5' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': '2' * 24, + 'visibility' : 'public' + }, + { + '_id': '6' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': '2' * 24, + 'visibility' : 'public' + }, + { + '_id': '7' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': '2' * 24, + 'visibility' : 'public' + }, + { + '_id': '8' * 24, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'authorId': '2' * 24, + 'visibility' : 'public' + }] + ] + mocker.patch.object(db, 'fetch_one', return_value={'_id': test_id}) + res = client.get('/prefabs/') + assert '200' in res.status + + +def test_get_prefab_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.get(f'/prefabs/{test_id}').status + + +def test_get_private_prefab_not_authorized(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + res = client.get(f'/prefabs/{test_id}') + assert '403' in res.status + + +def test_get_private_prefab(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': 'test', + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + res = client.get(f'/prefabs/{test_id}') + assert '200' in res.status + + +def test_get_public_prefab(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'public', + 'rack': {} + }, + { + '_id': test_id + } + ] + res = client.get(f'/prefabs/{test_id}') + assert '200' in res.status + + +def test_update_prefab_missing_parameter(client): + assert '400' in client.put(f'/prefabs/{test_id}').status + + +def test_update_prefab_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.put(f'/prefabs/{test_id}', json={'prefab': {'name': 'S'}}).status + + +def test_update_prefab_not_authorized(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + mocker.patch.object(db, 'update', return_value={}) + assert '403' in client.put(f'/prefabs/{test_id}', json={'prefab': {'name': 'test prefab', 'rack': {}}}).status + + +def test_update_prefab(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': 'test', + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + mocker.patch.object(db, 'update', return_value={}) + res = client.put(f'/prefabs/{test_id}', json={'prefab': {'name': 'test prefab', 'rack': {}}}) + assert '200' in res.status + + +def test_delete_prefab_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.delete(f'/prefabs/{test_id}').status + + +def test_delete_prefab_different_user(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + mocker.patch.object(db, 'delete_one', return_value=None) + assert '403' in client.delete(f'/prefabs/{test_id}').status + + +def test_delete_prefab(client, mocker): + db.fetch_one = Mock() + db.fetch_one.side_effect = [{ + '_id': test_id, + 'name': 'test prefab', + 'authorId': 'test', + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + mocker.patch.object(db, 'delete_one', return_value={'prefab': {'name': 'name'}}) + res = client.delete(f'/prefabs/{test_id}') + assert '200' in res.status diff --git a/opendc-web/opendc-web-api/tests/api/test_projects.py b/opendc-web/opendc-web-api/tests/api/test_projects.py new file mode 100644 index 00000000..c4c82e0d --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_projects.py @@ -0,0 +1,167 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from opendc.exts import db + +test_id = 24 * '1' + + +def test_get_user_projects(client, mocker): + mocker.patch.object(db, 'fetch_all', return_value={'_id': test_id, 'authorizations': [{'userId': 'test', + 'level': 'OWN'}]}) + res = client.get('/projects/') + assert '200' in res.status + + +def test_add_project_missing_parameter(client): + assert '400' in client.post('/projects/').status + + +def test_add_project(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value={'_id': test_id, 'authorizations': []}) + mocker.patch.object(db, + 'insert', + return_value={ + '_id': test_id, + 'datetimeCreated': '000', + 'datetimeLastEdited': '000', + 'topologyIds': [] + }) + mocker.patch.object(db, 'update', return_value={}) + res = client.post('/projects/', json={'project': {'name': 'test project'}}) + assert 'datetimeCreated' in res.json['data'] + assert 'datetimeLastEdited' in res.json['data'] + assert 'topologyIds' in res.json['data'] + assert '200' in res.status + + +def test_get_project_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.get(f'/projects/{test_id}').status + + +def test_get_project_no_authorizations(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value={'authorizations': []}) + res = client.get(f'/projects/{test_id}') + assert '403' in res.status + + +def test_get_project_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'authorizations': [] + }) + res = client.get(f'/projects/{test_id}') + assert '403' in res.status + + +def test_get_project(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'EDIT' + }] + }) + res = client.get(f'/projects/{test_id}') + assert '200' in res.status + + +def test_update_project_missing_parameter(client): + assert '400' in client.put(f'/projects/{test_id}').status + + +def test_update_project_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.put(f'/projects/{test_id}', json={'project': {'name': 'S'}}).status + + +def test_update_project_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'VIEW' + }] + }) + mocker.patch.object(db, 'update', return_value={}) + assert '403' in client.put(f'/projects/{test_id}', json={'project': {'name': 'S'}}).status + + +def test_update_project(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + mocker.patch.object(db, 'update', return_value={}) + + res = client.put(f'/projects/{test_id}', json={'project': {'name': 'S'}}) + assert '200' in res.status + + +def test_delete_project_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.delete(f'/projects/{test_id}').status + + +def test_delete_project_different_user(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'googleId': 'other_test', + 'authorizations': [{ + 'userId': 'test', + 'level': 'VIEW' + }], + 'topologyIds': [] + }) + mocker.patch.object(db, 'delete_one', return_value=None) + assert '403' in client.delete(f'/projects/{test_id}').status + + +def test_delete_project(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'googleId': 'test', + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }], + 'topologyIds': [], + 'portfolioIds': [], + }) + mocker.patch.object(db, 'update', return_value=None) + mocker.patch.object(db, 'delete_one', return_value={'googleId': 'test'}) + res = client.delete(f'/projects/{test_id}') + assert '200' in res.status diff --git a/opendc-web/opendc-web-api/tests/api/test_scenarios.py b/opendc-web/opendc-web-api/tests/api/test_scenarios.py new file mode 100644 index 00000000..bdd5c4a3 --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_scenarios.py @@ -0,0 +1,135 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from opendc.exts import db + +test_id = 24 * '1' +test_id_2 = 24 * '2' + + +def test_get_scenario_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.get(f'/scenarios/{test_id}').status + + +def test_get_scenario_no_authorizations(client, mocker): + m = mocker.MagicMock() + m.side_effect = ({'portfolioId': test_id}, {'projectId': test_id}, {'authorizations': []}) + mocker.patch.object(db, 'fetch_one', m) + res = client.get(f'/scenarios/{test_id}') + assert '403' in res.status + + +def test_get_scenario(client, mocker): + mocker.patch.object(db, + 'fetch_one', + side_effect=[ + {'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'level': 'OWN'}] + }]) + res = client.get(f'/scenarios/{test_id}') + assert '200' in res.status + + +def test_update_scenario_missing_parameter(client): + assert '400' in client.put(f'/scenarios/{test_id}').status + + +def test_update_scenario_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.put(f'/scenarios/{test_id}', json={ + 'scenario': { + 'name': 'test', + } + }).status + + +def test_update_scenario_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + side_effect=[ + {'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'level': 'VIEW'}] + }]) + mocker.patch.object(db, 'update', return_value={}) + assert '403' in client.put(f'/scenarios/{test_id}', json={ + 'scenario': { + 'name': 'test', + } + }).status + + +def test_update_scenario(client, mocker): + mocker.patch.object(db, + 'fetch_one', + side_effect=[ + {'_id': test_id, 'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'level': 'OWN'}] + }]) + mocker.patch.object(db, 'update', return_value={}) + + res = client.put(f'/scenarios/{test_id}', json={'scenario': { + 'name': 'test', + }}) + assert '200' in res.status + + +def test_delete_project_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.delete(f'/scenarios/{test_id}').status + + +def test_delete_project_different_user(client, mocker): + mocker.patch.object(db, + 'fetch_one', + side_effect=[ + {'_id': test_id, 'portfolioId': test_id}, + {'projectId': test_id}, + {'authorizations': + [{'userId': 'test', 'level': 'VIEW'}] + }]) + mocker.patch.object(db, 'delete_one', return_value=None) + assert '403' in client.delete(f'/scenarios/{test_id}').status + + +def test_delete_project(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, + 'googleId': 'test', + 'scenarioIds': [test_id], + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + mocker.patch.object(db, 'delete_one', return_value={}) + mocker.patch.object(db, 'update', return_value=None) + res = client.delete(f'/scenarios/{test_id}') + assert '200' in res.status diff --git a/opendc-web/opendc-web-api/tests/api/test_schedulers.py b/opendc-web/opendc-web-api/tests/api/test_schedulers.py new file mode 100644 index 00000000..5d9e6995 --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_schedulers.py @@ -0,0 +1,22 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +def test_get_schedulers(client): + assert '200' in client.get('/schedulers/').status diff --git a/opendc-web/opendc-web-api/tests/api/test_topologies.py b/opendc-web/opendc-web-api/tests/api/test_topologies.py new file mode 100644 index 00000000..6e7c54ef --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_topologies.py @@ -0,0 +1,140 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from opendc.exts import db + +test_id = 24 * '1' +test_id_2 = 24 * '2' + + +def test_get_topology(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'EDIT' + }] + }) + res = client.get(f'/topologies/{test_id}') + assert '200' in res.status + + +def test_get_topology_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.get('/topologies/1').status + + +def test_get_topology_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [] + }) + res = client.get(f'/topologies/{test_id}') + assert '403' in res.status + + +def test_get_topology_no_authorizations(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value={'projectId': test_id, 'authorizations': []}) + res = client.get(f'/topologies/{test_id}') + assert '403' in res.status + + +def test_update_topology_missing_parameter(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [] + }) + assert '400' in client.put(f'/topologies/{test_id}').status + + +def test_update_topology_non_existent(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.put(f'/topologies/{test_id}', json={'topology': {'name': 'test_topology', 'rooms': []}}).status + + +def test_update_topology_not_authorized(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [] + }) + mocker.patch.object(db, 'update', return_value={}) + assert '403' in client.put(f'/topologies/{test_id}', json={ + 'topology': { + 'name': 'updated_topology', + 'rooms': [] + } + }).status + + +def test_update_topology(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + mocker.patch.object(db, 'update', return_value={}) + + assert '200' in client.put(f'/topologies/{test_id}', json={ + 'topology': { + 'name': 'updated_topology', + 'rooms': [] + } + }).status + + +def test_delete_topology(client, mocker): + mocker.patch.object(db, + 'fetch_one', + return_value={ + '_id': test_id, + 'projectId': test_id, + 'googleId': 'test', + 'topologyIds': [test_id], + 'authorizations': [{ + 'userId': 'test', + 'level': 'OWN' + }] + }) + mocker.patch.object(db, 'delete_one', return_value={}) + mocker.patch.object(db, 'update', return_value=None) + res = client.delete(f'/topologies/{test_id}') + assert '200' in res.status + + +def test_delete_nonexistent_topology(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.delete(f'/topologies/{test_id}').status diff --git a/opendc-web/opendc-web-api/tests/api/test_traces.py b/opendc-web/opendc-web-api/tests/api/test_traces.py new file mode 100644 index 00000000..0b252c2f --- /dev/null +++ b/opendc-web/opendc-web-api/tests/api/test_traces.py @@ -0,0 +1,40 @@ +# Copyright (c) 2021 AtLarge Research +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from opendc.exts import db + +test_id = 24 * '1' + + +def test_get_traces(client, mocker): + mocker.patch.object(db, 'fetch_all', return_value=[]) + assert '200' in client.get('/traces/').status + + +def test_get_trace_non_existing(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value=None) + assert '404' in client.get(f'/traces/{test_id}').status + + +def test_get_trace(client, mocker): + mocker.patch.object(db, 'fetch_one', return_value={'name': 'test trace'}) + res = client.get(f'/traces/{test_id}') + assert 'name' in res.json['data'] + assert '200' in res.status diff --git a/opendc-web/opendc-web-ui/src/shapes.js b/opendc-web/opendc-web-ui/src/shapes.js index 621c7d25..9aeb99d8 100644 --- a/opendc-web/opendc-web-ui/src/shapes.js +++ b/opendc-web/opendc-web-ui/src/shapes.js @@ -23,7 +23,7 @@ export const Authorization = PropTypes.shape({ user: User, projectId: PropTypes.string.isRequired, project: Project, - authorizationLevel: PropTypes.string.isRequired, + level: PropTypes.string.isRequired, }) export const ProcessingUnit = PropTypes.shape({ -- cgit v1.2.3 From 5c710d329b16efb947a6d25793f6a0f7865f3df1 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 11:43:03 +0200 Subject: api: Add Swagger UI for API documentation This change adds Swagger UI to the REST API endpoint in order to experiment with the API endpoints interactively. It also serves as the documentation for the API endpoints. --- opendc-api-spec.yml | 16 ++++++++++++- opendc-web/opendc-web-api/app.py | 35 ++++++++++++++++++++++++++--- opendc-web/opendc-web-api/requirements.txt | 1 + opendc-web/opendc-web-api/static/schema.yml | 1 + 4 files changed, 49 insertions(+), 4 deletions(-) create mode 120000 opendc-web/opendc-web-api/static/schema.yml diff --git a/opendc-api-spec.yml b/opendc-api-spec.yml index 1f7c5697..c23b2f3d 100644 --- a/opendc-api-spec.yml +++ b/opendc-api-spec.yml @@ -3,11 +3,25 @@ info: version: 2.0.0 title: OpenDC API description: 'OpenDC is an open-source datacenter simulator for education, featuring real-time online collaboration, diverse simulation models, and detailed performance feedback statistics.' -host: opendc.org +host: api.opendc.org basePath: /v2 schemes: - https +security: + - auth0: + - openid + +securityDefinitions: + auth0: + type: oauth2 + scopes: + openid: Grants access to user_id + flow: accessCode + authorizationUrl: https://opendc.eu.auth0.com/authorize + tokenUrl: https://opendc.eu.auth0.com/oauth/token + x-token-validation-url: https://opendc.eu.auth0.com/userinfo + paths: '/projects': get: diff --git a/opendc-web/opendc-web-api/app.py b/opendc-web/opendc-web-api/app.py index 5041457f..c05e56b5 100755 --- a/opendc-web/opendc-web-api/app.py +++ b/opendc-web/opendc-web-api/app.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 +import mimetypes import os from dotenv import load_dotenv -from flask import Flask, jsonify +from flask import Flask, jsonify, redirect from flask_compress import Compress from flask_cors import CORS from flask_restful import Api +from flask_swagger_ui import get_swaggerui_blueprint from marshmallow import ValidationError from opendc.api.portfolios import Portfolio, PortfolioScenarios @@ -72,13 +74,33 @@ def setup_api(app): return api +def setup_swagger(app): + """ + Setup Swagger UI + """ + SWAGGER_URL = '/docs' + API_URL = '../schema.yml' + + swaggerui_blueprint = get_swaggerui_blueprint( + SWAGGER_URL, + API_URL, + config={ + 'app_name': "OpenDC API v2" + } + ) + app.register_blueprint(swaggerui_blueprint) + + def create_app(testing=False): - app = Flask(__name__) + app = Flask(__name__, static_url_path='/') app.config['TESTING'] = testing app.config['SECRET_KEY'] = os.environ['OPENDC_FLASK_SECRET'] app.config['RESTFUL_JSON'] = {'cls': JSONEncoder} app.json_encoder = JSONEncoder + # Define YAML content type + mimetypes.add_type('text/yaml', '.yml') + # Setup Sentry if DSN is specified setup_sentry() @@ -89,8 +111,15 @@ def create_app(testing=False): compress = Compress() compress.init_app(app) - # Setup API setup_api(app) + setup_swagger(app) + + @app.route('/') + def index(): + """ + Redirect the user to the API documentation if it accesses the API root. + """ + return redirect('docs/') return app diff --git a/opendc-web/opendc-web-api/requirements.txt b/opendc-web/opendc-web-api/requirements.txt index 375ed40c..bbad97d0 100644 --- a/opendc-web/opendc-web-api/requirements.txt +++ b/opendc-web/opendc-web-api/requirements.txt @@ -9,6 +9,7 @@ Flask==1.1.2 Flask-Compress==1.5.0 Flask-Cors==3.0.9 Flask-SocketIO==4.3.1 +flask-swagger-ui==3.36.0 Flask-Restful==0.3.8 greenlet==0.4.17 httplib2==0.19.0 diff --git a/opendc-web/opendc-web-api/static/schema.yml b/opendc-web/opendc-web-api/static/schema.yml new file mode 120000 index 00000000..153ad9dc --- /dev/null +++ b/opendc-web/opendc-web-api/static/schema.yml @@ -0,0 +1 @@ +../../../opendc-api-spec.yml \ No newline at end of file -- cgit v1.2.3 From 6412610f38117e1ea0635a56fa023183723fa67a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 12:43:48 +0200 Subject: api: Update API Schema to OpenAPI v3 This change updates the API Schema to the more recent OpenAPI version 3 and in addition actualizes the API specification to match the API again. --- opendc-api-spec.yml | 788 +--------------- opendc-web/opendc-web-api/static/schema.yml | 1294 ++++++++++++++++++++++++++- 2 files changed, 1294 insertions(+), 788 deletions(-) mode change 100644 => 120000 opendc-api-spec.yml mode change 120000 => 100644 opendc-web/opendc-web-api/static/schema.yml diff --git a/opendc-api-spec.yml b/opendc-api-spec.yml deleted file mode 100644 index c23b2f3d..00000000 --- a/opendc-api-spec.yml +++ /dev/null @@ -1,787 +0,0 @@ -swagger: '2.0' -info: - version: 2.0.0 - title: OpenDC API - description: 'OpenDC is an open-source datacenter simulator for education, featuring real-time online collaboration, diverse simulation models, and detailed performance feedback statistics.' -host: api.opendc.org -basePath: /v2 -schemes: - - https - -security: - - auth0: - - openid - -securityDefinitions: - auth0: - type: oauth2 - scopes: - openid: Grants access to user_id - flow: accessCode - authorizationUrl: https://opendc.eu.auth0.com/authorize - tokenUrl: https://opendc.eu.auth0.com/oauth/token - x-token-validation-url: https://opendc.eu.auth0.com/userinfo - -paths: - '/projects': - get: - tags: - - projects - description: List Projects of the active user - responses: - '200': - description: Successfully - schema: - type: array - items: - $ref: '#/definitions/Project' - '401': - description: Unauthorized. - post: - tags: - - projects - description: Add a Project. - parameters: - - name: project - in: body - description: The new Project. - required: true - schema: - properties: - name: - type: string - responses: - '200': - description: Successfully added Project. - schema: - $ref: '#/definitions/Project' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '/projects/{projectId}': - get: - tags: - - projects - description: Get this Project. - parameters: - - name: projectId - in: path - description: Project's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Project. - schema: - $ref: '#/definitions/Project' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from retrieving Project. - '404': - description: Project not found - put: - tags: - - projects - description: Update this Project. - parameters: - - name: projectId - in: path - description: Project's ID. - required: true - type: string - - name: project - in: body - description: Project's new properties. - required: true - schema: - properties: - project: - $ref: '#/definitions/Project' - responses: - '200': - description: Successfully updated Project. - schema: - $ref: '#/definitions/Project' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from updating Project. - '404': - description: Project not found. - delete: - tags: - - projects - description: Delete this project. - parameters: - - name: projectId - in: path - description: Project's ID. - required: true - type: string - responses: - '200': - description: Successfully deleted Project. - schema: - $ref: '#/definitions/Project' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from deleting Project. - '404': - description: Project not found. - '/projects/{projectId}/topologies': - post: - tags: - - projects - description: Add a Topology. - parameters: - - name: projectId - in: path - description: Project's ID. - required: true - type: string - - name: topology - in: body - description: The new Topology. - required: true - schema: - properties: - topology: - $ref: '#/definitions/Topology' - responses: - '200': - description: Successfully added Topology. - schema: - $ref: '#/definitions/Topology' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '/projects/{projectId}/portfolios': - post: - tags: - - portfolios - description: Add a Portfolio. - parameters: - - name: projectId - in: path - description: Project's ID. - required: true - type: string - - name: portfolio - in: body - description: The new Portfolio. - required: true - schema: - properties: - topology: - $ref: '#/definitions/Portfolio' - responses: - '200': - description: Successfully added Portfolio. - schema: - $ref: '#/definitions/Portfolio' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '/topologies/{topologyId}': - get: - tags: - - topologies - description: Get this Topology. - parameters: - - name: topologyId - in: path - description: Topology's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Topology. - schema: - $ref: '#/definitions/Topology' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from retrieving Topology. - '404': - description: Topology not found. - put: - tags: - - topologies - description: Update this Topology's name. - parameters: - - name: topologyId - in: path - description: Topology's ID. - required: true - type: string - - name: topology - in: body - description: Topology's new properties. - required: true - schema: - properties: - topology: - $ref: '#/definitions/Topology' - responses: - '200': - description: Successfully updated Topology. - schema: - $ref: '#/definitions/Topology' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from updating Topology. - '404': - description: Topology not found. - delete: - tags: - - topologies - description: Delete this Topology. - parameters: - - name: topologyId - in: path - description: Topology's ID. - required: true - type: string - responses: - '200': - description: Successfully deleted Topology. - schema: - $ref: '#/definitions/Topology' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from deleting Topology. - '404': - description: Topology not found. - '/portfolios/{portfolioId}': - get: - tags: - - portfolios - description: Get this Portfolio. - parameters: - - name: portfolioId - in: path - description: Portfolio's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Portfolio. - schema: - $ref: '#/definitions/Portfolio' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from retrieving Portfolio. - '404': - description: Portfolio not found. - put: - tags: - - portfolios - description: "Update this Portfolio." - parameters: - - name: portfolioId - in: path - description: Portfolio's ID. - required: true - type: string - - name: portfolio - in: body - description: Portfolio's new properties. - required: true - schema: - $ref: '#/definitions/Portfolio' - responses: - '200': - description: Successfully updated Portfolio. - schema: - $ref: '#/definitions/Portfolio' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from updating Portfolio. - '404': - description: 'Portfolio not found.' - delete: - tags: - - portfolios - description: Delete this Portfolio. - parameters: - - name: portfolioId - in: path - description: Portfolio's ID. - required: true - type: string - responses: - '200': - description: Successfully deleted Portfolio. - schema: - $ref: '#/definitions/Portfolio' - '401': - description: Unauthorized. - '403': - description: Forbidden from deleting Portfolio. - '404': - description: Portfolio not found. - '/scenarios/{scenarioId}': - get: - tags: - - scenarios - description: Get this Scenario. - parameters: - - name: scenarioId - in: path - description: Scenario's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Scenario. - schema: - $ref: '#/definitions/Scenario' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from retrieving Scenario. - '404': - description: Scenario not found. - put: - tags: - - scenarios - description: "Update this Scenario's name (other properties are read-only)." - parameters: - - name: scenarioId - in: path - description: Scenario's ID. - required: true - type: string - - name: scenario - in: body - description: Scenario with new name. - required: true - schema: - $ref: '#/definitions/Scenario' - responses: - '200': - description: Successfully updated Scenario. - schema: - $ref: '#/definitions/Scenario' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from updating Scenario. - '404': - description: 'Scenario not found.' - delete: - tags: - - scenarios - description: Delete this Scenario. - parameters: - - name: scenarioId - in: path - description: Scenario's ID. - required: true - type: string - responses: - '200': - description: Successfully deleted Scenario. - schema: - $ref: '#/definitions/Scenario' - '401': - description: Unauthorized. - '403': - description: Forbidden from deleting Scenario. - '404': - description: Scenario not found. - /schedulers: - get: - tags: - - simulation - description: Get all available Schedulers - responses: - '200': - description: Successfully retrieved Schedulers. - schema: - type: array - items: - $ref: '#/definitions/Scheduler' - '401': - description: Unauthorized. - /traces: - get: - tags: - - simulation - description: Get all available Traces (non-populated). - responses: - '200': - description: Successfully retrieved Traces (non-populated). - schema: - type: array - items: - type: object - properties: - _id: - type: string - name: - type: string - '401': - description: Unauthorized. - '/traces/{traceId}': - get: - tags: - - simulation - description: Get this Trace. - parameters: - - name: traceId - in: path - description: Trace's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Trace. - schema: - $ref: '#/definitions/Trace' - '401': - description: Unauthorized. - '404': - description: Trace not found. - /prefabs: - post: - tags: - - prefabs - description: Add a Prefab. - parameters: - - name: prefab - in: body - description: The new Prefab. - required: true - schema: - properties: - name: - type: string - responses: - '200': - description: Successfully added Prefab. - schema: - $ref: '#/definitions/Prefab' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '/prefabs/{prefabId}': - get: - tags: - - prefabs - description: Get this Prefab. - parameters: - - name: prefabId - in: path - description: Prefab's ID. - required: true - type: string - responses: - '200': - description: Successfully retrieved Prefab. - schema: - $ref: '#/definitions/Prefab' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from retrieving Prefab. - '404': - description: Prefab not found - put: - tags: - - prefabs - description: Update this Prefab. - parameters: - - name: prefabId - in: path - description: Prefab's ID. - required: true - type: string - - name: prefab - in: body - description: Prefab's new properties. - required: true - schema: - properties: - project: - $ref: '#/definitions/Prefab' - responses: - '200': - description: Successfully updated Prefab. - schema: - $ref: '#/definitions/Prefab' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from updating Prefab. - '404': - description: Prefab not found. - delete: - tags: - - prefabs - description: Delete this prefab. - parameters: - - name: prefabId - in: path - description: Prefab's ID. - required: true - type: string - responses: - '200': - description: Successfully deleted Prefab. - schema: - $ref: '#/definitions/Prefab' - '400': - description: Missing or incorrectly typed parameter. - '401': - description: Unauthorized. - '403': - description: Forbidden from deleting Prefab. - '404': - description: Prefab not found. - '/prefabs/authorizations': - get: - tags: - - prefabs - description: Get all Prefabs the user has rights to view. - responses: - '200': - description: Successfully retrieved prefabs the user is authorized on. - schema: - $ref: '#/definitions/Prefab' - '400': - description: Missing or incorrectly typed parameter. - '404': - description: Prefab or userId not found - -definitions: - Scheduler: - type: object - properties: - name: - type: string - Project: - type: object - properties: - _id: - type: string - name: - type: string - datetimeCreated: - type: string - format: dateTime - datetimeLastEdited: - type: string - format: dateTime - topologyIds: - type: array - items: - type: string - portfolioIds: - type: array - items: - type: string - Topology: - type: object - properties: - _id: - type: string - projectId: - type: string - name: - type: string - rooms: - type: array - items: - type: object - properties: - _id: - type: string - name: - type: string - tiles: - type: array - items: - type: object - properties: - _id: - type: string - positionX: - type: integer - positionY: - type: integer - object: - type: object - properties: - capacity: - type: integer - powerCapacityW: - type: integer - machines: - type: array - items: - type: object - properties: - position: - type: integer - cpuItems: - type: array - items: - type: object - properties: - name: - type: string - clockRateMhz: - type: integer - numberOfCores: - type: integer - gpuItems: - type: array - items: - type: object - properties: - name: - type: string - clockRateMhz: - type: integer - numberOfCores: - type: integer - memoryItems: - type: array - items: - type: object - properties: - name: - type: string - speedMbPerS: - type: integer - sizeMb: - type: integer - storageItems: - type: array - items: - type: integer - properties: - name: - type: string - speedMbPerS: - type: integer - sizeMb: - type: integer - Portfolio: - type: object - properties: - _id: - type: string - projectId: - type: string - name: - type: string - scenarioIds: - type: array - items: - type: string - targets: - type: object - properties: - enabledMetrics: - type: array - items: - type: string - repeatsPerScenario: - type: integer - Scenario: - type: object - properties: - _id: - type: string - portfolioId: - type: string - name: - type: string - simulation: - type: object - properties: - state: - type: string - results: - type: object - trace: - type: object - properties: - traceId: - type: string - loadSamplingFraction: - type: number - topology: - type: object - properties: - topologyId: - type: string - operational: - type: object - properties: - failuresEnabled: - type: boolean - performanceInterferenceEnabled: - type: boolean - schedulerName: - type: string - Trace: - type: object - properties: - _id: - type: string - name: - type: string - path: - type: string - type: - type: string - Prefab: - type: object - properties: - _id: - type: string - name: - type: string - datetimeCreated: - type: string - format: dateTime - datetimeLastEdited: - type: string - format: dateTime diff --git a/opendc-api-spec.yml b/opendc-api-spec.yml new file mode 120000 index 00000000..ca5a3b0c --- /dev/null +++ b/opendc-api-spec.yml @@ -0,0 +1 @@ +opendc-web/opendc-web-api/static/schema.yml \ No newline at end of file diff --git a/opendc-web/opendc-web-api/static/schema.yml b/opendc-web/opendc-web-api/static/schema.yml deleted file mode 120000 index 153ad9dc..00000000 --- a/opendc-web/opendc-web-api/static/schema.yml +++ /dev/null @@ -1 +0,0 @@ -../../../opendc-api-spec.yml \ No newline at end of file diff --git a/opendc-web/opendc-web-api/static/schema.yml b/opendc-web/opendc-web-api/static/schema.yml new file mode 100644 index 00000000..99e88095 --- /dev/null +++ b/opendc-web/opendc-web-api/static/schema.yml @@ -0,0 +1,1293 @@ +openapi: 3.0.0 +info: + version: 2.1.0 + title: OpenDC REST API v2 + description: OpenDC is an open-source datacenter simulator for education, featuring + real-time online collaboration, diverse simulation models, and detailed + performance feedback statistics. + license: + name: MIT + url: https://spdx.org/licenses/MIT + contact: + name: Support + url: https://opendc.org +servers: + - url: https://api.opendc.org/v2 +externalDocs: + description: OpenDC REST API v2 + url: https://api.opendc.com/v2/docs/ +security: + - auth0: + - openid +paths: + /projects: + get: + tags: + - projects + description: List Projects of the active user + responses: + "200": + description: Successfully + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: "#/components/schemas/Project" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + post: + tags: + - projects + description: Add a Project. + requestBody: + content: + application/json: + schema: + properties: + name: + type: string + description: The new Project. + required: true + responses: + "200": + description: Successfully added Project. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Project" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "/projects/{projectId}": + get: + tags: + - projects + description: Get this Project. + parameters: + - name: projectId + in: path + description: Project's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully retrieved Project. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Project" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Project. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Project not found + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + put: + tags: + - projects + description: Update this Project. + parameters: + - name: projectId + in: path + description: Project's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + project: + $ref: "#/components/schemas/Project" + description: Project's new properties. + required: true + responses: + "200": + description: Successfully updated Project. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Project" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from updating Project. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Project not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + delete: + tags: + - projects + description: Delete this project. + parameters: + - name: projectId + in: path + description: Project's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully deleted Project. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Project" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from deleting Project. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Project not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + "/projects/{projectId}/topologies": + post: + tags: + - projects + description: Add a Topology. + parameters: + - name: projectId + in: path + description: Project's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + topology: + $ref: "#/components/schemas/Topology" + description: The new Topology. + required: true + responses: + "200": + description: Successfully added Topology. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Topology" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "404": + description: Project not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + "/projects/{projectId}/portfolios": + post: + tags: + - portfolios + description: Add a Portfolio. + parameters: + - name: projectId + in: path + description: Project's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + topology: + $ref: "#/components/schemas/Portfolio" + description: The new Portfolio. + required: true + responses: + "200": + description: Successfully added Portfolio. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Portfolio" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "404": + description: Project not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + "/topologies/{topologyId}": + get: + tags: + - topologies + description: Get this Topology. + parameters: + - name: topologyId + in: path + description: Topology's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully retrieved Topology. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Topology" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Topology. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Topology not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + put: + tags: + - topologies + description: Update this Topology's name. + parameters: + - name: topologyId + in: path + description: Topology's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + topology: + $ref: "#/components/schemas/Topology" + description: Topology's new properties. + required: true + responses: + "200": + description: Successfully updated Topology. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Topology" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Project. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Project not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + delete: + tags: + - topologies + description: Delete this Topology. + parameters: + - name: topologyId + in: path + description: Topology's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully deleted Topology. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Topology" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from deleting Topology. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Topology not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + "/portfolios/{portfolioId}": + get: + tags: + - portfolios + description: Get this Portfolio. + parameters: + - name: portfolioId + in: path + description: Portfolio's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully retrieved Portfolio. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Portfolio" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Portfolio. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Portfolio not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + put: + tags: + - portfolios + description: Update this Portfolio. + parameters: + - name: portfolioId + in: path + description: Portfolio's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Portfolio" + description: Portfolio's new properties. + required: true + responses: + "200": + description: Successfully updated Portfolio. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Portfolio" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Portfolio. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Portfolio not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + delete: + tags: + - portfolios + description: Delete this Portfolio. + parameters: + - name: portfolioId + in: path + description: Portfolio's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully deleted Portfolio. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Portfolio" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Portfolio. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Portfolio not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + "/scenarios/{scenarioId}": + get: + tags: + - scenarios + description: Get this Scenario. + parameters: + - name: scenarioId + in: path + description: Scenario's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully retrieved Scenario. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Scenario" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Scenario. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Scenario not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + put: + tags: + - scenarios + description: Update this Scenario's name (other properties are read-only). + parameters: + - name: scenarioId + in: path + description: Scenario's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Scenario" + description: Scenario with new name. + required: true + responses: + "200": + description: Successfully updated Scenario. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Scenario" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Scenario. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Scenario not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + delete: + tags: + - scenarios + description: Delete this Scenario. + parameters: + - name: scenarioId + in: path + description: Scenario's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully deleted Scenario. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Scenario" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Scenario. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Scenario not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + /schedulers: + get: + tags: + - simulation + description: Get all available Schedulers + responses: + "200": + description: Successfully retrieved Schedulers. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: "#/components/schemas/Scheduler" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + /traces: + get: + tags: + - simulation + description: Get all available Traces + responses: + "200": + description: Successfully retrieved Traces. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + type: array + items: + type: object + properties: + _id: + type: string + name: + type: string + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "/traces/{traceId}": + get: + tags: + - simulation + description: Get this Trace. + parameters: + - name: traceId + in: path + description: Trace's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully retrieved Trace. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Trace" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "404": + description: Trace not found + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + /prefabs: + get: + tags: + - prefabs + description: Get all Prefabs the user has rights to view. + responses: + "200": + description: Successfully retrieved prefabs the user is authorized on. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: "#/components/schemas/Prefab" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + post: + tags: + - prefabs + description: Add a Prefab. + requestBody: + content: + application/json: + schema: + properties: + name: + type: string + description: The new Prefab. + required: true + responses: + "200": + description: Successfully added Prefab. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Prefab" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "/prefabs/{prefabId}": + get: + tags: + - prefabs + description: Get this Prefab. + parameters: + - name: prefabId + in: path + description: Prefab's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully retrieved Prefab. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Prefab" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Prefab. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Prefab not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + put: + tags: + - prefabs + description: Update this Prefab. + parameters: + - name: prefabId + in: path + description: Prefab's ID. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + project: + $ref: "#/components/schemas/Prefab" + description: Prefab's new properties. + required: true + responses: + "200": + description: Successfully updated Prefab. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Prefab" + "400": + description: Missing or incorrectly typed parameter. + content: + "application/json": + schema: + $ref: "#/components/schemas/Invalid" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "403": + description: Forbidden from retrieving Prefab. + content: + "application/json": + schema: + $ref: "#/components/schemas/Forbidden" + "404": + description: Prefab not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" + delete: + tags: + - prefabs + description: Delete this prefab. + parameters: + - name: prefabId + in: path + description: Prefab's ID. + required: true + schema: + type: string + responses: + "200": + description: Successfully deleted Prefab. + content: + "application/json": + schema: + type: object + required: + - data + properties: + data: + $ref: "#/components/schemas/Prefab" + "401": + description: Unauthorized. + content: + "application/json": + schema: + $ref: "#/components/schemas/Unauthorized" + "404": + description: Prefab not found. + content: + "application/json": + schema: + $ref: "#/components/schemas/NotFound" +components: + securitySchemes: + auth0: + type: oauth2 + x-token-validation-url: https://opendc.eu.auth0.com/userinfo + flows: + authorizationCode: + authorizationUrl: https://opendc.eu.auth0.com/authorize + tokenUrl: https://opendc.eu.auth0.com/oauth/token + scopes: + openid: Grants access to user_id + schemas: + Unauthorized: + type: object + required: + - message + properties: + message: + type: string + Invalid: + type: object + required: + - message + - errors + properties: + message: + type: string + errors: + type: array + items: + type: string + Forbidden: + type: object + required: + - message + properties: + message: + type: string + NotFound: + type: object + required: + - message + properties: + message: + type: string + Scheduler: + type: object + properties: + name: + type: string + Project: + type: object + properties: + _id: + type: string + name: + type: string + datetimeCreated: + type: string + format: dateTime + datetimeLastEdited: + type: string + format: dateTime + topologyIds: + type: array + items: + type: string + portfolioIds: + type: array + items: + type: string + authorizations: + type: array + items: + type: object + properties: + userId: + type: string + level: + type: string + enum: ['OWN', 'EDIT', 'VIEW'] + Topology: + type: object + properties: + _id: + type: string + projectId: + type: string + name: + type: string + rooms: + type: array + items: + type: object + properties: + _id: + type: string + name: + type: string + tiles: + type: array + items: + type: object + properties: + _id: + type: string + positionX: + type: integer + positionY: + type: integer + object: + type: object + properties: + capacity: + type: integer + powerCapacityW: + type: integer + machines: + type: array + items: + type: object + properties: + position: + type: integer + cpuItems: + type: array + items: + type: object + properties: + name: + type: string + clockRateMhz: + type: integer + numberOfCores: + type: integer + gpuItems: + type: array + items: + type: object + properties: + name: + type: string + clockRateMhz: + type: integer + numberOfCores: + type: integer + memoryItems: + type: array + items: + type: object + properties: + name: + type: string + speedMbPerS: + type: integer + sizeMb: + type: integer + storageItems: + type: array + items: + type: integer + properties: + name: + type: string + speedMbPerS: + type: integer + sizeMb: + type: integer + Portfolio: + type: object + properties: + _id: + type: string + projectId: + type: string + name: + type: string + scenarioIds: + type: array + items: + type: string + targets: + type: object + properties: + enabledMetrics: + type: array + items: + type: string + repeatsPerScenario: + type: integer + Scenario: + type: object + properties: + _id: + type: string + portfolioId: + type: string + name: + type: string + simulation: + type: object + properties: + state: + type: string + results: + type: object + trace: + type: object + properties: + traceId: + type: string + loadSamplingFraction: + type: number + topology: + type: object + properties: + topologyId: + type: string + operational: + type: object + properties: + failuresEnabled: + type: boolean + performanceInterferenceEnabled: + type: boolean + schedulerName: + type: string + Trace: + type: object + properties: + _id: + type: string + name: + type: string + path: + type: string + type: + type: string + Prefab: + type: object + properties: + _id: + type: string + name: + type: string + datetimeCreated: + type: string + format: dateTime + datetimeLastEdited: + type: string + format: dateTime -- cgit v1.2.3 From a6865b86cc8d710374fc0b6cfcbd2b863f1942a9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 23:18:02 +0200 Subject: ui: Migrate to Auth0 as Identity Provider This change updates the frontend codebase to move away from the Google login and instead use Auth0 as generic Identity Provider. This allows users to login with other accounts as well. Since Auth0 has a free tier, users can experiment themselves with OpenDC locally without having to pay for the login functionality. The code has been written so that we should be able to migrate away from Auth0 once it is not a suitable Identity Provider for OpenDC anymore. --- opendc-web/opendc-web-ui/package.json | 3 +- opendc-web/opendc-web-ui/src/api/index.js | 20 ++-- opendc-web/opendc-web-ui/src/api/portfolios.js | 16 +-- opendc-web/opendc-web-ui/src/api/prefabs.js | 16 +-- opendc-web/opendc-web-ui/src/api/projects.js | 20 ++-- opendc-web/opendc-web-ui/src/api/scenarios.js | 16 +-- opendc-web/opendc-web-ui/src/api/schedulers.js | 4 +- opendc-web/opendc-web-ui/src/api/token-signin.js | 32 ------ opendc-web/opendc-web-ui/src/api/topologies.js | 16 +-- opendc-web/opendc-web-ui/src/api/traces.js | 4 +- opendc-web/opendc-web-ui/src/api/users.js | 39 ------- opendc-web/opendc-web-ui/src/auth.js | 124 +++++++++------------ .../src/components/navigation/Navbar.js | 16 ++- .../src/components/projects/ProjectList.js | 12 +- .../src/components/projects/ProjectRow.js | 31 +++--- .../app/sidebars/project/ScenarioListContainer.js | 2 +- .../opendc-web-ui/src/containers/auth/Login.js | 35 +----- .../opendc-web-ui/src/containers/auth/Logout.js | 7 +- .../src/containers/auth/ProfileName.js | 10 +- .../containers/projects/ProjectListContainer.js | 34 ++++++ .../containers/projects/VisibleProjectAuthList.js | 37 ------ opendc-web/opendc-web-ui/src/data/project.js | 7 ++ opendc-web/opendc-web-ui/src/pages/_app.js | 20 +++- opendc-web/opendc-web-ui/src/pages/logout.js | 39 +++++++ opendc-web/opendc-web-ui/src/pages/profile.js | 76 ------------- .../opendc-web-ui/src/pages/projects/index.js | 8 +- opendc-web/opendc-web-ui/src/redux/actions/auth.js | 23 ---- .../opendc-web-ui/src/redux/actions/projects.js | 29 +++-- .../opendc-web-ui/src/redux/actions/users.js | 37 ------ opendc-web/opendc-web-ui/src/redux/index.js | 26 ++--- .../opendc-web-ui/src/redux/reducers/auth.js | 12 -- .../opendc-web-ui/src/redux/reducers/index.js | 6 +- .../src/redux/reducers/project-list.js | 18 --- .../opendc-web-ui/src/redux/reducers/projects.js | 14 +++ opendc-web/opendc-web-ui/src/redux/sagas/index.js | 14 +-- .../opendc-web-ui/src/redux/sagas/objects.js | 25 +++-- .../opendc-web-ui/src/redux/sagas/portfolios.js | 19 ++-- .../opendc-web-ui/src/redux/sagas/prefabs.js | 5 +- .../opendc-web-ui/src/redux/sagas/profile.js | 12 -- .../opendc-web-ui/src/redux/sagas/projects.js | 35 +++--- .../opendc-web-ui/src/redux/sagas/scenarios.js | 14 ++- .../opendc-web-ui/src/redux/sagas/topology.js | 7 +- opendc-web/opendc-web-ui/src/redux/sagas/users.js | 44 -------- opendc-web/opendc-web-ui/src/shapes.js | 22 ++++ opendc-web/opendc-web-ui/yarn.lock | 74 +++++++++--- 45 files changed, 448 insertions(+), 632 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/api/token-signin.js delete mode 100644 opendc-web/opendc-web-ui/src/api/users.js create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js create mode 100644 opendc-web/opendc-web-ui/src/pages/logout.js delete mode 100644 opendc-web/opendc-web-ui/src/pages/profile.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/actions/auth.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/actions/users.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/auth.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/project-list.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/projects.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/profile.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/users.js diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index f6917398..9c41c2e2 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -17,6 +17,7 @@ "license": "MIT", "private": true, "dependencies": { + "@auth0/auth0-react": "^1.5.0", "@sentry/react": "^5.30.0", "@sentry/tracing": "^5.30.0", "approximate-number": "~2.0.0", @@ -32,14 +33,12 @@ "react": "~17.0.2", "react-dom": "~17.0.2", "react-fontawesome": "~1.7.1", - "react-google-login": "~5.1.14", "react-hotkeys": "^2.0.0", "react-konva": "~17.0.2-0", "react-redux": "~7.2.0", "reactstrap": "^8.9.0", "recharts": "~2.0.9", "redux": "~4.0.5", - "redux-localstorage": "^0.4.1", "redux-logger": "~3.0.6", "redux-saga": "~1.1.3", "redux-thunk": "~2.3.0", diff --git a/opendc-web/opendc-web-ui/src/api/index.js b/opendc-web/opendc-web-ui/src/api/index.js index 65358745..680d49ce 100644 --- a/opendc-web/opendc-web-ui/src/api/index.js +++ b/opendc-web/opendc-web-ui/src/api/index.js @@ -20,30 +20,32 @@ * SOFTWARE. */ -import { getAuthToken } from '../auth' - const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL /** * Send the specified request to the OpenDC API. + * + * @param auth The authentication context. * @param path Relative path for the API. * @param method The method to use for the request. * @param body The body of the request. */ -export async function request(path, method = 'GET', body) { - const res = await fetch(`${apiUrl}/v2/${path}`, { +export async function request(auth, path, method = 'GET', body) { + const { getAccessTokenSilently } = auth + const token = await getAccessTokenSilently() + const response = await fetch(`${apiUrl}/${path}`, { method: method, headers: { - 'auth-token': getAuthToken(), + Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, body: body && JSON.stringify(body), }) - const { status, content } = await res.json() + const json = await response.json() - if (status.code !== 200) { - throw status + if (!response.ok) { + throw response.message } - return content + return json.data } diff --git a/opendc-web/opendc-web-ui/src/api/portfolios.js b/opendc-web/opendc-web-ui/src/api/portfolios.js index 6202e702..28898e6a 100644 --- a/opendc-web/opendc-web-ui/src/api/portfolios.js +++ b/opendc-web/opendc-web-ui/src/api/portfolios.js @@ -22,18 +22,18 @@ import { request } from './index' -export function addPortfolio(projectId, portfolio) { - return request(`projects/${projectId}/portfolios`, 'POST', { portfolio }) +export function addPortfolio(auth, projectId, portfolio) { + return request(auth, `projects/${projectId}/portfolios`, 'POST', { portfolio }) } -export function getPortfolio(portfolioId) { - return request(`portfolios/${portfolioId}`) +export function getPortfolio(auth, portfolioId) { + return request(auth, `portfolios/${portfolioId}`) } -export function updatePortfolio(portfolioId, portfolio) { - return request(`portfolios/${portfolioId}`, 'PUT', { portfolio }) +export function updatePortfolio(auth, portfolioId, portfolio) { + return request(auth, `portfolios/${portfolioId}`, 'PUT', { portfolio }) } -export function deletePortfolio(portfolioId) { - return request(`portfolios/${portfolioId}`, 'DELETE') +export function deletePortfolio(auth, portfolioId) { + return request(auth, `portfolios/${portfolioId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/prefabs.js b/opendc-web/opendc-web-ui/src/api/prefabs.js index a8bd3f3b..eb9aa23c 100644 --- a/opendc-web/opendc-web-ui/src/api/prefabs.js +++ b/opendc-web/opendc-web-ui/src/api/prefabs.js @@ -22,18 +22,18 @@ import { request } from './index' -export function getPrefab(prefabId) { - return request(`prefabs/${prefabId}`) +export function getPrefab(auth, prefabId) { + return request(auth, `prefabs/${prefabId}`) } -export function addPrefab(prefab) { - return request('prefabs', 'POST', { prefab }) +export function addPrefab(auth, prefab) { + return request(auth, 'prefabs/', 'POST', { prefab }) } -export function updatePrefab(prefab) { - return request(`prefabs/${prefab._id}`, 'PUT', { prefab }) +export function updatePrefab(auth, prefab) { + return request(auth, `prefabs/${prefab._id}`, 'PUT', { prefab }) } -export function deletePrefab(prefabId) { - return request(`prefabs/${prefabId}`, 'DELETE') +export function deletePrefab(auth, prefabId) { + return request(auth, `prefabs/${prefabId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/projects.js b/opendc-web/opendc-web-ui/src/api/projects.js index 9ff7deda..93052080 100644 --- a/opendc-web/opendc-web-ui/src/api/projects.js +++ b/opendc-web/opendc-web-ui/src/api/projects.js @@ -22,18 +22,22 @@ import { request } from './index' -export function getProject(projectId) { - return request(`projects/${projectId}`) +export function getProjects(auth) { + return request(auth, `projects/`) } -export function addProject(project) { - return request('projects', 'POST', { project }) +export function getProject(auth, projectId) { + return request(auth, `projects/${projectId}`) } -export function updateProject(project) { - return request(`projects/${project._id}`, 'PUT', { project }) +export function addProject(auth, project) { + return request(auth, 'projects/', 'POST', { project }) } -export function deleteProject(projectId) { - return request(`projects/${projectId}`, 'DELETE') +export function updateProject(auth, project) { + return request(auth, `projects/${project._id}`, 'PUT', { project }) +} + +export function deleteProject(auth, projectId) { + return request(auth, `projects/${projectId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/scenarios.js b/opendc-web/opendc-web-ui/src/api/scenarios.js index 9f8c717b..095aa788 100644 --- a/opendc-web/opendc-web-ui/src/api/scenarios.js +++ b/opendc-web/opendc-web-ui/src/api/scenarios.js @@ -22,18 +22,18 @@ import { request } from './index' -export function addScenario(portfolioId, scenario) { - return request(`portfolios/${portfolioId}/scenarios`, 'POST', { scenario }) +export function addScenario(auth, portfolioId, scenario) { + return request(auth, `portfolios/${portfolioId}/scenarios`, 'POST', { scenario }) } -export function getScenario(scenarioId) { - return request(`scenarios/${scenarioId}`) +export function getScenario(auth, scenarioId) { + return request(auth, `scenarios/${scenarioId}`) } -export function updateScenario(scenarioId, scenario) { - return request(`scenarios/${scenarioId}`, 'PUT', { scenario }) +export function updateScenario(auth, scenarioId, scenario) { + return request(auth, `scenarios/${scenarioId}`, 'PUT', { scenario }) } -export function deleteScenario(scenarioId) { - return request(`scenarios/${scenarioId}`, 'DELETE') +export function deleteScenario(auth, scenarioId) { + return request(auth, `scenarios/${scenarioId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/schedulers.js b/opendc-web/opendc-web-ui/src/api/schedulers.js index 7791e51e..1b69f1a1 100644 --- a/opendc-web/opendc-web-ui/src/api/schedulers.js +++ b/opendc-web/opendc-web-ui/src/api/schedulers.js @@ -22,6 +22,6 @@ import { request } from './index' -export function getAllSchedulers() { - return request('schedulers') +export function getAllSchedulers(auth) { + return request(auth, 'schedulers/') } diff --git a/opendc-web/opendc-web-ui/src/api/token-signin.js b/opendc-web/opendc-web-ui/src/api/token-signin.js deleted file mode 100644 index a3761fa1..00000000 --- a/opendc-web/opendc-web-ui/src/api/token-signin.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -export function performTokenSignIn(token) { - const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL - - return fetch(`${apiUrl}/tokensignin`, { - method: 'POST', - body: new URLSearchParams({ - idtoken: token, - }), - }).then((res) => res.json()) -} diff --git a/opendc-web/opendc-web-ui/src/api/topologies.js b/opendc-web/opendc-web-ui/src/api/topologies.js index e6df73c7..c8744e6c 100644 --- a/opendc-web/opendc-web-ui/src/api/topologies.js +++ b/opendc-web/opendc-web-ui/src/api/topologies.js @@ -22,18 +22,18 @@ import { request } from './index' -export function addTopology(topology) { - return request(`projects/${topology.projectId}/topologies`, 'POST', { topology }) +export function addTopology(auth, topology) { + return request(auth, `projects/${topology.projectId}/topologies`, 'POST', { topology }) } -export function getTopology(topologyId) { - return request(`topologies/${topologyId}`) +export function getTopology(auth, topologyId) { + return request(auth, `topologies/${topologyId}`) } -export function updateTopology(topology) { - return request(`topologies/${topology._id}`, 'PUT', { topology }) +export function updateTopology(auth, topology) { + return request(auth, `topologies/${topology._id}`, 'PUT', { topology }) } -export function deleteTopology(topologyId) { - return request(`topologies/${topologyId}`, 'DELETE') +export function deleteTopology(auth, topologyId) { + return request(auth, `topologies/${topologyId}`, 'DELETE') } diff --git a/opendc-web/opendc-web-ui/src/api/traces.js b/opendc-web/opendc-web-ui/src/api/traces.js index 1c5cfa1d..df03a2dd 100644 --- a/opendc-web/opendc-web-ui/src/api/traces.js +++ b/opendc-web/opendc-web-ui/src/api/traces.js @@ -22,6 +22,6 @@ import { request } from './index' -export function getAllTraces() { - return request('traces') +export function getAllTraces(auth) { + return request(auth, 'traces/') } diff --git a/opendc-web/opendc-web-ui/src/api/users.js b/opendc-web/opendc-web-ui/src/api/users.js deleted file mode 100644 index 3da030ad..00000000 --- a/opendc-web/opendc-web-ui/src/api/users.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import { request } from './index' - -export function getUserByEmail(email) { - return request(`users` + new URLSearchParams({ email })) -} - -export function addUser(user) { - return request('users', 'POST', { user }) -} - -export function getUser(userId) { - return request(`users/${userId}`) -} - -export function deleteUser(userId) { - return request(`users/${userId}`, 'DELETE') -} diff --git a/opendc-web/opendc-web-ui/src/auth.js b/opendc-web/opendc-web-ui/src/auth.js index faed9829..706151bf 100644 --- a/opendc-web/opendc-web-ui/src/auth.js +++ b/opendc-web/opendc-web-ui/src/auth.js @@ -1,83 +1,65 @@ -import { LOG_IN_SUCCEEDED, LOG_OUT } from './redux/actions/auth' -import { DELETE_CURRENT_USER_SUCCEEDED } from './redux/actions/users' -import { useEffect, useState } from 'react' -import { useRouter } from 'next/router' -import { useSelector } from 'react-redux' - -const getAuthObject = () => { - const authItem = global.localStorage && localStorage.getItem('auth') - if (!authItem || authItem === '{}') { - return undefined - } - return JSON.parse(authItem) -} - -export const userIsLoggedIn = () => { - const authObj = getAuthObject() - - if (!authObj || !authObj.googleId) { - return false - } - - const currentTime = new Date().getTime() - return parseInt(authObj.expiresAt, 10) - currentTime > 0 -} - -export const getAuthToken = () => { - const authObj = getAuthObject() - if (!authObj) { - return undefined - } - - return authObj.authToken -} - -export const saveAuthLocalStorage = (payload) => { - localStorage.setItem('auth', JSON.stringify(payload)) -} - -export const clearAuthLocalStorage = () => { - localStorage.setItem('auth', '') -} - -export const authRedirectMiddleware = (store) => (next) => (action) => { - switch (action.type) { - case LOG_IN_SUCCEEDED: - saveAuthLocalStorage(action.payload) - window.location.href = '/projects' - break - case LOG_OUT: - case DELETE_CURRENT_USER_SUCCEEDED: - clearAuthLocalStorage() - window.location.href = '/' - break - default: - next(action) - return - } - - next(action) -} +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ -export function useIsLoggedIn() { - const [isLoggedIn, setLoggedIn] = useState(false) - - useEffect(() => { - setLoggedIn(userIsLoggedIn()) - }, []) +import { Auth0Provider, useAuth0 } from '@auth0/auth0-react' +import { useEffect } from 'react' +import { useRouter } from 'next/router' - return isLoggedIn +/** + * Obtain the authentication context. + */ +export function useAuth() { + return useAuth0() } +/** + * Force the user to be authenticated or redirect to the homepage. + */ export function useRequireAuth() { + const auth = useAuth() const router = useRouter() + const { isLoading, isAuthenticated } = auth + useEffect(() => { - if (!userIsLoggedIn()) { + if (!isLoading && !isAuthenticated) { router.replace('/') } - }) + }, [isLoading, isAuthenticated]) + + return auth } -export function useUser() { - return useSelector((state) => state.auth) +/** + * AuthProvider which provides an authentication context. + */ +export function AuthProvider({ children }) { + return ( + + {children} + + ) } diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js index f16a3feb..5c9ea1b8 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js @@ -15,7 +15,7 @@ import Login from '../../containers/auth/Login' import Logout from '../../containers/auth/Logout' import ProfileName from '../../containers/auth/ProfileName' import { login, navbar, opendcBrand } from './Navbar.module.scss' -import { useIsLoggedIn } from '../../auth' +import { useAuth } from '../../auth' export const NAVBAR_HEIGHT = 60 @@ -44,10 +44,10 @@ export const NavItem = ({ route, children }) => { export const LoggedInSection = () => { const router = useRouter() - const isLoggedIn = useIsLoggedIn() + const { isAuthenticated } = useAuth() return (
      - Schematic top-down view of a datacenter

      diff --git a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js index 0d3217f9..98aa0af2 100644 --- a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js +++ b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js @@ -1,6 +1,9 @@ import React from 'react' +import Image from 'next/image' import { Container, Jumbotron, Button } from 'reactstrap' import { jumbotronHeader, jumbotron, dc } from './JumbotronHeader.module.scss' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons' const JumbotronHeader = () => (

      @@ -10,7 +13,9 @@ const JumbotronHeader = () => ( OpenDC

      Collaborative Datacenter Simulation and Exploration for Everybody

      - OpenDC +
      + OpenDC +

      diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js index 4f634b28..9673b7b7 100644 --- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js @@ -1,4 +1,5 @@ import React from 'react' +import Image from 'next/image' import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' import { screenshot } from './ScreenshotSection.module.scss' @@ -6,11 +7,18 @@ import { screenshot } from './ScreenshotSection.module.scss' const ScreenshotSection = ({ className, name, title, imageUrl, caption, imageIsRight, children }) => ( - + {children} - {caption} + {caption}
      {caption}
      diff --git a/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js b/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js index 44ce905b..c154cc26 100644 --- a/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js @@ -1,4 +1,5 @@ import React from 'react' +import Image from 'next/image' import { Col, Row } from 'reactstrap' import ContentSection from './ContentSection' @@ -18,9 +19,12 @@ const SimulationSection = ({ className }) => {
    - Running an experiment in OpenDC Running an experiment in OpenDC @@ -39,7 +43,14 @@ const SimulationSection = ({ className }) => { - OpenDC's Architecture + OpenDC's Architecture OpenDC's Architecture diff --git a/opendc-web/opendc-web-ui/src/components/home/TeamSection.js b/opendc-web/opendc-web-ui/src/components/home/TeamSection.js index 4e8a3906..bbbe241e 100644 --- a/opendc-web/opendc-web-ui/src/components/home/TeamSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/TeamSection.js @@ -1,43 +1,44 @@ import React from 'react' +import Image from 'next/image' import { Row, Col } from 'reactstrap' import ContentSection from './ContentSection' const TeamLead = ({ photoId, name, description }) => ( - - -

    {name}

    -
    {description}
    - + + + {name} + + +

    {name}

    +
    {description}
    + +
    ) const TeamMember = ({ photoId, name }) => ( - - -
    {name}
    - + + + {name} + + +
    {name}
    + +
    ) diff --git a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js index 6fdf4e5c..efedebb7 100644 --- a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js +++ b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js @@ -1,35 +1,36 @@ import React from 'react' -import FontAwesome from 'react-fontawesome' import { ListGroup, ListGroupItem } from 'reactstrap' import ContentSection from './ContentSection' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faWindowMaximize, faTv, faDatabase, faCogs } from '@fortawesome/free-solid-svg-icons' const TechnologiesSection = ({ className }) => ( - + Browser JavaScript, React, Redux, Konva - + Server Python, Flask, FlaskSocketIO, OpenAPI - + Database MongoDB - + Simulator Kotlin diff --git a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js index 7b1eaae2..28207968 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js @@ -1,16 +1,17 @@ import React from 'react' -import FontAwesome from 'react-fontawesome' import Link from 'next/link' import { NavLink } from 'reactstrap' import Navbar, { NavItem } from './Navbar' import {} from './Navbar.module.scss' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faList } from '@fortawesome/free-solid-svg-icons' const AppNavbarComponent = ({ project, fullWidth }) => ( - + My Projects diff --git a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js index 0c0feeb1..4ab577e0 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js @@ -1,11 +1,12 @@ import PropTypes from 'prop-types' import React from 'react' -import FontAwesome from 'react-fontawesome' import { NavLink } from 'reactstrap' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons' const LogoutButton = ({ onLogout }) => ( - + ) diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js index 5c9ea1b8..690a7bdf 100644 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js +++ b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js @@ -1,6 +1,7 @@ import React, { useState } from 'react' import Link from 'next/link' import { useRouter } from 'next/router' +import Image from 'next/image' import { Navbar as RNavbar, NavItem as RNavItem, @@ -16,6 +17,8 @@ import Logout from '../../containers/auth/Logout' import ProfileName from '../../containers/auth/ProfileName' import { login, navbar, opendcBrand } from './Navbar.module.scss' import { useAuth } from '../../auth' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faGithub } from '@fortawesome/free-brands-svg-icons' export const NAVBAR_HEIGHT = 60 @@ -25,7 +28,7 @@ const GitHubLink = () => ( className="ml-2 mr-3 text-dark" style={{ position: 'relative', top: 7 }} > - + ) @@ -87,7 +90,9 @@ const Navbar = ({ fullWidth, children }) => { - OpenDC +
    + OpenDC +
    diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js index 28fd81e9..e6200b10 100644 --- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js +++ b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js @@ -3,6 +3,8 @@ import Link from 'next/link' import BlinkingCursor from './BlinkingCursor' import CodeBlock from './CodeBlock' import { terminalWindow, terminalHeader, terminalBody, segfault, subTitle, homeBtn } from './TerminalWindow.module.scss' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faHome } from '@fortawesome/free-solid-svg-icons' const TerminalWindow = () => (
    @@ -25,7 +27,7 @@ const TerminalWindow = () => (
    - GET ME BACK TO OPENDC + GET ME BACK TO OPENDC
diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js index 96970fd9..0725e42b 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js +++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js @@ -2,12 +2,14 @@ import PropTypes from 'prop-types' import React from 'react' import Link from 'next/link' import { Button } from 'reactstrap' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faPlay, faUsers, faTrash } from '@fortawesome/free-solid-svg-icons' const ProjectActionButtons = ({ projectId, onViewUsers, onDelete }) => ( ) diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js index cb17b835..dc3f85ec 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js +++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js @@ -2,13 +2,15 @@ import PropTypes from 'prop-types' import React from 'react' import { Project } from '../../shapes' import ProjectRow from './ProjectRow' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons' const ProjectList = ({ projects }) => { return (
{projects.length === 0 ? (
- + No projects here yet... Add some with the 'New Project' button!
) : ( diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js index 9a95b777..91368de8 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js +++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js @@ -1,10 +1,10 @@ -import classNames from 'classnames' import React from 'react' import ProjectActions from '../../containers/projects/ProjectActions' import { Project } from '../../shapes' import { AUTH_DESCRIPTION_MAP, AUTH_ICON_MAP } from '../../util/authorizations' import { parseAndFormatDateTime } from '../../util/date-time' import { useAuth } from '../../auth' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' const ProjectRow = ({ project }) => { const { user } = useAuth() @@ -14,7 +14,7 @@ const ProjectRow = ({ project }) => { {project.name} {parseAndFormatDateTime(project.datetimeLastEdited)} - + {AUTH_DESCRIPTION_MAP[level]} diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js index f3344424..54e406f4 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -3,6 +3,8 @@ import { useDispatch } from 'react-redux' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' import { deleteMachine } from '../../../../../redux/actions/topology/machine' import { Button } from 'reactstrap' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faTrash } from '@fortawesome/free-solid-svg-icons' const DeleteMachineContainer = () => { const dispatch = useDispatch() @@ -16,7 +18,7 @@ const DeleteMachineContainer = () => { return ( <> { const dispatch = useDispatch() @@ -16,7 +18,7 @@ const DeleteRackContainer = () => { return ( <> { const dispatch = useDispatch() @@ -16,7 +18,7 @@ const DeleteRoomContainer = () => { return ( <> { const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') @@ -13,7 +15,7 @@ const EditRoomContainer = () => { return isEditing ? ( ) : ( @@ -24,7 +26,7 @@ const EditRoomContainer = () => { disabled={isInRackConstructionMode} onClick={() => (isInRackConstructionMode ? undefined : onEdit())} > - + Edit the tiles of this room ) diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js index 8459ef5f..d8083d89 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js @@ -1,6 +1,8 @@ import React from 'react' import { Button } from 'reactstrap' import { useAuth } from '../../auth' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faSignInAlt } from '@fortawesome/free-solid-svg-icons' function Login({ visible, className }) { const { loginWithRedirect } = useAuth() @@ -11,7 +13,7 @@ function Login({ visible, className }) { return ( ) } diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js index a0e607b2..e03b5c07 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js @@ -3,6 +3,8 @@ import { useDispatch } from 'react-redux' import { addProject } from '../../redux/actions/projects' import TextInputModal from '../../components/modals/TextInputModal' import { Button } from 'reactstrap' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faPlus } from '@fortawesome/free-solid-svg-icons' /** * A container for creating a new project. @@ -21,7 +23,7 @@ const NewProjectContainer = () => { <>
diff --git a/opendc-web/opendc-web-ui/src/pages/_document.js b/opendc-web/opendc-web-ui/src/pages/_document.js index 943ae395..8e4680c0 100644 --- a/opendc-web/opendc-web-ui/src/pages/_document.js +++ b/opendc-web/opendc-web-ui/src/pages/_document.js @@ -69,7 +69,6 @@ class OpenDCDocument extends Document { href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet" /> - - - - - - - - - -
- - diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js deleted file mode 100644 index 60a7e6a3..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react' -import Image from 'next/image' -import { Row, Col } from 'reactstrap' -import ContentSection from './ContentSection' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faExclamationTriangle, faEnvelope } from '@fortawesome/free-solid-svg-icons' -import { faGithub } from '@fortawesome/free-brands-svg-icons' -import { contactSection, tudelftIcon } from './ContactSection.module.scss' - -const ContactSection = () => ( - - - - - -
- atlarge-research/opendc - - - - - -
- opendc@atlarge-research.com - - - - - - TU Delft - - - - - A project by the   - - @Large Research Group - - . - - - - - -
- Disclaimer: - OpenDC is an experimental tool. Your data may get lost, overwritten, or otherwise become unavailable. -
- The OpenDC authors should in no way be liable in the event this happens (see our{' '} - - license - - ). Sorry for the inconvenience. - -
- -) - -export default ContactSection diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss b/opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss deleted file mode 100644 index 9ab4fcb1..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ContactSection.module.scss +++ /dev/null @@ -1,20 +0,0 @@ -.contactSection { - background-color: #444; - color: #ddd; - - a { - color: #ddd; - - &:hover { - color: #fff; - } - } - - .tudelftIcon { - height: 100px; - } - - .disclaimer { - color: #cccccc; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js deleted file mode 100644 index abaa565c..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js +++ /dev/null @@ -1,23 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import classNames from 'classnames' -import { Container } from 'reactstrap' -import { contentSection } from './ContentSection.module.scss' - -const ContentSection = ({ name, title, children, className }) => ( -
- -

{title}

- {children} -
-
-) - -ContentSection.propTypes = { - name: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - children: PropTypes.node, - className: PropTypes.string, -} - -export default ContentSection diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss b/opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss deleted file mode 100644 index d27a0ce0..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ContentSection.module.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import 'src/style/_variables.scss'; - -.contentSection { - padding-top: 50px; - padding-bottom: 50px; - text-align: center; - - h1 { - margin-bottom: 30px; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js deleted file mode 100644 index f9000d32..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js +++ /dev/null @@ -1,50 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Image from 'next/image' -import { Container, Row, Col } from 'reactstrap' - -const IntroSection = ({ className }) => ( -
- - - -

The datacenter (DC) industry...

-
    -
  • Is worth over $15 bn, and growing
  • -
  • Has many hard-to-grasp concepts
  • -
  • Needs to become accessible to many
  • -
- - - Schematic top-down view of a datacenter -

- - Image source - -

- - -

OpenDC provides...

-
    -
  • Collaborative online DC modeling
  • -
  • Diverse and effective DC simulation
  • -
  • Exploratory DC performance feedback
  • -
- -
-
-
-) - -IntroSection.propTypes = { - className: PropTypes.string, -} - -export default IntroSection diff --git a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js deleted file mode 100644 index 98aa0af2..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -import Image from 'next/image' -import { Container, Jumbotron, Button } from 'reactstrap' -import { jumbotronHeader, jumbotron, dc } from './JumbotronHeader.module.scss' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons' - -const JumbotronHeader = () => ( -
- - -

- OpenDC -

-

Collaborative Datacenter Simulation and Exploration for Everybody

-
- OpenDC -
-

- -

-
-
-
-) - -export default JumbotronHeader diff --git a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss b/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss deleted file mode 100644 index 567b3e73..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/JumbotronHeader.module.scss +++ /dev/null @@ -1,31 +0,0 @@ -.jumbotronHeader { - background: #00a6d6; -} - -.jumbotron { - background-color: inherit; - margin-bottom: 0; - text-align: center; - - padding-top: 120px; - padding-bottom: 120px; - - img { - max-width: 110px; - } - - h1 { - color: #fff; - font-size: 4.5em; - - .dc { - color: #fff; - font-weight: bold; - } - } - - :global(.lead) { - color: #fff; - font-size: 1.4em; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js b/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js deleted file mode 100644 index 8959663a..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ModelingSection.js +++ /dev/null @@ -1,28 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import ScreenshotSection from './ScreenshotSection' - -const ModelingSection = ({ className }) => ( - -

Collaboratively...

-
    -
  • Model DC layout, and room locations and types
  • -
  • Place racks in rooms and nodes in racks
  • -
  • Add real-world CPU, GPU, memory, storage and network units to each node
  • -
  • Select from diverse scheduling policies
  • -
-
-) - -ModelingSection.propTypes = { - className: PropTypes.string, -} - -export default ModelingSection diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js deleted file mode 100644 index 58fe1710..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Image from 'next/image' -import { Row, Col } from 'reactstrap' -import ContentSection from './ContentSection' -import { screenshot } from './ScreenshotSection.module.scss' - -const ScreenshotSection = ({ className, name, title, imageUrl, caption, imageIsRight, children }) => ( - - - - {children} - - - {caption} -
{caption}
- -
-
-) - -ScreenshotSection.propTypes = { - className: PropTypes.string, - name: PropTypes.string, - title: PropTypes.string, - imageUrl: PropTypes.string, - caption: PropTypes.string, - imageIsRight: PropTypes.bool, - children: PropTypes.node, -} - -export default ScreenshotSection diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss deleted file mode 100644 index 7e22de32..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.module.scss +++ /dev/null @@ -1,5 +0,0 @@ -.screenshot { - padding-left: 0; - padding-right: 0; - margin-bottom: 5px; -} diff --git a/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js b/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js deleted file mode 100644 index 46ce6a35..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/SimulationSection.js +++ /dev/null @@ -1,66 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Image from 'next/image' -import { Col, Row } from 'reactstrap' -import ContentSection from './ContentSection' - -const SimulationSection = ({ className }) => { - return ( - - - -

Working with OpenDC:

-
    -
  • Seamlessly switch between construction and simulation modes
  • -
  • - Choose one of several predefined workloads (Business Critical, Workflows, Machine Learning, - Serverless, etc.) -
  • -
  • Compare datacenter topologies using automated plots and visual summaries
  • -
- - - Running an experiment in OpenDC - Running an experiment in OpenDC - -
- - -

OpenDC's Simulator:

-
    -
  • Includes a detailed operational model of modern datacenters
  • -
  • - Support for emerging datacenter technologies around cloud computing,{' '} - serverless computing, big data, and machine learning -
  • -
- - - - OpenDC's Architecture - OpenDC's Architecture - -
-
- ) -} - -SimulationSection.propTypes = { - className: PropTypes.string, -} - -export default SimulationSection diff --git a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js deleted file mode 100644 index aa689ba4..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js +++ /dev/null @@ -1,47 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Row, Col } from 'reactstrap' -import ContentSection from './ContentSection' - -const Stakeholder = ({ name, title, subtitle }) => ( - - -
-

{title}

-

{subtitle}

-
- -) - -Stakeholder.propTypes = { - name: PropTypes.string, - title: PropTypes.string, - subtitle: PropTypes.string, -} - -const StakeholderSection = ({ className }) => ( - - - - - - - - - -) - -StakeholderSection.propTypes = { - className: PropTypes.string, -} - -export default StakeholderSection diff --git a/opendc-web/opendc-web-ui/src/components/home/TeamSection.js b/opendc-web/opendc-web-ui/src/components/home/TeamSection.js deleted file mode 100644 index dd057a93..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/TeamSection.js +++ /dev/null @@ -1,82 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Image from 'next/image' -import { Row, Col } from 'reactstrap' -import ContentSection from './ContentSection' - -const TeamLead = ({ photoId, name, description }) => ( - - - - {name} - - -

{name}

-
{description}
- -
- -) - -TeamLead.propTypes = { - photoId: PropTypes.string, - name: PropTypes.string, - description: PropTypes.string, -} - -const TeamMember = ({ photoId, name }) => ( - - - - {name} - - -
{name}
- -
- -) - -TeamMember.propTypes = { - photoId: PropTypes.string, - name: PropTypes.string, -} - -const TeamSection = ({ className }) => ( - - - - - - - - - - - - - - - - - - -) - -TeamSection.propTypes = { - className: PropTypes.string, -} - -export default TeamSection diff --git a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js deleted file mode 100644 index e5131c2a..00000000 --- a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js +++ /dev/null @@ -1,47 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { ListGroup, ListGroupItem } from 'reactstrap' -import ContentSection from './ContentSection' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faWindowMaximize, faTv, faDatabase, faCogs } from '@fortawesome/free-solid-svg-icons' - -const TechnologiesSection = ({ className }) => ( - - - - - - Browser - - JavaScript, React, Redux, Konva - - - - - Server - - Python, Flask, FlaskSocketIO, OpenAPI - - - - - Database - - MongoDB - - - - - Simulator - - Kotlin - - - -) - -TechnologiesSection.propTypes = { - className: PropTypes.string, -} - -export default TechnologiesSection diff --git a/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js b/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js deleted file mode 100644 index 57cb7a53..00000000 --- a/opendc-web/opendc-web-ui/src/components/navigation/HomeNavbar.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { NavItem, NavLink } from 'reactstrap' -import Navbar from './Navbar' - -const HomeNavbar = () => ( - - Stakeholders - Modeling - Project - Technologies - Team - Contact - -) - -export default HomeNavbar diff --git a/opendc-web/opendc-web-ui/src/pages/index.js b/opendc-web/opendc-web-ui/src/pages/index.js deleted file mode 100644 index bb904eb6..00000000 --- a/opendc-web/opendc-web-ui/src/pages/index.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react' -import Head from 'next/head' -import ContactSection from '../components/home/ContactSection' -import IntroSection from '../components/home/IntroSection' -import JumbotronHeader from '../components/home/JumbotronHeader' -import ModelingSection from '../components/home/ModelingSection' -import SimulationSection from '../components/home/SimulationSection' -import StakeholderSection from '../components/home/StakeholderSection' -import TeamSection from '../components/home/TeamSection' -import TechnologiesSection from '../components/home/TechnologiesSection' -import HomeNavbar from '../components/navigation/HomeNavbar' -import { - introSection, - stakeholderSection, - modelingSection, - simulationSection, - technologiesSection, - teamSection, -} from './index.module.scss' - -function Home() { - return ( - <> - - OpenDC - - -
- - - - - - - - -
- - ) -} - -export default Home diff --git a/opendc-web/opendc-web-ui/src/pages/index.module.scss b/opendc-web/opendc-web-ui/src/pages/index.module.scss deleted file mode 100644 index aed1d88f..00000000 --- a/opendc-web/opendc-web-ui/src/pages/index.module.scss +++ /dev/null @@ -1,16 +0,0 @@ -.bodyWrapper { - position: relative; - overflow-y: hidden; -} - -.introSection, -.modelingSection, -.technologiesSection { - background-color: #fff; -} - -.stakeholderSection, -.simulationSection, -.teamSection { - background-color: #f2f2f2; -} -- cgit v1.2.3 From 1ab168fb80fbf3958fbadda00d1c6714cad66c86 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 3 Jun 2021 17:57:46 +0200 Subject: feat(ui): Add initial support for PatternFly 4 framework This change adds support in our Next.js application for the PatternFly 4 design framework. This framework is built by RedHat and provides several components that are useful for the space in which OpenDC operates. --- opendc-web/opendc-web-ui/next.config.js | 11 ++- opendc-web/opendc-web-ui/package.json | 2 + opendc-web/opendc-web-ui/src/pages/_app.js | 1 + opendc-web/opendc-web-ui/yarn.lock | 123 ++++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 6 deletions(-) diff --git a/opendc-web/opendc-web-ui/next.config.js b/opendc-web/opendc-web-ui/next.config.js index 97580fa0..56263c86 100644 --- a/opendc-web/opendc-web-ui/next.config.js +++ b/opendc-web/opendc-web-ui/next.config.js @@ -20,7 +20,14 @@ * SOFTWARE. */ -module.exports = { +// PatternFly 4 uses global CSS imports in its distribution files. Therefore, +// we need to transpile the modules before we can use them. +const withTM = require('next-transpile-modules')([ + '@patternfly/react-core', + '@patternfly/react-styles', +]) + +module.exports = withTM({ reactStrictMode: true, experimental: { eslint: true, @@ -34,4 +41,4 @@ module.exports = { }, ] }, -} +}) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 2dfd137c..442d63a5 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -22,6 +22,7 @@ "@fortawesome/free-brands-svg-icons": "^5.15.3", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.14", + "@patternfly/react-core": "^4.135.0", "@sentry/react": "^5.30.0", "@sentry/tracing": "^5.30.0", "approximate-number": "~2.0.0", @@ -32,6 +33,7 @@ "lint-staged": "~10.2.2", "mathjs": "~7.6.0", "next": "^11.0.1", + "next-transpile-modules": "^8.0.0", "normalizr": "^3.6.1", "prettier": "~2.0.5", "prop-types": "~15.7.2", diff --git a/opendc-web/opendc-web-ui/src/pages/_app.js b/opendc-web/opendc-web-ui/src/pages/_app.js index 6a7200d5..78402323 100644 --- a/opendc-web/opendc-web-ui/src/pages/_app.js +++ b/opendc-web/opendc-web-ui/src/pages/_app.js @@ -25,6 +25,7 @@ import Head from 'next/head' import { Provider } from 'react-redux' import { useStore } from '../redux' import '../index.scss' +import '@patternfly/react-core/dist/styles/base.css' import { AuthProvider, useAuth } from '../auth' import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index bf4c419e..abd2613e 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -214,6 +214,34 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@patternfly/react-core@^4.135.0": + version "4.135.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.135.0.tgz#b64ad4da10a8814926e28fad727bc7690cd60e66" + integrity sha512-DZcONUGOR7Znd6BsUJ4L+KrrnIpyjUvh3JNcYiHW3loytxShCGcx+a04QjOOcZm+MtFhkgs/t51yiC5IP12abA== + dependencies: + "@patternfly/react-icons" "^4.11.0" + "@patternfly/react-styles" "^4.11.0" + "@patternfly/react-tokens" "^4.12.0" + focus-trap "6.2.2" + react-dropzone "9.0.0" + tippy.js "5.1.2" + tslib "1.13.0" + +"@patternfly/react-icons@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.11.0.tgz#26790eeff22dc3204aa8cd094470f0a2f915634a" + integrity sha512-WsIX34bO9rhVRmPG0jlV3GoFGfYgPC64TscNV0lxQosiVRnYIA6Z3nBSArtJsxo5Yn6c63glIefC/YTy6D/ZYg== + +"@patternfly/react-styles@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.11.0.tgz#0068dcb18e1343242f93fa6024dcc077acd57fb9" + integrity sha512-4eIqTwGI4mjt9DMqX6hnan4eRS+3LUWNaneTEJdmk+flKxtAE/O/OmQHvH4GetDnlSbyfATcA0VFbVtR0aRJAg== + +"@patternfly/react-tokens@^4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.12.0.tgz#2973c7f08a2f35997a0054bbf3c886b3c5c68822" + integrity sha512-Oj+GxqTtx0Yu9IDCTibZLQnpcKp58JneNKEFQkJ29WJydhPG4j6oFFElkK+ub+Ft/f9B1Ky1SsfR9eabo6IykQ== + "@redux-saga/core@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4" @@ -645,6 +673,13 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +attr-accept@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-1.1.3.tgz#48230c79f93790ef2775fcec4f0db0f5db41ca52" + integrity sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ== + dependencies: + core-js "^2.5.0" + available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" @@ -1024,6 +1059,11 @@ convert-source-map@1.7.0: dependencies: safe-buffer "~5.1.1" +core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + core-js@^3.11.0: version "3.12.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" @@ -1380,6 +1420,14 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +enhanced-resolve@^5.7.0: + version "5.8.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -1764,6 +1812,13 @@ file-saver@^1.3.3: resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.8.tgz#e68a30c7cb044e2fb362b428469feb291c2e09d8" integrity sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg== +file-selector@^0.1.8: + version "0.1.19" + resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.19.tgz#8ecc9d069a6f544f2e4a096b64a8052e70ec8abf" + integrity sha512-kCWw3+Aai8Uox+5tHCNgMFaUdgidxvMnLWO6fM5sZ0hA2wlHP5/DHGF0ECe84BiB95qdJbKNEJhWKVDvMN+JDQ== + dependencies: + tslib "^2.0.1" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -1815,6 +1870,13 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== +focus-trap@6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.2.2.tgz#0e6f391415b0697c99da932702dedd13084fa131" + integrity sha512-qWovH9+LGoKqREvJaTCzJyO0hphQYGz+ap5Hc4NqXHNhZBdxCi5uBPPcaOUw66fHmzXLVwvETLvFgpwPILqKpg== + dependencies: + tabbable "^5.1.4" + foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -1923,7 +1985,7 @@ globby@^11.0.3: merge2 "^1.3.0" slash "^3.0.0" -graceful-fs@^4.1.2: +graceful-fs@^4.1.2, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -2646,6 +2708,14 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +next-transpile-modules@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-8.0.0.tgz#56375cdc25ae5d23a834195f277fc2737b26cb97" + integrity sha512-Q2f2yB0zMJ8KJbIYAeZoIxG6cSfVk813zr6B5HzsLMBVcJ3FaF8lKr7WG66n0KlHCwjLSmf/6EkgI6QQVWHrDw== + dependencies: + enhanced-resolve "^5.7.0" + escalade "^3.1.1" + next@^11.0.1: version "11.0.1" resolved "https://registry.yarnpkg.com/next/-/next-11.0.1.tgz#b8e3914d153aaf7143cb98c09bcd3c8230eeb17a" @@ -3083,7 +3153,7 @@ pnp-webpack-plugin@1.6.4: dependencies: ts-pnp "^1.1.6" -popper.js@^1.14.4: +popper.js@^1.14.4, popper.js@^1.16.0: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== @@ -3132,6 +3202,14 @@ promise-polyfill@^8.2.0: resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.0.tgz#367394726da7561457aba2133c9ceefbd6267da0" integrity sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g== +prop-types-extra@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" + integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== + dependencies: + react-is "^16.3.2" + warning "^4.0.0" + prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -3244,6 +3322,16 @@ react-dom@^17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" +react-dropzone@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-9.0.0.tgz#4f5223cdcb4d3bd8a66e3298c4041eb0c75c4634" + integrity sha512-wZ2o9B2qkdE3RumWhfyZT9swgJYJPeU5qHEcMU8weYpmLex1eeWX0CC32/Y0VutB+BBi2D+iePV/YZIiB4kZGw== + dependencies: + attr-accept "^1.1.3" + file-selector "^0.1.8" + prop-types "^15.6.2" + prop-types-extra "^1.1.0" + react-hotkeys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0.tgz#a7719c7340cbba888b0e9184f806a9ec0ac2c53f" @@ -3261,7 +3349,7 @@ react-is@17.0.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -3975,6 +4063,11 @@ symbol-observable@^1.2.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +tabbable@^5.1.4: + version "5.2.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.0.tgz#4fba60991d8bb89d06e5d9455c92b453acf88fb2" + integrity sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg== + table@^6.0.9: version "6.7.1" resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" @@ -3987,6 +4080,11 @@ table@^6.0.9: string-width "^4.2.0" strip-ansi "^6.0.0" +tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4009,6 +4107,13 @@ tiny-emitter@^2.1.0: resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== +tippy.js@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-5.1.2.tgz#5ac91233c59ab482ef5988cffe6e08bd26528e66" + integrity sha512-Qtrv2wqbRbaKMUb6bWWBQWPayvcDKNrGlvihxtsyowhT7RLGEh1STWuy6EMXC6QLkfKPB2MLnf8W2mzql9VDAw== + dependencies: + popper.js "^1.16.0" + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -4053,11 +4158,21 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" +tslib@1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -4243,7 +4358,7 @@ vm-browserify@1.1.2, vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -warning@^4.0.2, warning@^4.0.3: +warning@^4.0.0, warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== -- cgit v1.2.3 From e200dbfdc076ac6263c9ac6f9dabdcc475f01d6e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sat, 10 Jul 2021 12:41:00 +0200 Subject: fix(ui): Relax topology schema requirements This change fixes an issue where the topology generated by the frontend was not accepted by the API server. --- opendc-web/opendc-web-api/opendc/models/topology.py | 6 ++++++ .../src/main/kotlin/org/opendc/web/client/model/Machine.kt | 3 ++- .../src/main/kotlin/org/opendc/web/client/model/Room.kt | 3 ++- .../src/main/kotlin/org/opendc/web/client/model/RoomTile.kt | 3 ++- opendc-web/opendc-web-ui/src/redux/sagas/topology.js | 6 ++---- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/opendc-web/opendc-web-api/opendc/models/topology.py b/opendc-web/opendc-web-api/opendc/models/topology.py index 592f82c5..44994818 100644 --- a/opendc-web/opendc-web-api/opendc/models/topology.py +++ b/opendc-web/opendc-web-api/opendc/models/topology.py @@ -38,6 +38,7 @@ class MachineSchema(Schema): gpus = fields.List(fields.Nested(PuSchema)) memories = fields.List(fields.Nested(MemorySchema)) storages = fields.List(fields.Nested(MemorySchema)) + rackId = fields.String() class ObjectSchema(Schema): @@ -49,6 +50,7 @@ class ObjectSchema(Schema): capacity = fields.Integer() powerCapacityW = fields.Integer() machines = fields.List(fields.Nested(MachineSchema)) + tileId = fields.String() class TileSchema(Schema): @@ -56,9 +58,11 @@ class TileSchema(Schema): Schema representing a room tile. """ _id = fields.String() + topologyId = fields.String() positionX = fields.Integer() positionY = fields.Integer() rack = fields.Nested(ObjectSchema) + roomId = fields.String() class RoomSchema(Schema): @@ -67,6 +71,7 @@ class RoomSchema(Schema): """ _id = fields.String() name = fields.String(required=True) + topologyId = fields.String() tiles = fields.List(fields.Nested(TileSchema), required=True) @@ -78,6 +83,7 @@ class TopologySchema(Schema): projectId = fields.String() name = fields.String(required=True) rooms = fields.List(fields.Nested(RoomSchema), required=True) + datetimeLastEdited = fields.DateTime() class Topology(Model): diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt index c6757c5c..86d2d46f 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt @@ -38,5 +38,6 @@ public data class Machine( @JsonProperty("memories") val memory: List = emptyList(), @JsonProperty("storages") - val storage: List = emptyList() + val storage: List = emptyList(), + val rackId: String? = null ) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt index e961d6db..f1b8f946 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt @@ -33,5 +33,6 @@ public data class Room( @JsonProperty("_id") val id: String, val name: String, - val tiles: Set + val tiles: Set, + val topologyId: String? = null, ) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt index 3bee3204..0b956262 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt @@ -34,5 +34,6 @@ public data class RoomTile( val id: String, val positionX: Double, val positionY: Double, - val rack: Rack? = null + val rack: Rack? = null, + val roomId: String? = null, ) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index 5d9154fd..333c1485 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -123,8 +123,6 @@ export function* onEditRoomName(action) { try { const topologyId = yield select((state) => state.currentTopologyId) const roomId = yield select((state) => state.interactionLevel.roomId) - const room = Object.assign({}, yield select((state) => state.objects.room[roomId])) - room.name = action.name yield put(addPropToStoreObject('room', roomId, { name: action.name })) yield updateTopologyOnServer(topologyId) } catch (error) { @@ -148,8 +146,6 @@ export function* onEditRackName(action) { try { const topologyId = yield select((state) => state.currentTopologyId) const rackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rack) - const rack = Object.assign({}, yield select((state) => state.objects.rack[rackId])) - rack.name = action.name yield put(addPropToStoreObject('rack', rackId, { name: action.name })) yield updateTopologyOnServer(topologyId) } catch (error) { @@ -175,6 +171,7 @@ export function* onAddRackToTile(action) { const rack = { _id: uuid(), name: 'Rack', + tileId: action.tileId, capacity: DEFAULT_RACK_SLOT_CAPACITY, powerCapacityW: DEFAULT_RACK_POWER_CAPACITY, machines: [], @@ -195,6 +192,7 @@ export function* onAddMachine(action) { const machine = { _id: uuid(), + rackId, position: action.position, cpus: [], gpus: [], -- cgit v1.2.3 From 803e13b32cf0ff8b496649fb0a4d6e32400e98a4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 14 Jul 2021 22:23:40 +0200 Subject: feat(ui): Migrate to PatternFly 4 design framework This change is a rewrite of the existing OpenDC frontend in order to migrate to the PatternFly 4 design framework. PatternFly is used by Red Hat for various computing related services such as OpenShift, Red Hat Virtualization and Cockpit. Since their design requirements are very similar to those of OpenDC (modeling computing services), migrating to PatternFly 4 allows us to re-use design choices from these services. See https://www.patternfly.org/v4/ for more information about PatternFly. --- opendc-web/opendc-web-ui/next.config.js | 2 + opendc-web/opendc-web-ui/package.json | 7 +- opendc-web/opendc-web-ui/src/auth.js | 8 +- .../opendc-web-ui/src/components/AppHeader.js | 44 ++++++ .../opendc-web-ui/src/components/AppHeaderTools.js | 133 ++++++++++++++++ opendc-web/opendc-web-ui/src/components/AppLogo.js | 46 ++++++ .../src/components/AppLogo.module.scss | 33 ++++ .../opendc-web-ui/src/components/AppNavigation.js | 75 +++++++++ opendc-web/opendc-web-ui/src/components/AppPage.js | 41 +++++ .../src/components/app/map/GrayContainer.js | 34 +++++ .../src/components/app/map/LoadingScreen.js | 12 -- .../src/components/app/map/MapConstants.js | 4 +- .../src/components/app/map/MapStage.js | 66 ++++++++ .../src/components/app/map/MapStage.module.scss | 31 ++++ .../src/components/app/map/MapStageComponent.js | 97 ------------ .../src/components/app/map/RackContainer.js | 37 +++++ .../components/app/map/RackEnergyFillContainer.js | 37 +++++ .../components/app/map/RackSpaceFillContainer.js | 43 ++++++ .../src/components/app/map/RoomContainer.js | 45 ++++++ .../src/components/app/map/TileContainer.js | 46 ++++++ .../src/components/app/map/TopologyContainer.js | 35 +++++ .../src/components/app/map/WallContainer.js | 39 +++++ .../src/components/app/map/controls/Collapse.js | 42 +++++ .../app/map/controls/Collapse.module.scss | 55 +++++++ .../app/map/controls/ExportCanvasComponent.js | 15 -- .../components/app/map/controls/ScaleIndicator.js | 16 ++ .../app/map/controls/ScaleIndicator.module.scss | 10 ++ .../app/map/controls/ScaleIndicatorComponent.js | 16 -- .../controls/ScaleIndicatorComponent.module.scss | 10 -- .../app/map/controls/ToolPanelComponent.js | 13 -- .../map/controls/ToolPanelComponent.module.scss | 6 - .../src/components/app/map/controls/Toolbar.js | 28 ++++ .../app/map/controls/Toolbar.module.scss | 29 ++++ .../app/map/controls/ZoomControlComponent.js | 31 ---- .../src/components/app/map/groups/RackGroup.js | 4 +- .../src/components/app/map/groups/RoomGroup.js | 6 +- .../src/components/app/map/groups/TileGroup.js | 2 +- .../src/components/app/map/groups/TopologyGroup.js | 4 +- .../src/components/app/map/layers/MapLayer.js | 33 ++++ .../components/app/map/layers/MapLayerComponent.js | 2 +- .../components/app/map/layers/ObjectHoverLayer.js | 54 +++++++ .../components/app/map/layers/RoomHoverLayer.js | 67 ++++++++ .../components/app/results/PortfolioResultInfo.js | 40 +++++ .../src/components/app/results/PortfolioResults.js | 134 ++++++++++++++++ .../app/results/PortfolioResultsComponent.js | 93 ----------- .../src/components/app/sidebars/Sidebar.js | 48 ------ .../components/app/sidebars/Sidebar.module.scss | 57 ------- .../app/sidebars/project/PortfolioListComponent.js | 71 --------- .../sidebars/project/ProjectSidebarComponent.js | 21 --- .../app/sidebars/project/ScenarioListComponent.js | 45 ------ .../app/sidebars/project/TopologyListComponent.js | 56 ------- .../app/sidebars/topology/NameComponent.js | 73 +++++++-- .../app/sidebars/topology/TopologySidebar.js | 83 ++++++++++ .../sidebars/topology/TopologySidebar.module.scss | 37 +++++ .../sidebars/topology/TopologySidebarComponent.js | 36 ----- .../topology/building/BuildingSidebarComponent.js | 9 +- .../building/NewRoomConstructionComponent.js | 41 +++-- .../building/NewRoomConstructionContainer.js | 46 ++++++ .../topology/machine/BackToRackComponent.js | 17 --- .../app/sidebars/topology/machine/DeleteMachine.js | 54 +++++++ .../topology/machine/MachineSidebarComponent.js | 39 +++-- .../topology/machine/MachineSidebarContainer.js | 37 +++++ .../sidebars/topology/machine/UnitAddComponent.js | 48 +++--- .../sidebars/topology/machine/UnitAddContainer.js | 42 +++++ .../app/sidebars/topology/machine/UnitComponent.js | 67 -------- .../sidebars/topology/machine/UnitListComponent.js | 122 ++++++++++++--- .../sidebars/topology/machine/UnitListContainer.js | 56 +++++++ .../sidebars/topology/machine/UnitTabsComponent.js | 97 +++--------- .../sidebars/topology/rack/AddPrefabComponent.js | 8 +- .../sidebars/topology/rack/AddPrefabContainer.js | 33 ++++ .../sidebars/topology/rack/BackToRoomComponent.js | 18 --- .../sidebars/topology/rack/DeleteRackContainer.js | 54 +++++++ .../sidebars/topology/rack/EmptySlotComponent.js | 24 --- .../app/sidebars/topology/rack/MachineComponent.js | 51 +++---- .../sidebars/topology/rack/MachineListComponent.js | 69 +++++++-- .../topology/rack/MachineListComponent.module.scss | 3 - .../sidebars/topology/rack/MachineListContainer.js | 56 +++++++ .../sidebars/topology/rack/RackNameContainer.js | 22 +++ .../sidebars/topology/rack/RackSidebarComponent.js | 61 ++++++-- .../topology/rack/RackSidebarComponent.module.scss | 6 +- .../sidebars/topology/rack/RackSidebarContainer.js | 32 ++++ .../topology/room/BackToBuildingComponent.js | 17 --- .../sidebars/topology/room/DeleteRoomComponent.js | 18 --- .../sidebars/topology/room/DeleteRoomContainer.js | 54 +++++++ .../sidebars/topology/room/EditRoomContainer.js | 56 +++++++ .../topology/room/RackConstructionComponent.js | 18 +-- .../topology/room/RackConstructionContainer.js | 46 ++++++ .../app/sidebars/topology/room/RoomName.js | 44 ++++++ .../sidebars/topology/room/RoomSidebarComponent.js | 43 ++++-- .../sidebars/topology/room/RoomSidebarContainer.js | 32 ++++ .../src/components/modals/ConfirmationModal.js | 6 +- .../opendc-web-ui/src/components/modals/Modal.js | 48 ++---- .../src/components/modals/TextInputModal.js | 65 +++++--- .../modals/custom-components/NewPortfolioModal.js | 139 +++++++++++++++++ .../NewPortfolioModalComponent.js | 78 ---------- .../modals/custom-components/NewScenarioModal.js | 159 +++++++++++++++++++ .../custom-components/NewScenarioModalComponent.js | 144 ----------------- .../modals/custom-components/NewTopologyModal.js | 81 ++++++++++ .../custom-components/NewTopologyModalComponent.js | 71 --------- .../components/navigation/AppNavbarComponent.js | 37 ----- .../src/components/navigation/LogoutButton.js | 17 --- .../src/components/navigation/Navbar.js | 120 --------------- .../src/components/navigation/Navbar.module.scss | 36 ----- .../src/components/not-found/BlinkingCursor.js | 6 - .../not-found/BlinkingCursor.module.scss | 13 -- .../src/components/not-found/CodeBlock.js | 28 ---- .../src/components/not-found/CodeBlock.module.scss | 4 - .../src/components/not-found/TerminalWindow.js | 37 ----- .../not-found/TerminalWindow.module.scss | 61 -------- .../src/components/projects/FilterPanel.js | 18 +-- .../src/components/projects/NewPortfolio.js | 53 +++++++ .../src/components/projects/NewProject.js | 39 +++++ .../src/components/projects/NewProject.module.scss | 26 ++++ .../src/components/projects/NewScenario.js | 64 ++++++++ .../src/components/projects/NewTopology.js | 58 +++++++ .../src/components/projects/PortfolioTable.js | 97 ++++++++++++ .../components/projects/ProjectActionButtons.js | 38 ----- .../src/components/projects/ProjectList.js | 41 ----- .../src/components/projects/ProjectRow.js | 29 ---- .../src/components/projects/ProjectTable.js | 76 +++++++++ .../src/components/projects/ScenarioState.js | 62 ++++++++ .../src/components/projects/ScenarioTable.js | 108 +++++++++++++ .../src/components/projects/TopologyTable.js | 95 ++++++++++++ .../src/components/util/BreadcrumbLink.js | 37 +++++ .../src/components/util/NavItemLink.js | 37 +++++ .../src/components/util/TableEmptyState.js | 103 +++++++++++++ .../src/containers/app/map/GrayContainer.js | 12 -- .../src/containers/app/map/MapStage.js | 26 ---- .../src/containers/app/map/RackContainer.js | 10 -- .../containers/app/map/RackEnergyFillContainer.js | 32 ---- .../containers/app/map/RackSpaceFillContainer.js | 16 -- .../src/containers/app/map/RoomContainer.js | 23 --- .../src/containers/app/map/TileContainer.js | 19 --- .../src/containers/app/map/TopologyContainer.js | 13 -- .../src/containers/app/map/WallContainer.js | 12 -- .../app/map/controls/ScaleIndicatorContainer.js | 10 -- .../app/map/controls/ZoomControlContainer.js | 13 -- .../src/containers/app/map/layers/MapLayer.js | 11 -- .../containers/app/map/layers/ObjectHoverLayer.js | 32 ---- .../containers/app/map/layers/RoomHoverLayer.js | 45 ------ .../app/results/PortfolioResultsContainer.js | 14 -- .../app/sidebars/project/PortfolioListContainer.js | 48 ------ .../sidebars/project/ProjectSidebarContainer.js | 11 -- .../app/sidebars/project/ScenarioListContainer.js | 67 -------- .../app/sidebars/project/TopologyListContainer.js | 67 -------- .../sidebars/topology/TopologySidebarContainer.js | 10 -- .../topology/building/BuildingSidebarContainer.js | 5 - .../building/NewRoomConstructionContainer.js | 28 ---- .../topology/machine/BackToRackContainer.js | 11 -- .../topology/machine/DeleteMachineContainer.js | 34 ----- .../topology/machine/MachineNameContainer.js | 9 -- .../topology/machine/MachineSidebarContainer.js | 15 -- .../sidebars/topology/machine/UnitAddContainer.js | 15 -- .../sidebars/topology/machine/UnitListContainer.js | 34 ----- .../sidebars/topology/machine/UnitTabsContainer.js | 5 - .../sidebars/topology/rack/AddPrefabContainer.js | 11 -- .../sidebars/topology/rack/BackToRoomContainer.js | 11 -- .../sidebars/topology/rack/DeleteRackContainer.js | 34 ----- .../sidebars/topology/rack/MachineListContainer.js | 29 ---- .../sidebars/topology/rack/RackNameContainer.js | 33 ---- .../sidebars/topology/rack/RackSidebarContainer.js | 10 -- .../topology/room/BackToBuildingContainer.js | 12 -- .../sidebars/topology/room/DeleteRoomContainer.js | 34 ----- .../sidebars/topology/room/EditRoomContainer.js | 35 ----- .../topology/room/RackConstructionContainer.js | 24 --- .../sidebars/topology/room/RoomNameContainer.js | 31 ---- .../sidebars/topology/room/RoomSidebarContainer.js | 10 -- .../opendc-web-ui/src/containers/auth/Login.js | 21 --- .../opendc-web-ui/src/containers/auth/Logout.js | 10 -- .../src/containers/auth/ProfileName.js | 9 -- .../containers/navigation/AppNavbarContainer.js | 11 -- .../src/containers/projects/NewProjectContainer.js | 34 ----- .../src/containers/projects/ProjectActions.js | 14 -- .../containers/projects/ProjectListContainer.js | 34 ----- opendc-web/opendc-web-ui/src/data/map.js | 4 - opendc-web/opendc-web-ui/src/data/project.js | 52 +++---- opendc-web/opendc-web-ui/src/data/topology.js | 10 +- opendc-web/opendc-web-ui/src/index.scss | 68 --------- opendc-web/opendc-web-ui/src/pages/404.js | 33 +++- opendc-web/opendc-web-ui/src/pages/404.module.scss | 8 - opendc-web/opendc-web-ui/src/pages/_app.js | 15 +- opendc-web/opendc-web-ui/src/pages/logout.js | 10 +- .../src/pages/projects/[project]/index.js | 111 +++++++++++++- .../projects/[project]/portfolios/[portfolio].js | 170 ++++++++++++++++++--- .../projects/[project]/topologies/[topology].js | 73 ++++++--- .../opendc-web-ui/src/pages/projects/index.js | 90 ++++++++--- opendc-web/opendc-web-ui/src/shapes.js | 2 + opendc-web/opendc-web-ui/src/style/_mixins.scss | 5 - opendc-web/opendc-web-ui/src/style/_variables.scss | 31 ---- opendc-web/opendc-web-ui/src/style/index.scss | 36 +++++ .../opendc-web-ui/src/util/authorizations.js | 10 +- .../opendc-web-ui/src/util/available-metrics.js | 45 +++++- opendc-web/opendc-web-ui/src/util/date-time.js | 14 +- .../opendc-web-ui/src/util/date-time.test.js | 16 +- opendc-web/opendc-web-ui/yarn.lock | 132 ++++++---------- 195 files changed, 4429 insertions(+), 3283 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/components/AppHeader.js create mode 100644 opendc-web/opendc-web-ui/src/components/AppHeaderTools.js create mode 100644 opendc-web/opendc-web-ui/src/components/AppLogo.js create mode 100644 opendc-web/opendc-web-ui/src/components/AppLogo.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/AppNavigation.js create mode 100644 opendc-web/opendc-web-ui/src/components/AppPage.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/LoadingScreen.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/MapStage.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ExportCanvasComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ZoomControlComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultsComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/project/ProjectSidebarComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/project/TopologyListComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebarComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/BackToRackComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/BackToRoomComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/EmptySlotComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/BackToBuildingComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModalComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModalComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModalComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js delete mode 100644 opendc-web/opendc-web-ui/src/components/navigation/Navbar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js delete mode 100644 opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewProject.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewProject.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewScenario.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewTopology.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/PortfolioTable.js delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/ProjectList.js delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/ProjectTable.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js create mode 100644 opendc-web/opendc-web-ui/src/components/util/BreadcrumbLink.js create mode 100644 opendc-web/opendc-web-ui/src/components/util/NavItemLink.js create mode 100644 opendc-web/opendc-web-ui/src/components/util/TableEmptyState.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/auth/Login.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/auth/Logout.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/index.scss delete mode 100644 opendc-web/opendc-web-ui/src/pages/404.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/style/_mixins.scss delete mode 100644 opendc-web/opendc-web-ui/src/style/_variables.scss create mode 100644 opendc-web/opendc-web-ui/src/style/index.scss diff --git a/opendc-web/opendc-web-ui/next.config.js b/opendc-web/opendc-web-ui/next.config.js index 56263c86..9092adc4 100644 --- a/opendc-web/opendc-web-ui/next.config.js +++ b/opendc-web/opendc-web-ui/next.config.js @@ -25,6 +25,8 @@ const withTM = require('next-transpile-modules')([ '@patternfly/react-core', '@patternfly/react-styles', + '@patternfly/react-table', + '@patternfly/react-tokens', ]) module.exports = withTM({ diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 442d63a5..84db4277 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -22,11 +22,12 @@ "@fortawesome/free-brands-svg-icons": "^5.15.3", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.14", - "@patternfly/react-core": "^4.135.0", + "@patternfly/react-core": "^4.135.7", + "@patternfly/react-icons": "^4.11.2", + "@patternfly/react-table": "^4.29.8", "@sentry/react": "^5.30.0", "@sentry/tracing": "^5.30.0", "approximate-number": "~2.0.0", - "bootstrap": "~4.6.0", "classnames": "~2.2.5", "husky": "~4.2.5", "konva": "~7.2.5", @@ -43,7 +44,6 @@ "react-konva": "~17.0.2-0", "react-query": "^3.18.1", "react-redux": "~7.2.0", - "reactstrap": "^8.9.0", "recharts": "~2.0.9", "redux": "~4.0.5", "redux-logger": "~3.0.6", @@ -51,6 +51,7 @@ "redux-thunk": "~2.3.0", "sass": "^1.32.12", "svgsaver": "~0.9.0", + "use-resize-observer": "^7.0.0", "uuidv4": "~6.1.1" }, "devDependencies": { diff --git a/opendc-web/opendc-web-ui/src/auth.js b/opendc-web/opendc-web-ui/src/auth.js index 96417e67..e670476c 100644 --- a/opendc-web/opendc-web-ui/src/auth.js +++ b/opendc-web/opendc-web-ui/src/auth.js @@ -23,7 +23,6 @@ import PropTypes from 'prop-types' import { Auth0Provider, useAuth0 } from '@auth0/auth0-react' import { useEffect } from 'react' -import { useRouter } from 'next/router' /** * Obtain the authentication context. @@ -37,14 +36,13 @@ export function useAuth() { */ export function useRequireAuth() { const auth = useAuth() - const router = useRouter() - const { isLoading, isAuthenticated } = auth + const { loginWithRedirect, isLoading, isAuthenticated } = auth useEffect(() => { if (!isLoading && !isAuthenticated) { - router.replace('/') + loginWithRedirect() } - }, [router, isLoading, isAuthenticated]) + }, [loginWithRedirect, isLoading, isAuthenticated]) return auth } diff --git a/opendc-web/opendc-web-ui/src/components/AppHeader.js b/opendc-web/opendc-web-ui/src/components/AppHeader.js new file mode 100644 index 00000000..b33212c4 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/AppHeader.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { PageHeader } from '@patternfly/react-core' +import React from 'react' +import Image from 'next/image' +import AppHeaderTools from './AppHeaderTools' +import { AppNavigation } from './AppNavigation' +import AppLogo from './AppLogo' + +export function AppHeader() { + const logo = OpenDC + + return ( + } + topNav={} + /> + ) +} + +AppHeader.propTypes = {} diff --git a/opendc-web/opendc-web-ui/src/components/AppHeaderTools.js b/opendc-web/opendc-web-ui/src/components/AppHeaderTools.js new file mode 100644 index 00000000..02e5d265 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/AppHeaderTools.js @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { + Avatar, + Button, + ButtonVariant, + Dropdown, + DropdownGroup, + DropdownItem, + DropdownToggle, + KebabToggle, + PageHeaderTools, + PageHeaderToolsGroup, + PageHeaderToolsItem, + Skeleton, +} from '@patternfly/react-core' +import { useState } from 'react' +import { useAuth } from '../auth' +import { GithubIcon, HelpIcon } from '@patternfly/react-icons' + +function AppHeaderTools() { + const auth = useAuth() + + const [isKebabDropdownOpen, setKebabDropdownOpen] = useState(false) + const kebabDropdownItems = [ + + Help + + } + />, + ] + + const [isDropdownOpen, setDropdownOpen] = useState(false) + const userDropdownItems = [ + + auth.logout({ returnTo: window.location.origin })}> + Logout + + , + ] + + return ( + + + + + + + + + + + + setKebabDropdownOpen(!isKebabDropdownOpen)} />} + isOpen={isKebabDropdownOpen} + dropdownItems={kebabDropdownItems} + /> + + + setDropdownOpen(!isDropdownOpen)}> + {auth?.user?.name ?? ( + + )} + + } + dropdownItems={userDropdownItems} + /> + + + {auth?.user?.picture ? ( + + ) : ( + + )} + + ) +} + +AppHeaderTools.propTypes = {} + +export default AppHeaderTools diff --git a/opendc-web/opendc-web-ui/src/components/AppLogo.js b/opendc-web/opendc-web-ui/src/components/AppLogo.js new file mode 100644 index 00000000..92663295 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/AppLogo.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import Link from 'next/link' +import { appLogo } from './AppLogo.module.scss' + +function AppLogo({ href, children, className, ...props }) { + return ( + <> + + + {children} + OpenDC + + + + ) +} + +AppLogo.propTypes = { + href: PropTypes.string.isRequired, + children: PropTypes.node, + className: PropTypes.string, +} + +export default AppLogo diff --git a/opendc-web/opendc-web-ui/src/components/AppLogo.module.scss b/opendc-web/opendc-web-ui/src/components/AppLogo.module.scss new file mode 100644 index 00000000..3d228cb6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/AppLogo.module.scss @@ -0,0 +1,33 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.appLogo { + span { + margin-left: 4px; + color: #fff; + } + + &:hover, + &:focus { + text-decoration: none; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/AppNavigation.js b/opendc-web/opendc-web-ui/src/components/AppNavigation.js new file mode 100644 index 00000000..b3f11f34 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/AppNavigation.js @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Dropdown, DropdownItem, DropdownToggle, Nav, NavItem, NavList } from '@patternfly/react-core' +import { useRouter } from 'next/router' +import NavItemLink from './util/NavItemLink' +import { useProject } from '../data/project' + +export function AppNavigation() { + const { pathname, query } = useRouter() + const { project: projectId } = query + const { data: project } = useProject(projectId) + + const nextTopologyId = project?.topologyIds?.[0] + const nextPortfolioId = project?.portfolioIds?.[0] + + return ( + + ) +} + +AppNavigation.propTypes = {} diff --git a/opendc-web/opendc-web-ui/src/components/AppPage.js b/opendc-web/opendc-web-ui/src/components/AppPage.js new file mode 100644 index 00000000..7cf9cc15 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/AppPage.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { AppHeader } from './AppHeader' +import { AppNavigation } from './AppNavigation' +import React, { useState } from 'react' +import { Page } from '@patternfly/react-core' + +export function AppPage({ children, breadcrumb, tertiaryNav }) { + return ( + }> + {children} + + ) +} + +AppPage.propTypes = { + breadcrumb: PropTypes.node, + tertiaryNav: PropTypes.node, + children: PropTypes.node, +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js new file mode 100644 index 00000000..4791940f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch } from 'react-redux' +import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' +import GrayLayer from '../../../components/app/map/elements/GrayLayer' + +const GrayContainer = () => { + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + return +} + +export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/LoadingScreen.js b/opendc-web/opendc-web-ui/src/components/app/map/LoadingScreen.js deleted file mode 100644 index ddb94990..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/LoadingScreen.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faSpinner } from '@fortawesome/free-solid-svg-icons' - -const LoadingScreen = () => ( -
- - Loading your project... -
-) - -export default LoadingScreen diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js b/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js index d6ea1f84..45799f70 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js @@ -8,8 +8,8 @@ export const TILE_PLUS_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 3 export const OBJECT_SIZE_IN_PIXELS = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 export const GRID_LINE_WIDTH_IN_PIXELS = 2 -export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 8 -export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 12 +export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 +export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 export const TILE_PLUS_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 10 export const SIDEBAR_WIDTH = 350 diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js new file mode 100644 index 00000000..73accf3f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js @@ -0,0 +1,66 @@ +import React, { useEffect, useRef, useState } from 'react' +import { HotKeys } from 'react-hotkeys' +import { Stage } from 'react-konva' +import { MAP_MOVE_PIXELS_PER_EVENT } from './MapConstants' +import { Provider, useDispatch, useStore } from 'react-redux' +import useResizeObserver from 'use-resize-observer' +import { mapContainer } from './MapStage.module.scss' +import { useMapPosition } from '../../../data/map' +import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../redux/actions/map' +import MapLayer from './layers/MapLayer' +import RoomHoverLayer from './layers/RoomHoverLayer' +import ObjectHoverLayer from './layers/ObjectHoverLayer' + +function MapStage() { + const store = useStore() + const dispatch = useDispatch() + + const stage = useRef(null) + const [pos, setPos] = useState([0, 0]) + const [x, y] = pos + const handlers = { + MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), + MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), + } + const mapPosition = useMapPosition() + const { ref, width = 100, height = 100 } = useResizeObserver() + + const moveWithDelta = (deltaX, deltaY) => + dispatch(setMapPositionWithBoundsCheck(mapPosition.x + deltaX, mapPosition.y + deltaY)) + const updateMousePosition = () => { + if (!stage.current) { + return + } + + const mousePos = stage.current.getStage().getPointerPosition() + setPos([mousePos.x, mousePos.y]) + } + const updateScale = ({ evt }) => dispatch(zoomInOnPosition(evt.deltaY < 0, x, y)) + + useEffect(() => { + window['exportCanvasToImage'] = () => { + const download = document.createElement('a') + download.href = stage.current.getStage().toDataURL() + download.download = 'opendc-canvas-export-' + Date.now() + '.png' + download.click() + } + }, [stage]) + + useEffect(() => dispatch(setMapDimensions(width, height)), [width, height]) // eslint-disable-line react-hooks/exhaustive-deps + + return ( + + + + + + + + + + ) +} + +export default MapStage diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss new file mode 100644 index 00000000..d879b4c8 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss @@ -0,0 +1,31 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.mapContainer { + background-color: var(--pf-global--Color--light-200); + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js deleted file mode 100644 index c3177fe1..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js +++ /dev/null @@ -1,97 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useEffect, useRef, useState } from 'react' -import { HotKeys } from 'react-hotkeys' -import { Stage } from 'react-konva' -import MapLayer from '../../../containers/app/map/layers/MapLayer' -import ObjectHoverLayer from '../../../containers/app/map/layers/ObjectHoverLayer' -import RoomHoverLayer from '../../../containers/app/map/layers/RoomHoverLayer' -import { NAVBAR_HEIGHT } from '../../navigation/Navbar' -import { MAP_MOVE_PIXELS_PER_EVENT } from './MapConstants' -import { Provider, useStore } from 'react-redux' - -function MapStageComponent({ - mapDimensions, - mapPosition, - setMapDimensions, - setMapPositionWithBoundsCheck, - zoomInOnPosition, -}) { - const [pos, setPos] = useState([0, 0]) - const stage = useRef(null) - const [x, y] = pos - const handlers = { - MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), - MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), - MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), - MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), - } - - const moveWithDelta = (deltaX, deltaY) => - setMapPositionWithBoundsCheck(mapPosition.x + deltaX, mapPosition.y + deltaY) - const updateMousePosition = () => { - if (!stage.current) { - return - } - - const mousePos = stage.current.getStage().getPointerPosition() - setPos([mousePos.x, mousePos.y]) - } - - const updateDimensions = () => setMapDimensions(window.innerWidth, window.innerHeight - NAVBAR_HEIGHT) - const updateScale = (e) => zoomInOnPosition(e.deltaY < 0, x, y) - - // We explicitly do not specify any dependencies to prevent infinitely dispatching updateDimensions commands - useEffect(() => { - updateDimensions() - - window.addEventListener('resize', updateDimensions) - window.addEventListener('wheel', updateScale) - - window['exportCanvasToImage'] = () => { - const download = document.createElement('a') - download.href = stage.current.getStage().toDataURL() - download.download = 'opendc-canvas-export-' + Date.now() + '.png' - download.click() - } - - return () => { - window.removeEventListener('resize', updateDimensions) - window.removeEventListener('wheel', updateScale) - } - }, []) // eslint-disable-line react-hooks/exhaustive-deps - - const store = useStore() - - return ( - - - - - - - - - - ) -} - -MapStageComponent.propTypes = { - mapDimensions: PropTypes.shape({ - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - }).isRequired, - mapPosition: PropTypes.shape({ - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - }).isRequired, - setMapDimensions: PropTypes.func, - setMapPositionWithBoundsCheck: PropTypes.func, - zoomInOnPosition: PropTypes.func, -} - -export default MapStageComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js new file mode 100644 index 00000000..3c75d3a7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import RackGroup from '../../../components/app/map/groups/RackGroup' +import { Tile } from '../../../shapes' + +const RackContainer = ({ tile }) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + return +} + +RackContainer.propTypes = { + tile: Tile, +} + +export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js new file mode 100644 index 00000000..838aea5a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js @@ -0,0 +1,37 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' +import RackFillBar from '../../../components/app/map/elements/RackFillBar' + +const RackSpaceFillContainer = (props) => { + const state = useSelector((state) => { + let energyConsumptionTotal = 0 + const rack = state.objects.rack[state.objects.tile[props.tileId].rack] + const machineIds = rack.machines + machineIds.forEach((machineId) => { + if (machineId !== null) { + const machine = state.objects.machine[machineId] + machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) + machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) + machine.memories.forEach( + (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) + ) + machine.storages.forEach( + (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) + ) + } + }) + + return { + type: 'energy', + fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), + } + }) + return +} + +RackSpaceFillContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js new file mode 100644 index 00000000..6791120e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' +import RackFillBar from '../../../components/app/map/elements/RackFillBar' + +const RackSpaceFillContainer = (props) => { + const state = useSelector((state) => { + const machineIds = state.objects.rack[state.objects.tile[props.tileId].rack].machines + return { + type: 'space', + fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, + } + }) + return +} + +RackSpaceFillContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js new file mode 100644 index 00000000..26fbcd7a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' +import RoomGroup from '../../../components/app/map/groups/RoomGroup' + +const RoomContainer = (props) => { + const state = useSelector((state) => { + return { + interactionLevel: state.interactionLevel, + currentRoomInConstruction: state.construction.currentRoomInConstruction, + room: state.objects.room[props.roomId], + } + }) + const dispatch = useDispatch() + return dispatch(goFromBuildingToRoom(props.roomId))} /> +} + +RoomContainer.propTypes = { + roomId: PropTypes.string, +} + +export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js new file mode 100644 index 00000000..bfcbf735 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { useDispatch, useSelector } from 'react-redux' +import { goFromRoomToRack } from '../../../redux/actions/interaction-level' +import TileGroup from '../../../components/app/map/groups/TileGroup' + +const TileContainer = (props) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + const tile = useSelector((state) => state.objects.tile[props.tileId]) + + const dispatch = useDispatch() + const onClick = (tile) => { + if (tile.rack) { + dispatch(goFromRoomToRack(tile._id)) + } + } + return +} + +TileContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js new file mode 100644 index 00000000..78e75d0f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' +import { useActiveTopology } from '../../../data/topology' + +const TopologyContainer = () => { + const topology = useActiveTopology() + const interactionLevel = useSelector((state) => state.interactionLevel) + + return +} + +export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js new file mode 100644 index 00000000..51dffe4b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' +import WallGroup from '../../../components/app/map/groups/WallGroup' + +const WallContainer = (props) => { + const tiles = useSelector((state) => + state.objects.room[props.roomId].tiles.map((tileId) => state.objects.tile[tileId]) + ) + return +} + +WallContainer.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js new file mode 100644 index 00000000..f54b7c84 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { ChevronLeftIcon } from '@patternfly/react-icons' +import { collapseContainer } from './Collapse.module.scss' +import { Button } from '@patternfly/react-core' + +function Collapse({ onClick }) { + return ( +
+ +
+ ) +} + +Collapse.propTypes = { + onClick: PropTypes.func, +} + +export default Collapse diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss new file mode 100644 index 00000000..0c1fac94 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss @@ -0,0 +1,55 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.collapseContainer { + position: absolute; + right: var(--pf-global--spacer--xs); + top: 0; + bottom: 10%; + margin: auto 0; + height: 50px; + + button:global(.pf-m-tertiary) { + height: 100%; + padding: 2px; + + margin-right: var(--pf-global--spacer--xs); + margin-top: var(--pf-global--spacer--xs); + background-color: var(--pf-global--BackgroundColor--100); + border: none; + border-radius: var(--pf-global--BorderRadius--sm); + box-shadow: var(--pf-global--BoxShadow--sm); + + &:not(:global(.pf-m-disabled)) { + background-color: var(--pf-global--BackgroundColor--100); + } + + &:after { + display: none; + } + + &:hover { + border: none; + box-shadow: var(--pf-global--BoxShadow--md); + } + } +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ExportCanvasComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ExportCanvasComponent.js deleted file mode 100644 index 9e8cb36a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ExportCanvasComponent.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCamera } from '@fortawesome/free-solid-svg-icons' - -const ExportCanvasComponent = () => ( - -) - -export default ExportCanvasComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js new file mode 100644 index 00000000..11c2f2d3 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js @@ -0,0 +1,16 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from '../MapConstants' +import { scaleIndicator } from './ScaleIndicator.module.scss' + +const ScaleIndicator = ({ scale }) => ( +
+ {TILE_SIZE_IN_METERS}m +
+) + +ScaleIndicator.propTypes = { + scale: PropTypes.number.isRequired, +} + +export default ScaleIndicator diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss new file mode 100644 index 00000000..f19e0ff2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss @@ -0,0 +1,10 @@ +.scaleIndicator { + position: absolute; + right: 10px; + bottom: 10px; + z-index: 50; + + border: solid 2px #212529; + border-top: none; + border-left: none; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js deleted file mode 100644 index ef633764..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.js +++ /dev/null @@ -1,16 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from '../MapConstants' -import { scaleIndicator } from './ScaleIndicatorComponent.module.scss' - -const ScaleIndicatorComponent = ({ scale }) => ( -
- {TILE_SIZE_IN_METERS}m -
-) - -ScaleIndicatorComponent.propTypes = { - scale: PropTypes.number.isRequired, -} - -export default ScaleIndicatorComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss deleted file mode 100644 index f19e0ff2..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicatorComponent.module.scss +++ /dev/null @@ -1,10 +0,0 @@ -.scaleIndicator { - position: absolute; - right: 10px; - bottom: 10px; - z-index: 50; - - border: solid 2px #212529; - border-top: none; - border-left: none; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js deleted file mode 100644 index d2f70953..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import ZoomControlContainer from '../../../../containers/app/map/controls/ZoomControlContainer' -import ExportCanvasComponent from './ExportCanvasComponent' -import { toolPanel } from './ToolPanelComponent.module.scss' - -const ToolPanelComponent = () => ( -
- - -
-) - -export default ToolPanelComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss deleted file mode 100644 index 970b1ce2..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ToolPanelComponent.module.scss +++ /dev/null @@ -1,6 +0,0 @@ -.toolPanel { - position: absolute; - left: 10px; - bottom: 10px; - z-index: 50; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js new file mode 100644 index 00000000..4c60bfb2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js @@ -0,0 +1,28 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { control, toolBar } from './Toolbar.module.scss' +import { Button } from '@patternfly/react-core' +import { SearchPlusIcon, SearchMinusIcon } from '@patternfly/react-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faCamera } from '@fortawesome/free-solid-svg-icons' + +const Toolbar = ({ onZoom, onExport }) => ( +
+ + + +
+) + +Toolbar.propTypes = { + onZoom: PropTypes.func, + onExport: PropTypes.func, +} + +export default Toolbar diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss new file mode 100644 index 00000000..0d505acc --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss @@ -0,0 +1,29 @@ +.toolBar { + position: absolute; + bottom: var(--pf-global--spacer--md); + left: var(--pf-global--spacer--xl); +} + +.control { + &:global(.pf-m-tertiary) { + margin-right: var(--pf-global--spacer--xs); + margin-top: var(--pf-global--spacer--xs); + background-color: var(--pf-global--BackgroundColor--100); + border: none; + border-radius: var(--pf-global--BorderRadius--sm); + box-shadow: var(--pf-global--BoxShadow--sm); + + &:not(:global(.pf-m-disabled)) { + background-color: var(--pf-global--BackgroundColor--100); + } + + &:after { + display: none; + } + + &:hover { + border: none; + box-shadow: var(--pf-global--BoxShadow--md); + } + } +} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ZoomControlComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ZoomControlComponent.js deleted file mode 100644 index 6c3c6cb7..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ZoomControlComponent.js +++ /dev/null @@ -1,31 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus, faMinus } from '@fortawesome/free-solid-svg-icons' - -const ZoomControlComponent = ({ zoomInOnCenter }) => { - return ( - - - - - ) -} - -ZoomControlComponent.propTypes = { - zoomInOnCenter: PropTypes.func.isRequired, -} - -export default ZoomControlComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js index 40e28f01..9c4abc4a 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js @@ -1,10 +1,10 @@ import React from 'react' import { Group } from 'react-konva' -import RackEnergyFillContainer from '../../../../containers/app/map/RackEnergyFillContainer' -import RackSpaceFillContainer from '../../../../containers/app/map/RackSpaceFillContainer' import { Tile } from '../../../../shapes' import { RACK_BACKGROUND_COLOR } from '../../../../util/colors' import TileObject from '../elements/TileObject' +import RackSpaceFillContainer from '../RackSpaceFillContainer' +import RackEnergyFillContainer from '../RackEnergyFillContainer' const RackGroup = ({ tile }) => { return ( diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js index 42d20ff1..a14f3676 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js @@ -1,10 +1,10 @@ import PropTypes from 'prop-types' import React from 'react' import { Group } from 'react-konva' -import GrayContainer from '../../../../containers/app/map/GrayContainer' -import TileContainer from '../../../../containers/app/map/TileContainer' -import WallContainer from '../../../../containers/app/map/WallContainer' import { InteractionLevel, Room } from '../../../../shapes' +import GrayContainer from '../GrayContainer' +import TileContainer from '../TileContainer' +import WallContainer from '../WallContainer' const RoomGroup = ({ room, interactionLevel, currentRoomInConstruction, onClick }) => { if (currentRoomInConstruction === room._id) { diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js index ce5e4a6b..cd36c7e5 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js @@ -1,10 +1,10 @@ import PropTypes from 'prop-types' import React from 'react' import { Group } from 'react-konva' -import RackContainer from '../../../../containers/app/map/RackContainer' import { Tile } from '../../../../shapes' import { ROOM_DEFAULT_COLOR, ROOM_IN_CONSTRUCTION_COLOR } from '../../../../util/colors' import RoomTile from '../elements/RoomTile' +import RackContainer from '../RackContainer' const TileGroup = ({ tile, newTile, onClick }) => { let tileObject diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js index d4c6db7d..d3bcb279 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js @@ -1,8 +1,8 @@ import React from 'react' import { Group } from 'react-konva' -import GrayContainer from '../../../../containers/app/map/GrayContainer' -import RoomContainer from '../../../../containers/app/map/RoomContainer' import { InteractionLevel, Topology } from '../../../../shapes' +import RoomContainer from '../RoomContainer' +import GrayContainer from '../GrayContainer' const TopologyGroup = ({ topology, interactionLevel }) => { if (!topology) { diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js new file mode 100644 index 00000000..badb9f68 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' +import { useMapPosition, useMapScale } from '../../../../data/map' + +const MapLayer = (props) => { + const position = useMapPosition() + const scale = useMapScale() + return +} + +export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js index 96e6867c..efe5b4e5 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js @@ -1,9 +1,9 @@ import PropTypes from 'prop-types' import React from 'react' import { Group, Layer } from 'react-konva' -import TopologyContainer from '../../../../containers/app/map/TopologyContainer' import Backdrop from '../elements/Backdrop' import GridGroup from '../groups/GridGroup' +import TopologyContainer from '../TopologyContainer' const MapLayerComponent = ({ mapPosition, mapScale }) => ( diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js new file mode 100644 index 00000000..9a087bd5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { addRackToTile } from '../../../../redux/actions/topology/room' +import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' +import { findTileWithPosition } from '../../../../util/tile-calculations' + +const ObjectHoverLayer = (props) => { + const state = useSelector((state) => { + return { + mapPosition: state.map.position, + mapScale: state.map.scale, + isEnabled: () => state.construction.inRackConstructionMode, + isValid: (x, y) => { + if (state.interactionLevel.mode !== 'ROOM') { + return false + } + + const currentRoom = state.objects.room[state.interactionLevel.roomId] + const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) + const tile = findTileWithPosition(tiles, x, y) + + return !(tile === null || tile.rack) + }, + } + }) + + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(addRackToTile(x, y)) + return +} + +export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js new file mode 100644 index 00000000..87240813 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' +import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' +import { + deriveValidNextTilePositions, + findPositionInPositions, + findPositionInRooms, +} from '../../../../util/tile-calculations' + +const RoomHoverLayer = (props) => { + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) + + const state = useSelector((state) => { + return { + mapPosition: state.map.position, + mapScale: state.map.scale, + isEnabled: () => state.construction.currentRoomInConstruction !== '-1', + isValid: (x, y) => { + const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) + const oldRooms = Object.keys(state.objects.room) + .map((id) => Object.assign({}, state.objects.room[id])) + .filter( + (room) => + state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && + room._id !== state.construction.currentRoomInConstruction + ) + + ;[...oldRooms, newRoom].forEach((room) => { + room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) + }) + if (newRoom.tiles.length === 0) { + return findPositionInRooms(oldRooms, x, y) === -1 + } + + const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) + return findPositionInPositions(validNextPositions, x, y) !== -1 + }, + } + }) + return +} + +export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js new file mode 100644 index 00000000..09348e60 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { Tooltip } from '@patternfly/react-core' +import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' +import { METRIC_DESCRIPTIONS } from '../../../util/available-metrics' + +function PortfolioResultInfo({ metric }) { + return ( + {METRIC_DESCRIPTIONS[metric]}
}> + + + ) +} + +PortfolioResultInfo.propTypes = { + metric: PropTypes.string.isRequired, +} + +export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js new file mode 100644 index 00000000..6a96c70c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js @@ -0,0 +1,134 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' +import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_NAMES_SHORT, METRIC_UNITS } from '../../../util/available-metrics' +import { mean, std } from 'mathjs' +import approx from 'approximate-number' +import { + Bullseye, + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + Grid, + GridItem, + Spinner, + Title, +} from '@patternfly/react-core' +import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' +import { usePortfolioScenarios } from '../../../data/project' +import NewScenario from '../../projects/NewScenario' +import PortfolioResultInfo from './PortfolioResultInfo' + +const PortfolioResults = ({ portfolioId }) => { + const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) + + if (status === 'loading') { + return ( + + + + + Loading Results + + + + ) + } else if (status === 'error') { + return ( + + + + + Unable to connect + + + There was an error retrieving data. Check your connection and try again. + + + + ) + } else if (scenarios.length === 0) { + return ( + + + + + No results + + + No results are currently available for this portfolio. Run a scenario to obtain simulation + results. + + + + + ) + } + + const dataPerMetric = {} + + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios + .filter((scenario) => scenario.results) + .map((scenario) => ({ + name: scenario.name, + value: mean(scenario.results[metric]), + errorX: std(scenario.results[metric]), + })) + }) + + return ( + + {AVAILABLE_METRICS.map((metric) => ( + + + + + + + {METRIC_NAMES[metric]} + + + + + + approx(tick)} + label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} + type="number" + /> + + + + + + + + + + + ))} + + ) +} + +PortfolioResults.propTypes = { + portfolioId: PropTypes.string, +} + +export default PortfolioResults diff --git a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultsComponent.js b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultsComponent.js deleted file mode 100644 index 983a5c1d..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultsComponent.js +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' -import { AVAILABLE_METRICS, METRIC_NAMES_SHORT, METRIC_UNITS } from '../../../util/available-metrics' -import { mean, std } from 'mathjs' -import { Portfolio, Scenario } from '../../../shapes' -import approx from 'approximate-number' - -const PortfolioResultsComponent = ({ portfolio, scenarios }) => { - if (!portfolio) { - return
Loading...
- } - - const nonFinishedScenarios = scenarios.filter((s) => s.simulation.state !== 'FINISHED') - - if (nonFinishedScenarios.length > 0) { - if (nonFinishedScenarios.every((s) => s.simulation.state === 'QUEUED' || s.simulation.state === 'RUNNING')) { - return ( -
-

Simulation running...

-

{nonFinishedScenarios.length} of the scenarios are still being simulated

-
- ) - } - if (nonFinishedScenarios.some((s) => s.simulation.state === 'FAILED')) { - return ( -
-

Simulation failed.

-

- Try again by creating a new scenario. Please contact the OpenDC team for support, if issues - persist. -

-
- ) - } - } - - const dataPerMetric = {} - - AVAILABLE_METRICS.forEach((metric) => { - dataPerMetric[metric] = scenarios.map((scenario) => ({ - name: scenario.name, - value: mean(scenario.results[metric]), - errorX: std(scenario.results[metric]), - })) - }) - - return ( -
-

Portfolio: {portfolio.name}

-

Repeats per Scenario: {portfolio.targets.repeatsPerScenario}

-
- {AVAILABLE_METRICS.map((metric) => ( -
-

{METRIC_NAMES_SHORT[metric]}

- - - - approx(tick)} - label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} - type="number" - /> - - - - - - - -
- ))} -
-
- ) -} - -PortfolioResultsComponent.propTypes = { - portfolio: Portfolio, - scenarios: PropTypes.arrayOf(Scenario), -} - -export default PortfolioResultsComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js deleted file mode 100644 index 56fa799f..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.js +++ /dev/null @@ -1,48 +0,0 @@ -import PropTypes from 'prop-types' -import classNames from 'classnames' -import React, { useState } from 'react' -import { collapseButton, collapseButtonRight, sidebar, sidebarRight } from './Sidebar.module.scss' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faAngleLeft, faAngleRight } from '@fortawesome/free-solid-svg-icons' - -function Sidebar({ isRight, collapsible = true, children }) { - const [isCollapsed, setCollapsed] = useState(false) - - const button = ( -
setCollapsed(!isCollapsed)} - > - {(isCollapsed && isRight) || (!isCollapsed && !isRight) ? ( - - ) : ( - - )} -
- ) - - if (isCollapsed) { - return button - } - return ( -
e.stopPropagation()} - > - {children} - {collapsible && button} -
- ) -} - -Sidebar.propTypes = { - isRight: PropTypes.bool.isRequired, - collapsible: PropTypes.bool, - children: PropTypes.node, -} - -export default Sidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss deleted file mode 100644 index 19c6a97f..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/Sidebar.module.scss +++ /dev/null @@ -1,57 +0,0 @@ -@import 'src/style/_variables.scss'; -@import 'src/style/_mixins.scss'; - -.collapseButton { - position: absolute; - left: 5px; - top: 5px; - padding: 5px 7px; - - background: white; - border: solid 1px $gray-semi-light; - z-index: 99; - - @include clickable; - border-radius: 5px; - transition: background 200ms; - - &.collapseButtonRight { - left: auto; - right: 5px; - top: 5px; - } - - &:hover { - background: #eeeeee; - } -} - -.sidebar { - position: absolute; - top: 0; - left: 0; - width: $side-bar-width; - - z-index: 100; - background: white; - - border-right: $gray-semi-dark 1px solid; - - .collapseButton { - left: auto; - right: -25px; - } -} - -.sidebarRight { - left: auto; - right: 0; - - border-left: $gray-semi-dark 1px solid; - border-right: none; - - .collapseButtonRight { - left: -25px; - right: auto; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js deleted file mode 100644 index d61ff24e..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js +++ /dev/null @@ -1,71 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Portfolio } from '../../../../shapes' -import Link from 'next/link' -import ScenarioListContainer from '../../../../containers/app/sidebars/project/ScenarioListContainer' -import { Button, Col, Row } from 'reactstrap' -import classNames from 'classnames' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus, faPlay, faTrash } from '@fortawesome/free-solid-svg-icons' - -function PortfolioListComponent({ - portfolios, - currentProjectId, - currentPortfolioId, - onNewPortfolio, - onChoosePortfolio, - onDeletePortfolio, -}) { - return ( -
-

- Portfolios - -

- - {portfolios.map((portfolio) => ( -
- - - {portfolio.name} - - - - - - - - - -
- ))} -
- ) -} - -PortfolioListComponent.propTypes = { - portfolios: PropTypes.arrayOf(Portfolio), - currentProjectId: PropTypes.string, - currentPortfolioId: PropTypes.string, - onNewPortfolio: PropTypes.func.isRequired, - onChoosePortfolio: PropTypes.func.isRequired, - onDeletePortfolio: PropTypes.func.isRequired, -} - -export default PortfolioListComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ProjectSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ProjectSidebarComponent.js deleted file mode 100644 index 10d22e5b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ProjectSidebarComponent.js +++ /dev/null @@ -1,21 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Sidebar from '../Sidebar' -import TopologyListContainer from '../../../../containers/app/sidebars/project/TopologyListContainer' -import PortfolioListContainer from '../../../../containers/app/sidebars/project/PortfolioListContainer' -import { Container } from 'reactstrap' - -const ProjectSidebarComponent = ({ collapsible }) => ( - - - - - - -) - -ProjectSidebarComponent.propTypes = { - collapsible: PropTypes.bool, -} - -export default ProjectSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js deleted file mode 100644 index e81d2b78..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js +++ /dev/null @@ -1,45 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Scenario } from '../../../../shapes' -import { Button, Col, Row } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus, faTrash } from '@fortawesome/free-solid-svg-icons' - -function ScenarioListComponent({ scenarios, portfolioId, onNewScenario, onDeleteScenario }) { - return ( - <> - {scenarios.map((scenario, idx) => ( - - - {scenario.name} - - - - - - ))} -
- -
- - ) -} - -ScenarioListComponent.propTypes = { - scenarios: PropTypes.arrayOf(Scenario), - portfolioId: PropTypes.string, - onNewScenario: PropTypes.func.isRequired, - onDeleteScenario: PropTypes.func.isRequired, -} - -export default ScenarioListComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/TopologyListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/TopologyListComponent.js deleted file mode 100644 index ac58669b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/TopologyListComponent.js +++ /dev/null @@ -1,56 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Topology } from '../../../../shapes' -import { Button, Col, Row } from 'reactstrap' -import classNames from 'classnames' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus, faPlay, faTrash } from '@fortawesome/free-solid-svg-icons' - -function TopologyListComponent({ topologies, currentTopologyId, onChooseTopology, onNewTopology, onDeleteTopology }) { - return ( -
-

- Topologies - -

- - {topologies.map((topology, idx) => ( - - - {topology.name} - - - - - - - ))} -
- ) -} - -TopologyListComponent.propTypes = { - topologies: PropTypes.arrayOf(Topology), - currentTopologyId: PropTypes.string, - onChooseTopology: PropTypes.func.isRequired, - onNewTopology: PropTypes.func.isRequired, - onDeleteTopology: PropTypes.func.isRequired, -} - -export default TopologyListComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js index b8c88003..ececd07b 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js @@ -1,16 +1,65 @@ import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPencilAlt } from '@fortawesome/free-solid-svg-icons' - -const NameComponent = ({ name, onEdit }) => ( -

- {name} - -

-) +import React, { useRef, useState } from 'react' +import { Button, TextInput } from '@patternfly/react-core' +import { PencilAltIcon, CheckIcon, TimesIcon } from '@patternfly/react-icons' + +function NameComponent({ name, onEdit }) { + const [isEditing, setEditing] = useState(false) + const nameInput = useRef(null) + + const onCancel = () => { + nameInput.current.value = name + setEditing(false) + } + + const onSubmit = (event) => { + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + if (name) { + onEdit(name) + } + + setEditing(false) + } + + return ( +
+
+
+ {name} +
+
+ +
+
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+ ) +} NameComponent.propTypes = { name: PropTypes.string, diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js new file mode 100644 index 00000000..c4a880b1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js @@ -0,0 +1,83 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { InteractionLevel } from '../../../../shapes' +import BuildingSidebarComponent from './building/BuildingSidebarComponent' +import { + Button, + DrawerActions, + DrawerCloseButton, + DrawerHead, + DrawerPanelBody, + DrawerPanelContent, + Flex, + Title, +} from '@patternfly/react-core' +import { AngleLeftIcon } from '@patternfly/react-icons' +import { useDispatch } from 'react-redux' +import { goDownOneInteractionLevel } from '../../../../redux/actions/interaction-level' +import { backButton } from './TopologySidebar.module.scss' +import RoomSidebarContainer from './room/RoomSidebarContainer' +import RackSidebarContainer from './rack/RackSidebarContainer' +import MachineSidebarContainer from './machine/MachineSidebarContainer' + +const name = { + BUILDING: 'Building', + ROOM: 'Room', + RACK: 'Rack', + MACHINE: 'Machine', +} + +const TopologySidebar = ({ interactionLevel, onClose }) => { + let sidebarContent + + switch (interactionLevel.mode) { + case 'BUILDING': + sidebarContent = + break + case 'ROOM': + sidebarContent = + break + case 'RACK': + sidebarContent = + break + case 'MACHINE': + sidebarContent = + break + default: + sidebarContent = 'Missing Content' + } + + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + + return ( + + + + + + {name[interactionLevel.mode]} + + + + + + + {sidebarContent} + + ) +} + +TopologySidebar.propTypes = { + interactionLevel: InteractionLevel, + onClose: PropTypes.func, +} + +export default TopologySidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss new file mode 100644 index 00000000..45dc98da --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss @@ -0,0 +1,37 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.backButton { + &:global(.pf-c-button) { + align-self: center; + --pf-c-button--after--BorderColor: var(--pf-global--BorderColor--light-100); + color: var(--pf-global--Color--400); + + --pf-c-button--PaddingRight: var(--pf-global--spacer--sm); + --pf-c-button--PaddingLeft: var(--pf-global--spacer--sm); + + &:hover, + &:focus { + --pf-c-button--after--BorderColor: var(--pf-global--BorderColor--100); + } + } +} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebarComponent.js deleted file mode 100644 index 450df6cd..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebarComponent.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import BuildingSidebarContainer from '../../../../containers/app/sidebars/topology/building/BuildingSidebarContainer' -import MachineSidebarContainer from '../../../../containers/app/sidebars/topology/machine/MachineSidebarContainer' -import RackSidebarContainer from '../../../../containers/app/sidebars/topology/rack/RackSidebarContainer' -import RoomSidebarContainer from '../../../../containers/app/sidebars/topology/room/RoomSidebarContainer' -import Sidebar from '../Sidebar' -import { InteractionLevel } from '../../../../shapes' - -const TopologySidebarComponent = ({ interactionLevel }) => { - let sidebarContent - - switch (interactionLevel.mode) { - case 'BUILDING': - sidebarContent = - break - case 'ROOM': - sidebarContent = - break - case 'RACK': - sidebarContent = - break - case 'MACHINE': - sidebarContent = - break - default: - sidebarContent = 'Missing Content' - } - - return {sidebarContent} -} - -TopologySidebarComponent.propTypes = { - interactionLevel: InteractionLevel, -} - -export default TopologySidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js index eea62f84..6c2556d3 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js @@ -1,13 +1,8 @@ import React from 'react' -import NewRoomConstructionContainer from '../../../../../containers/app/sidebars/topology/building/NewRoomConstructionContainer' +import NewRoomConstructionContainer from './NewRoomConstructionContainer' const BuildingSidebarComponent = () => { - return ( -
-

Building

- -
- ) + return } export default BuildingSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js index e8c81735..656b2515 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js @@ -1,29 +1,38 @@ import PropTypes from 'prop-types' import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus, faCheck, faTimes } from '@fortawesome/free-solid-svg-icons' -import { Button } from 'reactstrap' +import { Button, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from '@patternfly/react-core' +import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' +import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' const NewRoomConstructionComponent = ({ onStart, onFinish, onCancel, currentRoomInConstruction }) => { if (currentRoomInConstruction === '-1') { return ( -
- +
+ ) } return ( -
- - -
+ + + + + + + + + + + + ) } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js new file mode 100644 index 00000000..0836263c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { + cancelNewRoomConstruction, + finishNewRoomConstruction, + startNewRoomConstruction, +} from '../../../../../redux/actions/topology/building' +import NewRoomConstructionComponent from './NewRoomConstructionComponent' + +const NewRoomConstructionButton = (props) => { + const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) + + const dispatch = useDispatch() + const actions = { + onStart: () => dispatch(startNewRoomConstruction()), + onFinish: () => dispatch(finishNewRoomConstruction()), + onCancel: () => dispatch(cancelNewRoomConstruction()), + } + return ( + + ) +} + +export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/BackToRackComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/BackToRackComponent.js deleted file mode 100644 index 829bf265..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/BackToRackComponent.js +++ /dev/null @@ -1,17 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faAngleLeft } from '@fortawesome/free-solid-svg-icons' - -const BackToRackComponent = ({ onClick }) => ( -
- - Back to rack -
-) - -BackToRackComponent.propTypes = { - onClick: PropTypes.func, -} - -export default BackToRackComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js new file mode 100644 index 00000000..a7bf3719 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import { deleteMachine } from '../../../../../redux/actions/topology/machine' +import { Button } from '@patternfly/react-core' +import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' +import ConfirmationModal from '../../../../modals/ConfirmationModal' + +const DeleteMachine = () => { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteMachine()) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +export default DeleteMachine diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js index 88a99e0f..d3d4a8cf 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js @@ -1,17 +1,38 @@ import PropTypes from 'prop-types' import React from 'react' -import BackToRackContainer from '../../../../../containers/app/sidebars/topology/machine/BackToRackContainer' -import DeleteMachineContainer from '../../../../../containers/app/sidebars/topology/machine/DeleteMachineContainer' -import MachineNameContainer from '../../../../../containers/app/sidebars/topology/machine/MachineNameContainer' -import UnitTabsContainer from '../../../../../containers/app/sidebars/topology/machine/UnitTabsContainer' +import UnitTabsComponent from './UnitTabsComponent' +import DeleteMachine from './DeleteMachine' +import { + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' +import { useSelector } from 'react-redux' const MachineSidebarComponent = ({ machineId }) => { + const machine = useSelector((state) => state.objects.machine[machineId]) return ( -
- - - - +
+ + Details + + Name + + Machine at position {machine.position} + + + + Actions + + + Units + +
+ +
) } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarContainer.js new file mode 100644 index 00000000..94d9f2c3 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarContainer.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import MachineSidebarComponent from './MachineSidebarComponent' + +const MachineSidebarContainer = (props) => { + const machineId = useSelector( + (state) => + state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ + state.interactionLevel.position - 1 + ] + ) + return +} + +export default MachineSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js index 532add37..88591208 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js @@ -1,28 +1,36 @@ import PropTypes from 'prop-types' -import React, { useRef } from 'react' -import { Button, Form, FormGroup, Input } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus } from '@fortawesome/free-solid-svg-icons' +import React, { useState } from 'react' +import { Button, InputGroup, Select, SelectOption, SelectVariant } from '@patternfly/react-core' +import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' function UnitAddComponent({ units, onAdd }) { - const unitSelect = useRef(null) + const [isOpen, setOpen] = useState(false) + const [selected, setSelected] = useState(null) return ( -
- - - {units.map((unit) => ( - - ))} - - - -
+ + + + ) } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js new file mode 100644 index 00000000..8a6680e6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { addUnit } from '../../../../../redux/actions/topology/machine' +import UnitAddComponent from './UnitAddComponent' + +const UnitAddContainer = ({ unitType }) => { + const units = useSelector((state) => Object.values(state.objects[unitType])) + const dispatch = useDispatch() + + const onAdd = (id) => dispatch(addUnit(unitType, id)) + + return +} + +UnitAddContainer.propTypes = { + unitType: PropTypes.string.isRequired, +} + +export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitComponent.js deleted file mode 100644 index 46c639bd..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitComponent.js +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { UncontrolledPopover, PopoverHeader, PopoverBody, Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash, faInfoCircle } from '@fortawesome/free-solid-svg-icons' -import { ProcessingUnit, StorageUnit } from '../../../../../shapes' - -function UnitComponent({ index, unitType, unit, onDelete }) { - let unitInfo - if (unitType === 'cpu' || unitType === 'gpu') { - unitInfo = ( - <> - Clockrate: - {unit.clockRateMhz} -
- Num. Cores: - {unit.numberOfCores} -
- Energy Cons.: - {unit.energyConsumptionW} W -
- - ) - } else if (unitType === 'memory' || unitType === 'storage') { - unitInfo = ( - <> - Speed: - {unit.speedMbPerS} Mb/s -
- Size: - {unit.sizeMb} MB -
- Energy Cons.: - {unit.energyConsumptionW} W -
- - ) - } - - return ( -
  • - {unit.name} - - - - Unit Information - {unitInfo} - - - - -
  • - ) -} - -UnitComponent.propTypes = { - index: PropTypes.number, - unitType: PropTypes.string, - unit: PropTypes.oneOfType([ProcessingUnit, StorageUnit]), - onDelete: PropTypes.func, -} - -export default UnitComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js index 54c1a6cc..9c3c08fd 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js @@ -1,29 +1,107 @@ import PropTypes from 'prop-types' import React from 'react' import { ProcessingUnit, StorageUnit } from '../../../../../shapes' -import UnitComponent from './UnitComponent' +import { + Button, + DataList, + DataListAction, + DataListCell, + DataListItem, + DataListItemCells, + DataListItemRow, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + Popover, + Title, +} from '@patternfly/react-core' +import { CubesIcon, InfoIcon, TrashIcon } from '@patternfly/react-icons' -const UnitListComponent = ({ unitType, units, onDelete }) => ( -
      - {units.length !== 0 ? ( - units.map((unit, index) => ( - onDelete(unit, unitType)} - index={index} - key={index} - /> - )) - ) : ( -
      - - No units... Add some with the menu above! - -
      - )} -
    -) +const UnitInfo = ({ unit, unitType }) => { + if (unitType === 'cpu' || unitType === 'gpu') { + return ( + + + Clock Frequency + {unit.clockRateMhz} MHz + + + Number of Cores + {unit.numberOfCores} + + + Energy Consumption + {unit.energyConsumptionW} W + + + ) + } + + return ( + + + Speed + {unit.speedMbPerS} Mb/s + + + Capacity + {unit.sizeMb} MB + + + Energy Consumption + {unit.energyConsumptionW} W + + + ) +} + +UnitInfo.propTypes = { + unitType: PropTypes.string.isRequired, + unit: PropTypes.oneOfType([ProcessingUnit, StorageUnit]).isRequired, +} + +const UnitListComponent = ({ unitType, units, onDelete }) => { + if (units.length === 0) { + return ( + + + + No units found + + You have not configured any units yet. Add some with the menu above! + + ) + } + + return ( + + {units.map((unit, index) => ( + + + {unit.name}]} /> + + } + > + + + + + + + ))} + + ) +} UnitListComponent.propTypes = { unitType: PropTypes.string.isRequired, diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js new file mode 100644 index 00000000..2d994f97 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import UnitListComponent from './UnitListComponent' +import { deleteUnit } from '../../../../../redux/actions/topology/machine' + +const unitMapping = { + cpu: 'cpus', + gpu: 'gpus', + memory: 'memories', + storage: 'storages', +} + +const UnitListContainer = ({ unitType, ...props }) => { + const dispatch = useDispatch() + const units = useSelector((state) => { + const machine = + state.objects.machine[ + state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ + state.interactionLevel.position - 1 + ] + ] + return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) + }) + const onDelete = (unit, unitType) => dispatch(deleteUnit(unitType, unit._id)) + + return +} + +UnitListContainer.propTypes = { + unitType: PropTypes.string.isRequired, +} + +export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js index ebb5f479..723ed2e2 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js @@ -1,85 +1,30 @@ import React, { useState } from 'react' -import { Nav, NavItem, NavLink, Row, TabContent, TabPane } from 'reactstrap' -import UnitAddContainer from '../../../../../containers/app/sidebars/topology/machine/UnitAddContainer' -import UnitListContainer from '../../../../../containers/app/sidebars/topology/machine/UnitListContainer' +import { Tab, Tabs, TabTitleText } from '@patternfly/react-core' +import UnitAddContainer from './UnitAddContainer' +import UnitListContainer from './UnitListContainer' const UnitTabsComponent = () => { const [activeTab, setActiveTab] = useState('cpu-units') - const toggle = (tab) => { - if (activeTab !== tab) setActiveTab(tab) - } return ( -
    - - - -
    - - -
    -
    - -
    - - -
    -
    - -
    - - -
    -
    - -
    - - -
    -
    -
    -
    + setActiveTab(tab)}> + CPU}> + + + + GPU}> + + + + Memory}> + + + + Storage}> + + + + ) } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js index a330c302..c8543134 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js @@ -1,12 +1,10 @@ import PropTypes from 'prop-types' import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faSave } from '@fortawesome/free-solid-svg-icons' -import { Button } from 'reactstrap' +import { SaveIcon } from '@patternfly/react-icons' +import { Button } from '@patternfly/react-core' const AddPrefabComponent = ({ onClick }) => ( - ) diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js new file mode 100644 index 00000000..d3d9aaf5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch } from 'react-redux' +import { addPrefab } from '../../../../../redux/actions/prefabs' +import AddPrefabComponent from './AddPrefabComponent' + +const AddPrefabContainer = (props) => { + const dispatch = useDispatch() + return dispatch(addPrefab('name'))} /> +} + +export default AddPrefabContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/BackToRoomComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/BackToRoomComponent.js deleted file mode 100644 index e0eb5979..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/BackToRoomComponent.js +++ /dev/null @@ -1,18 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faAngleLeft } from '@fortawesome/free-solid-svg-icons' -import { Button } from 'reactstrap' - -const BackToRoomComponent = ({ onClick }) => ( - -) - -BackToRoomComponent.propTypes = { - onClick: PropTypes.func, -} - -export default BackToRoomComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js new file mode 100644 index 00000000..47959f03 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' +import { deleteRack } from '../../../../../redux/actions/topology/rack' +import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' +import { Button } from '@patternfly/react-core' + +const DeleteRackContainer = () => { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRack()) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/EmptySlotComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/EmptySlotComponent.js deleted file mode 100644 index 63b319e0..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/EmptySlotComponent.js +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus } from '@fortawesome/free-solid-svg-icons' -import { ListGroupItem, Badge, Button } from 'reactstrap' - -const EmptySlotComponent = ({ position, onAdd }) => ( - - - {position} - - - -) - -EmptySlotComponent.propTypes = { - position: PropTypes.number, - onAdd: PropTypes.func, -} - -export default EmptySlotComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js index b71918da..1617b3bf 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js @@ -2,18 +2,16 @@ import PropTypes from 'prop-types' import React from 'react' import Image from 'next/image' import { Machine } from '../../../../../shapes' -import { Badge, ListGroupItem } from 'reactstrap' +import { Flex, Label } from '@patternfly/react-core' const UnitIcon = ({ id, type }) => ( -
    - {'Machine -
    + {'Machine ) UnitIcon.propTypes = { @@ -21,34 +19,27 @@ UnitIcon.propTypes = { type: PropTypes.string, } -const MachineComponent = ({ position, machine, onClick }) => { +const MachineComponent = ({ machine, onClick }) => { const hasNoUnits = machine.cpus.length + machine.gpus.length + machine.memories.length + machine.storages.length === 0 return ( - - - {position} - -
    - {machine.cpus.length > 0 ? : undefined} - {machine.gpus.length > 0 ? : undefined} - {machine.memories.length > 0 ? : undefined} - {machine.storages.length > 0 ? : undefined} - {hasNoUnits ? Machine with no units : undefined} -
    -
    + onClick()}> + {machine.cpus.length > 0 ? : undefined} + {machine.gpus.length > 0 ? : undefined} + {machine.memories.length > 0 ? : undefined} + {machine.storages.length > 0 ? : undefined} + {hasNoUnits ? ( + + ) : undefined} + ) } MachineComponent.propTypes = { - machine: Machine, - position: PropTypes.number, + machine: Machine.isRequired, onClick: PropTypes.func, } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js index e024a417..27834cf4 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js @@ -1,21 +1,66 @@ import PropTypes from 'prop-types' import React from 'react' -import { machineList } from './MachineListComponent.module.scss' import MachineComponent from './MachineComponent' import { Machine } from '../../../../../shapes' -import EmptySlotComponent from './EmptySlotComponent' +import { + Badge, + Button, + DataList, + DataListAction, + DataListCell, + DataListItem, + DataListItemCells, + DataListItemRow, +} from '@patternfly/react-core' +import { AngleRightIcon, PlusIcon } from '@patternfly/react-icons' -const MachineListComponent = ({ machines = [], onSelect, onAdd }) => { +function MachineListComponent({ machines = [], onSelect, onAdd }) { return ( -
      - {machines.map((machine, index) => { - if (machine === null) { - return onAdd(index + 1)} /> - } else { - return onSelect(index + 1)} machine={machine} /> - } - })} -
    + + {machines.map((machine, index) => + machine ? ( + onSelect(index + 1)}> + + + {machines.length - index}U + , + + onSelect(index + 1)} machine={machine} /> + , + ]} + /> + + + + + + ) : ( + + + + {machines.length - index}U + , + + Empty Slot + , + ]} + /> + + + + + + ) + )} + ) } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss deleted file mode 100644 index f075aac9..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.machineList li { - min-height: 64px; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js new file mode 100644 index 00000000..54e6db0a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React, { useMemo } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import MachineListComponent from './MachineListComponent' +import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' +import { addMachine } from '../../../../../redux/actions/topology/rack' + +function MachineListContainer({ tileId, ...props }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) + const machinesNull = useMemo(() => { + const res = Array(rack.capacity).fill(null) + for (const machine of machines) { + res[machine.position - 1] = machine + } + return res + }, [rack, machines]) + const dispatch = useDispatch() + + return ( + dispatch(addMachine(index))} + onSelect={(index) => dispatch(goFromRackToMachine(index))} + /> + ) +} + +MachineListContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js new file mode 100644 index 00000000..11529b55 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import NameComponent from '../NameComponent' +import { editRackName } from '../../../../../redux/actions/topology/rack' + +const RackNameContainer = ({ tileId }) => { + const rackName = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack].name) + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRackName(name)) + } + } + return +} + +RackNameContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js index 74313bf7..dd5117f7 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js @@ -1,25 +1,58 @@ +import PropTypes from 'prop-types' import React from 'react' -import BackToRoomContainer from '../../../../../containers/app/sidebars/topology/rack/BackToRoomContainer' -import DeleteRackContainer from '../../../../../containers/app/sidebars/topology/rack/DeleteRackContainer' -import MachineListContainer from '../../../../../containers/app/sidebars/topology/rack/MachineListContainer' -import RackNameContainer from '../../../../../containers/app/sidebars/topology/rack/RackNameContainer' -import { sidebarContainer, sidebarHeaderContainer, machineListContainer } from './RackSidebarComponent.module.scss' -import AddPrefabContainer from '../../../../../containers/app/sidebars/topology/rack/AddPrefabContainer' +import { machineListContainer, sidebarContainer } from './RackSidebarComponent.module.scss' +import RackNameContainer from './RackNameContainer' +import AddPrefabContainer from './AddPrefabContainer' +import DeleteRackContainer from './DeleteRackContainer' +import MachineListContainer from './MachineListContainer' +import { + Skeleton, + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' +import { useSelector } from 'react-redux' + +function RackSidebarComponent({ tileId }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) -const RackSidebarComponent = () => { return ( -
    -
    - - +
    + + Details + + + Name + + + + + Capacity + + {rack?.capacity ?? } + + + Actions -
    -
    - + + Slots + +
    +
    ) } +RackSidebarComponent.propTypes = { + tileId: PropTypes.string.isRequired, +} + export default RackSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss index 8ce3836a..6f258aec 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss @@ -2,13 +2,11 @@ display: flex; height: 100%; max-height: 100%; -} - -.sidebarHeaderContainer { - flex: 0; + flex-direction: column; } .machineListContainer { flex: 1; overflow-y: scroll; + margin-top: 10px; } diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js new file mode 100644 index 00000000..2b31413d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import RackSidebarComponent from './RackSidebarComponent' + +const RackSidebarContainer = (props) => { + const tileId = useSelector((state) => state.interactionLevel.tileId) + return +} + +export default RackSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/BackToBuildingComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/BackToBuildingComponent.js deleted file mode 100644 index 043cc713..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/BackToBuildingComponent.js +++ /dev/null @@ -1,17 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faAngleLeft } from '@fortawesome/free-solid-svg-icons' - -const BackToBuildingComponent = ({ onClick }) => ( -
    - - Back to building -
    -) - -BackToBuildingComponent.propTypes = { - onClick: PropTypes.func, -} - -export default BackToBuildingComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomComponent.js deleted file mode 100644 index d81bad0f..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomComponent.js +++ /dev/null @@ -1,18 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' -import { Button } from 'reactstrap' - -const DeleteRoomComponent = ({ onClick }) => ( - -) - -DeleteRoomComponent.propTypes = { - onClick: PropTypes.func, -} - -export default DeleteRoomComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js new file mode 100644 index 00000000..284c4d53 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' +import { deleteRoom } from '../../../../../redux/actions/topology/room' +import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' +import { Button } from '@patternfly/react-core' + +const DeleteRoomContainer = () => { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRoom()) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js new file mode 100644 index 00000000..6db2bfb6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { finishRoomEdit, startRoomEdit } from '../../../../../redux/actions/topology/building' +import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' +import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon' +import { Button } from '@patternfly/react-core' + +const EditRoomContainer = () => { + const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) + + const dispatch = useDispatch() + const onEdit = () => dispatch(startRoomEdit()) + const onFinish = () => dispatch(finishRoomEdit()) + + return isEditing ? ( + + ) : ( + + ) +} + +export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js index 0a27910c..8aebe969 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js @@ -1,14 +1,13 @@ import PropTypes from 'prop-types' import React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTimes, faPlus } from '@fortawesome/free-solid-svg-icons' -import { Button } from 'reactstrap' +import { Button } from '@patternfly/react-core' +import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' +import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon' const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, isEditingRoom }) => { if (inRackConstructionMode) { return ( - ) @@ -16,13 +15,12 @@ const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, is return ( ) diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js new file mode 100644 index 00000000..38af447a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { startRackConstruction, stopRackConstruction } from '../../../../../redux/actions/topology/room' +import RackConstructionComponent from './RackConstructionComponent' + +const RackConstructionContainer = (props) => { + const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) + const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + + const dispatch = useDispatch() + const onStart = () => dispatch(startRackConstruction()) + const onStop = () => dispatch(stopRackConstruction()) + return ( + + ) +} + +export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js new file mode 100644 index 00000000..d7b006a6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' +import { editRoomName } from '../../../../../redux/actions/topology/room' + +function RoomName({ roomId }) { + const roomName = useSelector((state) => state.objects.room[roomId].name) + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRoomName(name)) + } + } + return +} + +RoomName.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default RoomName diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js index 1bc6533e..fac58c51 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js @@ -1,20 +1,43 @@ +import PropTypes from 'prop-types' import React from 'react' -import BackToBuildingContainer from '../../../../../containers/app/sidebars/topology/room/BackToBuildingContainer' -import DeleteRoomContainer from '../../../../../containers/app/sidebars/topology/room/DeleteRoomContainer' -import EditRoomContainer from '../../../../../containers/app/sidebars/topology/room/EditRoomContainer' -import RackConstructionContainer from '../../../../../containers/app/sidebars/topology/room/RackConstructionContainer' -import RoomNameContainer from '../../../../../containers/app/sidebars/topology/room/RoomNameContainer' +import RoomName from './RoomName' +import RackConstructionContainer from './RackConstructionContainer' +import EditRoomContainer from './EditRoomContainer' +import DeleteRoomContainer from './DeleteRoomContainer' +import { + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' -const RoomSidebarComponent = () => { +const RoomSidebarComponent = ({ roomId }) => { return ( -
    - - + + Details + + + Name + + + + + + Construction -
    + ) } +RoomSidebarComponent.propTypes = { + roomId: PropTypes.string.isRequired, +} + export default RoomSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js new file mode 100644 index 00000000..2076b00e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import RoomSidebarComponent from './RoomSidebarComponent' + +const RoomSidebarContainer = (props) => { + const roomId = useSelector((state) => state.interactionLevel.roomId) + return +} + +export default RoomSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js index 5a95810a..f6e1c98b 100644 --- a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js +++ b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js @@ -2,11 +2,11 @@ import PropTypes from 'prop-types' import React from 'react' import Modal from './Modal' -function ConfirmationModal({ title, message, show, callback }) { +function ConfirmationModal({ title, message, isOpen, callback }) { return ( callback(true)} onCancel={() => callback(false)} submitButtonType="danger" @@ -20,7 +20,7 @@ function ConfirmationModal({ title, message, show, callback }) { ConfirmationModal.propTypes = { title: PropTypes.string.isRequired, message: PropTypes.string.isRequired, - show: PropTypes.bool.isRequired, + isOpen: PropTypes.bool.isRequired, callback: PropTypes.func.isRequired, } diff --git a/opendc-web/opendc-web-ui/src/components/modals/Modal.js b/opendc-web/opendc-web-ui/src/components/modals/Modal.js index 8ab3924c..d4577062 100644 --- a/opendc-web/opendc-web-ui/src/components/modals/Modal.js +++ b/opendc-web/opendc-web-ui/src/components/modals/Modal.js @@ -1,43 +1,27 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' import PropTypes from 'prop-types' -import { Modal as RModal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap' +import { Button, Modal as PModal, ModalVariant } from '@patternfly/react-core' -function Modal({ children, title, show, onSubmit, onCancel, submitButtonType, submitButtonText }) { - const [modal, setModal] = useState(show) - - useEffect(() => setModal(show), [show]) - - const toggle = () => setModal(!modal) - const cancel = () => { - if (onCancel() !== false) { - toggle() - } - } - const submit = () => { - if (onSubmit() !== false) { - toggle() - } - } +function Modal({ children, title, isOpen, onSubmit, onCancel, submitButtonType, submitButtonText }) { + const actions = [ + , + , + ] return ( - - {title} - {children} - - - - - + + {children} + ) } Modal.propTypes = { title: PropTypes.string.isRequired, - show: PropTypes.bool.isRequired, + isOpen: PropTypes.bool, onSubmit: PropTypes.func.isRequired, onCancel: PropTypes.func.isRequired, submitButtonType: PropTypes.string, @@ -48,7 +32,7 @@ Modal.propTypes = { Modal.defaultProps = { submitButtonType: 'primary', submitButtonText: 'Save', - show: false, + isOpen: false, } export default Modal diff --git a/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js b/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js index 6758fdc0..392a729e 100644 --- a/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js +++ b/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js @@ -1,31 +1,60 @@ import PropTypes from 'prop-types' -import React, { useRef } from 'react' +import React, { useRef, useState } from 'react' import Modal from './Modal' +import { Form, FormGroup, TextInput } from '@patternfly/react-core' -function TextInputModal({ title, label, show, callback, initialValue }) { +function TextInputModal({ title, label, isOpen, callback, initialValue }) { const textInput = useRef(null) - const onSubmit = () => { - callback(textInput.current.value) + const [isSubmitted, setSubmitted] = useState(false) + const [isValid, setValid] = useState(true) + + const resetState = () => { textInput.current.value = '' + setSubmitted(false) + setValid(false) + } + const onSubmit = (event) => { + const value = textInput.current.value + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + if (!value) { + setValid(false) + return false + } + + callback(value) + resetState() + return true } const onCancel = () => { callback(undefined) - textInput.current.value = '' + resetState() } return ( - -
    { - e.preventDefault() - onSubmit() - }} - > -
    - - -
    -
    + +
    + + + +
    ) } @@ -33,7 +62,7 @@ function TextInputModal({ title, label, show, callback, initialValue }) { TextInputModal.propTypes = { title: PropTypes.string.isRequired, label: PropTypes.string.isRequired, - show: PropTypes.bool.isRequired, + isOpen: PropTypes.bool.isRequired, callback: PropTypes.func.isRequired, initialValue: PropTypes.string, } diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js new file mode 100644 index 00000000..afe07597 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js @@ -0,0 +1,139 @@ +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import Modal from '../Modal' +import { + Form, + FormGroup, + FormSection, + NumberInput, + Select, + SelectGroup, + SelectOption, + SelectVariant, + TextInput, +} from '@patternfly/react-core' +import { METRIC_GROUPS, METRIC_NAMES } from '../../../util/available-metrics' + +const NewPortfolioModal = ({ isOpen, onSubmit: onSubmitUpstream, onCancel: onUpstreamCancel }) => { + const nameInput = useRef(null) + const [repeats, setRepeats] = useState(1) + const [isSelectOpen, setSelectOpen] = useState(false) + const [selectedMetrics, setSelectedMetrics] = useState([]) + + const [isSubmitted, setSubmitted] = useState(false) + const [errors, setErrors] = useState({}) + + const clearState = () => { + setSubmitted(false) + setErrors({}) + nameInput.current.value = '' + setRepeats(1) + setSelectOpen(false) + setSelectedMetrics([]) + } + + const onSubmit = (event) => { + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + + if (!name) { + setErrors({ name: true }) + return false + } else { + onSubmitUpstream(name, { enabledMetrics: selectedMetrics, repeatsPerScenario: repeats }) + } + + clearState() + return false + } + const onCancel = () => { + onUpstreamCancel() + clearState() + } + + const onSelect = (event, selection) => { + if (selectedMetrics.includes(selection)) { + setSelectedMetrics((metrics) => metrics.filter((item) => item !== selection)) + } else { + setSelectedMetrics((metrics) => [...metrics, selection]) + } + } + + return ( + +
    + + + + + + + + + + + setRepeats(Number(e.target.value))} + onPlus={() => setRepeats((r) => r + 1)} + onMinus={() => setRepeats((r) => r - 1)} + min={1} + /> + + +
    +
    + ) +} + +NewPortfolioModal.propTypes = { + isOpen: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +} + +export default NewPortfolioModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModalComponent.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModalComponent.js deleted file mode 100644 index 3c6b8724..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModalComponent.js +++ /dev/null @@ -1,78 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef } from 'react' -import { Form, FormGroup, Input, Label } from 'reactstrap' -import Modal from '../Modal' -import { AVAILABLE_METRICS, METRIC_NAMES } from '../../../util/available-metrics' - -const NewPortfolioModalComponent = ({ show, callback }) => { - const form = useRef(null) - const textInput = useRef(null) - const repeatsInput = useRef(null) - const metricCheckboxes = useRef({}) - - const onSubmit = () => { - if (form.current.reportValidity()) { - callback(textInput.current.value, { - enabledMetrics: AVAILABLE_METRICS.filter((metric) => metricCheckboxes.current[metric].checked), - repeatsPerScenario: parseInt(repeatsInput.current.value), - }) - - return true - } else { - return false - } - } - const onCancel = () => callback(undefined) - - return ( - -
    { - e.preventDefault() - this.onSubmit() - }} - innerRef={form} - > - - - - -

    Targets

    -
    Metrics
    - - {AVAILABLE_METRICS.map((metric) => ( - - - - ))} - - - - - -
    -
    - ) -} - -NewPortfolioModalComponent.propTypes = { - show: PropTypes.bool.isRequired, - callback: PropTypes.func.isRequired, -} - -export default NewPortfolioModalComponent diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js new file mode 100644 index 00000000..94d0d424 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js @@ -0,0 +1,159 @@ +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import { Portfolio } from '../../../shapes' +import Modal from '../Modal' +import { + Checkbox, + Form, + FormGroup, + FormSection, + FormSelect, + FormSelectOption, + NumberInput, + TextInput, +} from '@patternfly/react-core' +import { useSchedulers, useTraces } from '../../../data/experiments' +import { useProjectTopologies } from '../../../data/topology' +import { usePortfolio } from '../../../data/project' + +const NewScenarioModal = ({ portfolioId, isOpen, onSubmit: onSubmitUpstream, onCancel: onCancelUpstream }) => { + const { data: portfolio } = usePortfolio(portfolioId) + const { data: topologies = [] } = useProjectTopologies(portfolio?.projectId) + const { data: traces = [] } = useTraces() + const { data: schedulers = [] } = useSchedulers() + + const [isSubmitted, setSubmitted] = useState(false) + const [traceLoad, setTraceLoad] = useState(100) + const [trace, setTrace] = useState(undefined) + const [topology, setTopology] = useState(undefined) + const [scheduler, setScheduler] = useState(undefined) + const [failuresEnabled, setFailuresEnabled] = useState(false) + const [opPhenEnabled, setOpPhenEnabled] = useState(false) + const nameInput = useRef(null) + + const resetState = () => { + setSubmitted(false) + setTraceLoad(100) + setTrace(undefined) + setTopology(undefined) + setScheduler(undefined) + setFailuresEnabled(false) + setOpPhenEnabled(false) + nameInput.current.value = '' + } + + const onSubmit = (event) => { + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + + onSubmitUpstream( + name, + portfolio._id, + { + traceId: trace || traces[0]._id, + loadSamplingFraction: traceLoad / 100, + }, + { + topologyId: topology || topologies[0]._id, + }, + { + failuresEnabled, + performanceInterferenceEnabled: opPhenEnabled, + schedulerName: scheduler || schedulers[0].name, + } + ) + + resetState() + return true + } + const onCancel = () => { + onCancelUpstream() + resetState() + } + + return ( + +
    + + + + + + + {traces.map((trace) => ( + + ))} + + + + setTraceLoad((load) => load - 1)} + onPlus={() => setTraceLoad((load) => load + 1)} + onChange={(e) => setTraceLoad(Number(e.target.value))} + unit="%" + /> + + + + + + {topologies.map((topology) => ( + + ))} + + + + + + {schedulers.map((scheduler) => ( + + ))} + + + + + setFailuresEnabled((e) => !e)} + /> + setOpPhenEnabled((e) => !e)} + /> + +
    +
    + ) +} + +NewScenarioModal.propTypes = { + portfolioId: PropTypes.string, + isOpen: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +} + +export default NewScenarioModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModalComponent.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModalComponent.js deleted file mode 100644 index 782812ac..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModalComponent.js +++ /dev/null @@ -1,144 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef } from 'react' -import { Form, FormGroup, Input, Label } from 'reactstrap' -import { Scheduler, Topology, Trace } from '../../../shapes' -import Modal from '../Modal' - -const NewScenarioModalComponent = ({ - show, - callback, - currentPortfolioId, - currentPortfolioScenarioIds, - traces, - topologies, - schedulers, -}) => { - const form = useRef(null) - const textInput = useRef(null) - const traceSelect = useRef(null) - const traceLoadInput = useRef(null) - const topologySelect = useRef(null) - const failuresCheckbox = useRef(null) - const performanceInterferenceCheckbox = useRef(null) - const schedulerSelect = useRef(null) - - const onSubmit = () => { - if (!form.current.reportValidity()) { - return false - } - callback( - textInput.current.value, - currentPortfolioId, - { - traceId: traceSelect.current.value, - loadSamplingFraction: parseFloat(traceLoadInput.current.value), - }, - { - topologyId: topologySelect.current.value, - }, - { - failuresEnabled: failuresCheckbox.current.checked, - performanceInterferenceEnabled: performanceInterferenceCheckbox.current.checked, - schedulerName: schedulerSelect.current.value, - } - ) - return true - } - const onCancel = () => { - callback(undefined) - } - - return ( - -
    { - e.preventDefault() - onSubmit() - }} - innerRef={form} - > - - - - -

    Trace

    - - - - {traces.map((trace) => ( - - ))} - - - - - - -

    Topology

    -
    - - - {topologies.map((topology) => ( - - ))} - -
    -

    Operational Phenomena

    - - - - - - - - - - {schedulers.map((scheduler) => ( - - ))} - - -
    -
    - ) -} - -NewScenarioModalComponent.propTypes = { - show: PropTypes.bool.isRequired, - currentPortfolioId: PropTypes.string.isRequired, - currentPortfolioScenarioIds: PropTypes.arrayOf(PropTypes.string), - traces: PropTypes.arrayOf(Trace), - topologies: PropTypes.arrayOf(Topology), - schedulers: PropTypes.arrayOf(Scheduler), - callback: PropTypes.func.isRequired, -} - -export default NewScenarioModalComponent diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js new file mode 100644 index 00000000..49952aec --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js @@ -0,0 +1,81 @@ +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import Modal from '../Modal' +import { Form, FormGroup, FormSelect, FormSelectOption, TextInput } from '@patternfly/react-core' +import { useProjectTopologies } from '../../../data/topology' + +const NewTopologyModal = ({ projectId, isOpen, onSubmit: onSubmitUpstream, onCancel: onCancelUpstream }) => { + const nameInput = useRef(null) + const [isSubmitted, setSubmitted] = useState(false) + const [originTopology, setOriginTopology] = useState(-1) + const [errors, setErrors] = useState({}) + + const { data: topologies = [] } = useProjectTopologies(projectId) + + const clearState = () => { + nameInput.current.value = '' + setSubmitted(false) + setOriginTopology(-1) + setErrors({}) + } + + const onSubmit = (event) => { + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + + if (!name) { + setErrors({ name: true }) + return false + } else if (originTopology === -1) { + onSubmitUpstream(name) + } else { + onSubmitUpstream(name, originTopology) + } + + clearState() + return true + } + + const onCancel = () => { + onCancelUpstream() + clearState() + } + + return ( + +
    + + + + + + + {topologies.map((topology) => ( + + ))} + + +
    +
    + ) +} + +NewTopologyModal.propTypes = { + projectId: PropTypes.string, + isOpen: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +} + +export default NewTopologyModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModalComponent.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModalComponent.js deleted file mode 100644 index f06fe797..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModalComponent.js +++ /dev/null @@ -1,71 +0,0 @@ -import PropTypes from 'prop-types' -import { Form, FormGroup, Input, Label } from 'reactstrap' -import React, { useRef } from 'react' -import { Topology } from '../../../shapes' -import Modal from '../Modal' - -const NewTopologyModalComponent = ({ show, onCreateTopology, onDuplicateTopology, onCancel, topologies }) => { - const form = useRef(null) - const textInput = useRef(null) - const originTopology = useRef(null) - - const onCreate = () => { - onCreateTopology(textInput.current.value) - } - - const onDuplicate = () => { - onDuplicateTopology(textInput.current.value, originTopology.current.value) - } - - const onSubmit = () => { - if (!form.current.reportValidity()) { - return false - } else if (originTopology.current.selectedIndex === 0) { - onCreate() - } else { - onDuplicate() - } - - return true - } - - return ( - -
    { - e.preventDefault() - onSubmit() - }} - innerRef={form} - > - - - - - - - - - {topologies.map((topology) => ( - - ))} - - -
    -
    - ) -} - -NewTopologyModalComponent.propTypes = { - show: PropTypes.bool.isRequired, - topologies: PropTypes.arrayOf(Topology), - onCreateTopology: PropTypes.func.isRequired, - onDuplicateTopology: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, -} - -export default NewTopologyModalComponent diff --git a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js deleted file mode 100644 index 8aaaf847..00000000 --- a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Link from 'next/link' -import { NavLink, NavItem as RNavItem } from 'reactstrap' -import Navbar, { NavItem } from './Navbar' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faList } from '@fortawesome/free-solid-svg-icons' -import { Project } from '../../shapes' - -const AppNavbarComponent = ({ project, fullWidth }) => ( - - - - - - My Projects - - - - {project ? ( - - - - {project.name} - - - - ) : undefined} - -) - -AppNavbarComponent.propTypes = { - project: Project, - fullWidth: PropTypes.bool, -} - -export default AppNavbarComponent diff --git a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js deleted file mode 100644 index 4ab577e0..00000000 --- a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js +++ /dev/null @@ -1,17 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { NavLink } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons' - -const LogoutButton = ({ onLogout }) => ( - - - -) - -LogoutButton.propTypes = { - onLogout: PropTypes.func.isRequired, -} - -export default LogoutButton diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js deleted file mode 100644 index dc74bb8f..00000000 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js +++ /dev/null @@ -1,120 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import Link from 'next/link' -import { useRouter } from 'next/router' -import Image from 'next/image' -import { - Navbar as RNavbar, - NavItem as RNavItem, - NavLink, - NavbarBrand, - NavbarToggler, - Collapse, - Nav, - Container, -} from 'reactstrap' -import Login from '../../containers/auth/Login' -import Logout from '../../containers/auth/Logout' -import ProfileName from '../../containers/auth/ProfileName' -import { login, navbar, opendcBrand } from './Navbar.module.scss' -import { useAuth } from '../../auth' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faGithub } from '@fortawesome/free-brands-svg-icons' - -export const NAVBAR_HEIGHT = 60 - -const GitHubLink = () => ( - - - -) - -export const NavItem = ({ route, children }) => { - const router = useRouter() - const handleClick = (e) => { - e.preventDefault() - router.push(route) - } - return ( - - {children} - - ) -} - -NavItem.propTypes = { - route: PropTypes.string.isRequired, - children: PropTypes.node, -} - -export const LoggedInSection = () => { - const router = useRouter() - const { isAuthenticated } = useAuth() - return ( - - ) -} - -const Navbar = ({ fullWidth, children }) => { - const [isOpen, setIsOpen] = useState(false) - const toggle = () => setIsOpen(!isOpen) - - return ( - - - - -
    - OpenDC -
    -
    - - - - - -
    -
    - ) -} - -Navbar.propTypes = { - fullWidth: PropTypes.bool, - children: PropTypes.node, -} - -export default Navbar diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss deleted file mode 100644 index 8b9e4c97..00000000 --- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.module.scss +++ /dev/null @@ -1,36 +0,0 @@ -@import 'src/style/_mixins.scss'; -@import 'src/style/_variables.scss'; - -.navbar { - border-top: $blue 3px solid; - border-bottom: $gray-semi-dark 1px solid; - color: $gray-very-dark; - background: #fafafb; -} - -.opendcBrand { - display: inline-block; - color: $gray-very-dark; - - transition: background $transition-length; - - img { - position: relative; - bottom: 3px; - display: inline-block; - width: 30px; - } -} - -.login { - height: 40px; - background: $blue; - border: none; - padding-top: 10px; - - @include clickable; - - &:hover { - background: $blue-dark; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js deleted file mode 100644 index 03a4894b..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.js +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react' -import { blinkingCursor } from './BlinkingCursor.module.scss' - -const BlinkingCursor = () => _ - -export default BlinkingCursor diff --git a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss b/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss deleted file mode 100644 index aba0c604..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/BlinkingCursor.module.scss +++ /dev/null @@ -1,13 +0,0 @@ -.blinkingCursor { - animation: blink 1s step-end infinite; -} - -@keyframes blink { - from, - to { - color: #eeeeee; - } - 50% { - color: #333333; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js deleted file mode 100644 index 6ded4350..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' -import { codeBlock } from './CodeBlock.module.scss' - -const CodeBlock = () => { - const textBlock = - ' oo oooo oo
    ' + - ' oo oo oo oo
    ' + - ' oo oo oo oo
    ' + - ' oooooo oo oo oooooo
    ' + - ' oo oo oo oo
    ' + - ' oo oooo oo
    ' - const charList = textBlock.split('') - - // Binary representation of the string "OpenDC!" ;) - const binaryString = '01001111011100000110010101101110010001000100001100100001' - - let binaryIndex = 0 - for (let i = 0; i < charList.length; i++) { - if (charList[i] === 'o') { - charList[i] = binaryString[binaryIndex] - binaryIndex++ - } - } - - return
    -} - -export default CodeBlock diff --git a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss b/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss deleted file mode 100644 index 8af3ee6d..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/CodeBlock.module.scss +++ /dev/null @@ -1,4 +0,0 @@ -.codeBlock { - white-space: pre-wrap; - margin-top: 60px; -} diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js deleted file mode 100644 index e6200b10..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react' -import Link from 'next/link' -import BlinkingCursor from './BlinkingCursor' -import CodeBlock from './CodeBlock' -import { terminalWindow, terminalHeader, terminalBody, segfault, subTitle, homeBtn } from './TerminalWindow.module.scss' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faHome } from '@fortawesome/free-solid-svg-icons' - -const TerminalWindow = () => ( -
    -
    Terminal -- bash
    -
    -
    - $ status -
    - opendc[4264]: segfault at 0000051497be459d1 err 12 in libopendc.9.0.4 -
    - opendc[4269]: segfault at 000004234855fc2db err 3 in libopendc.9.0.4 -
    - opendc[4270]: STDERR Page does not exist -
    -
    - -
    - Got lost? - -
    - - - GET ME BACK TO OPENDC - - -
    -
    -) - -export default TerminalWindow diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss deleted file mode 100644 index 614852d3..00000000 --- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.module.scss +++ /dev/null @@ -1,61 +0,0 @@ -.terminalWindow { - display: block; - align-self: center; - - margin: auto; - - user-select: none; - cursor: default; - - overflow: hidden; - - box-shadow: 5px 5px 20px #444444; -} - -.terminalHeader { - font-family: monospace; - background: #cccccc; - color: #444444; - height: 30px; - line-height: 30px; - padding-left: 10px; - - border-top-left-radius: 7px; - border-top-right-radius: 7px; -} - -.terminalBody { - font-family: monospace; - text-align: center; - background-color: #333333; - color: #eeeeee; - padding: 10px; - - height: 100%; -} - -.segfault { - text-align: left; -} - -.subTitle { - margin-top: 20px; -} - -.homeBtn { - margin-top: 10px; - padding: 5px; - display: inline-block; - border: 1px solid #eeeeee; - color: #eeeeee; - text-decoration: none; - cursor: pointer; - - transition: all 200ms; - - &:hover, - &:active { - background: #eeeeee; - color: #333333; - } -} diff --git a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js index 5129c013..285217e9 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js +++ b/opendc-web/opendc-web-ui/src/components/projects/FilterPanel.js @@ -1,23 +1,21 @@ import React from 'react' import PropTypes from 'prop-types' -import { Button, ButtonGroup } from 'reactstrap' +import { ToggleGroup, ToggleGroupItem } from '@patternfly/react-core' import { filterPanel } from './FilterPanel.module.scss' export const FILTERS = { SHOW_ALL: 'All Projects', SHOW_OWN: 'My Projects', SHOW_SHARED: 'Shared with me' } const FilterPanel = ({ onSelect, activeFilter = 'SHOW_ALL' }) => ( - + {Object.keys(FILTERS).map((filter) => ( - + onChange={() => activeFilter === filter || onSelect(filter)} + isSelected={activeFilter === filter} + text={FILTERS[filter]} + /> ))} - + ) FilterPanel.propTypes = { diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js b/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js new file mode 100644 index 00000000..ae4cb9cd --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { PlusIcon } from '@patternfly/react-icons' +import { Button } from '@patternfly/react-core' +import { useState } from 'react' +import NewPortfolioModal from '../modals/custom-components/NewPortfolioModal' +import { useMutation } from 'react-query' + +function NewPortfolio({ projectId }) { + const [isVisible, setVisible] = useState(false) + const { mutate: addPortfolio } = useMutation('addPortfolio') + + const onSubmit = (name, targets) => { + addPortfolio({ projectId, name, targets }) + setVisible(false) + } + + return ( + <> + + setVisible(false)} /> + + ) +} + +NewPortfolio.propTypes = { + projectId: PropTypes.string, +} + +export default NewPortfolio diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewProject.js b/opendc-web/opendc-web-ui/src/components/projects/NewProject.js new file mode 100644 index 00000000..4f5d79cf --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewProject.js @@ -0,0 +1,39 @@ +import React, { useState } from 'react' +import TextInputModal from '../../components/modals/TextInputModal' +import { Button } from '@patternfly/react-core' +import { useMutation } from 'react-query' +import { PlusIcon } from '@patternfly/react-icons' +import { buttonContainer } from './NewProject.module.scss' + +/** + * A container for creating a new project. + */ +const NewProject = () => { + const [isVisible, setVisible] = useState(false) + const { mutate: addProject } = useMutation('addProject') + + const onSubmit = (name) => { + if (name) { + addProject({ name }) + } + setVisible(false) + } + + return ( + <> +
    + +
    + + + ) +} + +export default NewProject diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewProject.module.scss b/opendc-web/opendc-web-ui/src/components/projects/NewProject.module.scss new file mode 100644 index 00000000..5a0e74fc --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewProject.module.scss @@ -0,0 +1,26 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.buttonContainer { + flex: 0 1 auto; + padding: 20px 0; +} diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewScenario.js b/opendc-web/opendc-web-ui/src/components/projects/NewScenario.js new file mode 100644 index 00000000..6d4f48c1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewScenario.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { PlusIcon } from '@patternfly/react-icons' +import { Button } from '@patternfly/react-core' +import { useState } from 'react' +import NewScenarioModal from '../modals/custom-components/NewScenarioModal' +import { useMutation } from 'react-query' + +function NewScenario({ portfolioId }) { + const [isVisible, setVisible] = useState(false) + const { mutate: addScenario } = useMutation('addScenario') + + const onSubmit = (name, portfolioId, trace, topology, operational) => { + addScenario({ + portfolioId, + name, + trace, + topology, + operational, + }) + setVisible(false) + } + + return ( + <> + + setVisible(false)} + /> + + ) +} + +NewScenario.propTypes = { + portfolioId: PropTypes.string, +} + +export default NewScenario diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js b/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js new file mode 100644 index 00000000..c6c4171b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { PlusIcon } from '@patternfly/react-icons' +import { Button } from '@patternfly/react-core' +import { useState } from 'react' +import NewTopologyModal from '../modals/custom-components/NewTopologyModal' +import { useDispatch } from 'react-redux' +import { addTopology } from '../../redux/actions/topologies' + +function NewTopology({ projectId }) { + const [isVisible, setVisible] = useState(false) + const dispatch = useDispatch() + + const onSubmit = (name, duplicateId) => { + dispatch(addTopology(projectId, name, duplicateId)) + setVisible(false) + } + return ( + <> + + setVisible(false)} + /> + + ) +} + +NewTopology.propTypes = { + projectId: PropTypes.string, +} + +export default NewTopology diff --git a/opendc-web/opendc-web-ui/src/components/projects/PortfolioTable.js b/opendc-web/opendc-web-ui/src/components/projects/PortfolioTable.js new file mode 100644 index 00000000..45e399ed --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/PortfolioTable.js @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import Link from 'next/link' +import { Table, TableBody, TableHeader } from '@patternfly/react-table' +import React from 'react' +import TableEmptyState from '../util/TableEmptyState' +import { useProjectPortfolios } from '../../data/project' +import { useMutation } from 'react-query' + +const PortfolioTable = ({ projectId }) => { + const { status, data: portfolios = [] } = useProjectPortfolios(projectId) + const { mutate: deletePortfolio } = useMutation('deletePortfolio') + + const columns = ['Name', 'Scenarios', 'Metrics', 'Repeats'] + const rows = + portfolios.length > 0 + ? portfolios.map((portfolio) => [ + { + title: ( + + {portfolio.name} + + ), + }, + + portfolio.scenarioIds.length === 1 ? '1 scenario' : `${portfolio.scenarioIds.length} scenarios`, + + portfolio.targets.enabledMetrics.length === 1 + ? '1 metric' + : `${portfolio.targets.enabledMetrics.length} metrics`, + portfolio.targets.repeatsPerScenario === 1 + ? '1 repeat' + : `${portfolio.targets.repeatsPerScenario} repeats`, + ]) + : [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 4 }, + title: ( + + ), + }, + ], + }, + ] + + const actions = + portfolios.length > 0 + ? [ + { + title: 'Delete Portfolio', + onClick: (_, rowId) => deletePortfolio(portfolios[rowId]._id), + }, + ] + : [] + + return ( + + + +
    + ) +} + +PortfolioTable.propTypes = { + projectId: PropTypes.string, +} + +export default PortfolioTable diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js deleted file mode 100644 index 4adf3205..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js +++ /dev/null @@ -1,38 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Link from 'next/link' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlay, faUsers, faTrash } from '@fortawesome/free-solid-svg-icons' - -const ProjectActionButtons = ({ projectId, onViewUsers, onDelete }) => ( - - - - - - - -) - -ProjectActionButtons.propTypes = { - projectId: PropTypes.string.isRequired, - onViewUsers: PropTypes.func, - onDelete: PropTypes.func, -} - -export default ProjectActionButtons diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js deleted file mode 100644 index 46ef4691..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectList.js +++ /dev/null @@ -1,41 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Project } from '../../shapes' -import ProjectRow from './ProjectRow' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons' - -const ProjectList = ({ projects }) => { - return ( -
    - {projects.length === 0 ? ( -
    - - No projects here yet... Add some with the ‘New Project’ button! -
    - ) : ( - - - - - - - - - - {projects.map((project) => ( - - ))} - -
    Project nameLast editedAccess rights -
    - )} -
    - ) -} - -ProjectList.propTypes = { - projects: PropTypes.arrayOf(Project).isRequired, -} - -export default ProjectList diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js deleted file mode 100644 index 91368de8..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/ProjectRow.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import ProjectActions from '../../containers/projects/ProjectActions' -import { Project } from '../../shapes' -import { AUTH_DESCRIPTION_MAP, AUTH_ICON_MAP } from '../../util/authorizations' -import { parseAndFormatDateTime } from '../../util/date-time' -import { useAuth } from '../../auth' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' - -const ProjectRow = ({ project }) => { - const { user } = useAuth() - const { level } = project.authorizations.find((auth) => auth.userId === user.sub) - return ( - - {project.name} - {parseAndFormatDateTime(project.datetimeLastEdited)} - - - {AUTH_DESCRIPTION_MAP[level]} - - - - ) -} - -ProjectRow.propTypes = { - project: Project.isRequired, -} - -export default ProjectRow diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectTable.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectTable.js new file mode 100644 index 00000000..a7290259 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectTable.js @@ -0,0 +1,76 @@ +import PropTypes from 'prop-types' +import React from 'react' +import Link from 'next/link' +import { Project, Status } from '../../shapes' +import { Table, TableBody, TableHeader } from '@patternfly/react-table' +import { parseAndFormatDateTime } from '../../util/date-time' +import { AUTH_DESCRIPTION_MAP, AUTH_ICON_MAP } from '../../util/authorizations' +import { useAuth } from '../../auth' +import TableEmptyState from '../util/TableEmptyState' + +const ProjectTable = ({ status, projects, onDelete, isFiltering }) => { + const { user } = useAuth() + const columns = ['Project name', 'Last edited', 'Access Rights'] + const rows = + projects.length > 0 + ? projects.map((project) => { + const { level } = project.authorizations.find((auth) => auth.userId === user.sub) + const Icon = AUTH_ICON_MAP[level] + return [ + { + title: {project.name}, + }, + parseAndFormatDateTime(project.datetimeLastEdited), + { + title: ( + <> + {AUTH_DESCRIPTION_MAP[level]} + + ), + }, + ] + }) + : [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 3 }, + title: ( + + ), + }, + ], + }, + ] + + const actions = + projects.length > 0 + ? [ + { + title: 'Delete Project', + onClick: (_, rowId) => onDelete(projects[rowId]), + }, + ] + : [] + + return ( + + + +
    + ) +} + +ProjectTable.propTypes = { + status: Status.isRequired, + isFiltering: PropTypes.bool, + projects: PropTypes.arrayOf(Project).isRequired, + onDelete: PropTypes.func, +} + +export default ProjectTable diff --git a/opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js b/opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js new file mode 100644 index 00000000..285345e7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { ClockIcon, InfoIcon, CheckCircleIcon, ErrorCircleOIcon } from '@patternfly/react-icons' + +function ScenarioState({ state }) { + switch (state) { + case 'CLAIMED': + case 'QUEUED': + return ( + + Queued + + ) + case 'RUNNING': + return ( + + Running + + ) + case 'FINISHED': + return ( + + Finished + + ) + case 'FAILED': + return ( + + Failed + + ) + } + + return 'Unknown' +} + +ScenarioState.propTypes = { + state: PropTypes.oneOf(['QUEUED', 'CLAIMED', 'RUNNING', 'FINISHED', 'FAILED']), +} + +export default ScenarioState diff --git a/opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js b/opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js new file mode 100644 index 00000000..9966e3ba --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import Link from 'next/link' +import { Table, TableBody, TableHeader } from '@patternfly/react-table' +import React from 'react' +import TableEmptyState from '../util/TableEmptyState' +import ScenarioState from './ScenarioState' +import { usePortfolio, usePortfolioScenarios } from '../../data/project' +import { useProjectTopologies } from '../../data/topology' +import { useMutation } from 'react-query' + +const ScenarioTable = ({ portfolioId }) => { + const { data: portfolio } = usePortfolio(portfolioId) + const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) + const { data: topologies } = useProjectTopologies(portfolio?.projectId, { + select: (topologies) => new Map(topologies.map((topology) => [topology._id, topology])), + }) + + const { mutate: deleteScenario } = useMutation('deleteScenario') + + const columns = ['Name', 'Topology', 'Trace', 'State'] + const rows = + scenarios.length > 0 + ? scenarios.map((scenario) => { + const topology = topologies?.get(scenario.topology.topologyId) + + return [ + scenario.name, + { + title: topology ? ( + + {topology.name} + + ) : ( + 'Unknown Topology' + ), + }, + scenario.trace.traceId, + { title: }, + ] + }) + : [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 4 }, + title: ( + + ), + }, + ], + }, + ] + + const actionResolver = (_, { rowIndex }) => [ + { + title: 'Delete Scenario', + onClick: (_, rowId) => deleteScenario(scenarios[rowId]._id), + isDisabled: rowIndex === 0, + }, + ] + + return ( + 0 ? actionResolver : undefined} + > + + +
    + ) +} + +ScenarioTable.propTypes = { + portfolioId: PropTypes.string, +} + +export default ScenarioTable diff --git a/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js b/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js new file mode 100644 index 00000000..80099ece --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import Link from 'next/link' +import { Table, TableBody, TableHeader } from '@patternfly/react-table' +import React from 'react' +import TableEmptyState from '../util/TableEmptyState' +import { parseAndFormatDateTime } from '../../util/date-time' +import { useMutation } from 'react-query' +import { useProjectTopologies } from '../../data/topology' + +const TopologyTable = ({ projectId }) => { + const { status, data: topologies = [] } = useProjectTopologies(projectId) + const { mutate: deleteTopology } = useMutation('deleteTopology') + + const columns = ['Name', 'Rooms', 'Last Edited'] + const rows = + topologies.length > 0 + ? topologies.map((topology) => [ + { + title: ( + + {topology.name} + + ), + }, + topology.rooms.length === 1 ? '1 room' : `${topology.rooms.length} rooms`, + parseAndFormatDateTime(topology.datetimeLastEdited), + ]) + : [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 3 }, + title: ( + + ), + }, + ], + }, + ] + + const actionResolver = (_, { rowIndex }) => [ + { + title: 'Delete Topology', + onClick: (_, rowId) => deleteTopology(topologies[rowId]._id), + isDisabled: rowIndex === 0, + }, + ] + + return ( + 0 ? actionResolver : () => []} + > + + +
    + ) +} + +TopologyTable.propTypes = { + projectId: PropTypes.string, +} + +export default TopologyTable diff --git a/opendc-web/opendc-web-ui/src/components/util/BreadcrumbLink.js b/opendc-web/opendc-web-ui/src/components/util/BreadcrumbLink.js new file mode 100644 index 00000000..c6ab214a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/util/BreadcrumbLink.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import Link from 'next/link' + +const BreadcrumbLink = ({ children, href, ...props }) => ( + + {children} + +) + +BreadcrumbLink.propTypes = { + children: PropTypes.node, + href: PropTypes.string.isRequired, +} + +export default BreadcrumbLink diff --git a/opendc-web/opendc-web-ui/src/components/util/NavItemLink.js b/opendc-web/opendc-web-ui/src/components/util/NavItemLink.js new file mode 100644 index 00000000..c0d109bd --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/util/NavItemLink.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import Link from 'next/link' +import PropTypes from 'prop-types' + +const NavItemLink = ({ children, href, ...props }) => ( + + {children} + +) + +NavItemLink.propTypes = { + children: PropTypes.node, + href: PropTypes.string.isRequired, +} + +export default NavItemLink diff --git a/opendc-web/opendc-web-ui/src/components/util/TableEmptyState.js b/opendc-web/opendc-web-ui/src/components/util/TableEmptyState.js new file mode 100644 index 00000000..9d16ffbb --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/util/TableEmptyState.js @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { Bullseye, EmptyState, EmptyStateBody, EmptyStateIcon, Spinner, Title } from '@patternfly/react-core' +import { SearchIcon, CubesIcon } from '@patternfly/react-icons' +import { Status } from '../../shapes' + +function TableEmptyState({ + status, + isFiltering, + loadingTitle = 'Loading', + emptyTitle = 'No results found', + emptyText = 'No results found of this type.', + emptyAction = '', +}) { + if (status === 'loading') { + return ( + + + + + {loadingTitle} + + + + ) + } else if (status === 'error') { + return ( + + + Unable to connect + + + There was an error retrieving data. Check your connection and try again. + + + ) + } else if (status === 'idle') { + return ( + + + + {emptyTitle} + + No results available at this moment. + + ) + } else if (isFiltering) { + return ( + + + + No results found + + + No results match this filter criteria. Remove all filters or clear all filters to show results. + + + ) + } + + return ( + + + + {emptyTitle} + + {emptyText} + {emptyAction} + + ) +} + +TableEmptyState.propTypes = { + status: Status.isRequired, + isFiltering: PropTypes.bool, + loadingTitle: PropTypes.string, + emptyTitle: PropTypes.string, + emptyText: PropTypes.string, + emptyAction: PropTypes.node, +} + +export default TableEmptyState diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js deleted file mode 100644 index bac24c8b..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' -import GrayLayer from '../../../components/app/map/elements/GrayLayer' - -const GrayContainer = () => { - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - return -} - -export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js deleted file mode 100644 index 91ceb35d..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../redux/actions/map' -import MapStageComponent from '../../../components/app/map/MapStageComponent' -import { useMapDimensions, useMapPosition } from '../../../data/map' - -const MapStage = () => { - const position = useMapPosition() - const dimensions = useMapDimensions() - const dispatch = useDispatch() - const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) - const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) - const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height)) - - return ( - - ) -} - -export default MapStage diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js deleted file mode 100644 index e5af5117..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackGroup from '../../../components/app/map/groups/RackGroup' - -const RackContainer = ({ tile }) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - return -} - -export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js deleted file mode 100644 index d22317a5..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackFillBar from '../../../components/app/map/elements/RackFillBar' - -const RackSpaceFillContainer = (props) => { - const state = useSelector((state) => { - let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[props.tileId].rack] - const machineIds = rack.machines - machineIds.forEach((machineId) => { - if (machineId !== null) { - const machine = state.objects.machine[machineId] - machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) - machine.memories.forEach( - (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) - ) - machine.storages.forEach( - (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) - ) - } - }) - - return { - type: 'energy', - fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), - } - }) - return -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js deleted file mode 100644 index 8d6f61e0..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackFillBar from '../../../components/app/map/elements/RackFillBar' - -const RackSpaceFillContainer = (props) => { - const state = useSelector((state) => { - const machineIds = state.objects.rack[state.objects.tile[props.tileId].rack].machines - return { - type: 'space', - fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, - } - }) - return -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js deleted file mode 100644 index 0a9e1503..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js +++ /dev/null @@ -1,23 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' -import RoomGroup from '../../../components/app/map/groups/RoomGroup' - -const RoomContainer = (props) => { - const state = useSelector((state) => { - return { - interactionLevel: state.interactionLevel, - currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.objects.room[props.roomId], - } - }) - const dispatch = useDispatch() - return dispatch(goFromBuildingToRoom(props.roomId))} /> -} - -RoomContainer.propTypes = { - roomId: PropTypes.string, -} - -export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js deleted file mode 100644 index 50a2abfd..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { goFromRoomToRack } from '../../../redux/actions/interaction-level' -import TileGroup from '../../../components/app/map/groups/TileGroup' - -const TileContainer = (props) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - const tile = useSelector((state) => state.objects.tile[props.tileId]) - - const dispatch = useDispatch() - const onClick = (tile) => { - if (tile.rack) { - dispatch(goFromRoomToRack(tile._id)) - } - } - return -} - -export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js deleted file mode 100644 index e7ab3c72..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -import { useActiveTopology } from '../../../data/topology' - -const TopologyContainer = () => { - const topology = useActiveTopology() - const interactionLevel = useSelector((state) => state.interactionLevel) - - return -} - -export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js deleted file mode 100644 index 67f36396..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import WallGroup from '../../../components/app/map/groups/WallGroup' - -const WallContainer = (props) => { - const tiles = useSelector((state) => - state.objects.room[props.roomId].tiles.map((tileId) => state.objects.tile[tileId]) - ) - return -} - -export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js deleted file mode 100644 index a10eea22..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' -import { useMapScale } from '../../../../data/map' - -const ScaleIndicatorContainer = (props) => { - const scale = useMapScale() - return -} - -export default ScaleIndicatorContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js deleted file mode 100644 index a39c6077..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { zoomInOnCenter } from '../../../../redux/actions/map' -import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent' -import { useMapScale } from '../../../../data/map' - -const ZoomControlContainer = () => { - const dispatch = useDispatch() - const scale = useMapScale() - return dispatch(zoomInOnCenter(zoomIn))} /> -} - -export default ZoomControlContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js deleted file mode 100644 index 633ebcc7..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' -import { useMapPosition, useMapScale } from '../../../../data/map' - -const MapLayer = (props) => { - const position = useMapPosition() - const scale = useMapScale() - return -} - -export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js deleted file mode 100644 index e9a64545..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addRackToTile } from '../../../../redux/actions/topology/room' -import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' -import { findTileWithPosition } from '../../../../util/tile-calculations' - -const ObjectHoverLayer = (props) => { - const state = useSelector((state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.inRackConstructionMode, - isValid: (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } - - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) - const tile = findTileWithPosition(tiles, x, y) - - return !(tile === null || tile.rack) - }, - } - }) - - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(addRackToTile(x, y)) - return -} - -export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js deleted file mode 100644 index 4070c766..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' -import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' -import { - deriveValidNextTilePositions, - findPositionInPositions, - findPositionInRooms, -} from '../../../../util/tile-calculations' - -const RoomHoverLayer = (props) => { - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) - - const state = useSelector((state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.currentRoomInConstruction !== '-1', - isValid: (x, y) => { - const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) - const oldRooms = Object.keys(state.objects.room) - .map((id) => Object.assign({}, state.objects.room[id])) - .filter( - (room) => - state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && - room._id !== state.construction.currentRoomInConstruction - ) - - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) - }) - if (newRoom.tiles.length === 0) { - return findPositionInRooms(oldRooms, x, y) === -1 - } - - const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) - return findPositionInPositions(validNextPositions, x, y) !== -1 - }, - } - }) - return -} - -export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js deleted file mode 100644 index a75f15ae..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' -import { useRouter } from 'next/router' -import { usePortfolio, usePortfolioScenarios } from '../../../data/project' - -const PortfolioResultsContainer = (props) => { - const router = useRouter() - const { portfolio: currentPortfolioId } = router.query - const { data: portfolio } = usePortfolio(currentPortfolioId) - const scenarios = usePortfolioScenarios(currentPortfolioId).data ?? [] - return -} - -export default PortfolioResultsContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js deleted file mode 100644 index 60ac666c..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useState } from 'react' -import { useRouter } from 'next/router' -import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' -import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { useProjectPortfolios } from '../../../../data/project' -import { useMutation } from 'react-query' - -const PortfolioListContainer = () => { - const router = useRouter() - const { project: currentProjectId, portfolio: currentPortfolioId } = router.query - const portfolios = useProjectPortfolios(currentProjectId).data ?? [] - - const { mutate: addPortfolio } = useMutation('addPortfolio') - const { mutateAsync: deletePortfolio } = useMutation('deletePortfolio') - - const [isVisible, setVisible] = useState(false) - const actions = { - onNewPortfolio: () => setVisible(true), - onChoosePortfolio: async (portfolioId) => { - await router.push(`/projects/${currentProjectId}/portfolios/${portfolioId}`) - }, - onDeletePortfolio: async (id) => { - if (id) { - await deletePortfolio(id) - await router.push(`/projects/${currentProjectId}`) - } - }, - } - const callback = (name, targets) => { - if (name) { - addPortfolio({ projectId: currentProjectId, name, targets }) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default PortfolioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js deleted file mode 100644 index 06c7f0f7..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useRouter } from 'next/router' -import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' -import { isCollapsible } from '../../../../util/sidebar-space' - -const ProjectSidebarContainer = (props) => { - const router = useRouter() - return -} - -export default ProjectSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js deleted file mode 100644 index 3b68df38..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' -import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' -import { useProjectTopologies } from '../../../../data/topology' -import { usePortfolio, usePortfolioScenarios } from '../../../../data/project' -import { useSchedulers, useTraces } from '../../../../data/experiments' -import { useMutation } from 'react-query' - -const ScenarioListContainer = ({ portfolioId }) => { - const { data: portfolio } = usePortfolio(portfolioId) - const scenarios = usePortfolioScenarios(portfolioId).data ?? [] - const topologies = - useProjectTopologies(portfolio?.projectId).data?.map((topology) => ({ - _id: topology._id, - name: topology.name, - })) ?? [] - const traces = useTraces().data ?? [] - const schedulers = useSchedulers().data ?? [] - - const { mutate: addScenario } = useMutation('addScenario') - const { mutate: deleteScenario } = useMutation('deleteScenario') - - const [isVisible, setVisible] = useState(false) - - const onNewScenario = () => setVisible(true) - const onDeleteScenario = (id) => id && deleteScenario(id) - const callback = (name, portfolioId, trace, topology, operational) => { - if (name) { - addScenario({ - portfolioId, - name, - trace, - topology, - operational, - }) - } - - setVisible(false) - } - - return ( - <> - - s._id)} - traces={traces} - schedulers={schedulers} - topologies={topologies} - callback={callback} - /> - - ) -} - -ScenarioListContainer.propTypes = { - portfolioId: PropTypes.string, -} - -export default ScenarioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js deleted file mode 100644 index a2244a30..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ /dev/null @@ -1,67 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' -import { setCurrentTopology } from '../../../../redux/actions/topology/building' -import { useRouter } from 'next/router' -import { addTopology } from '../../../../redux/actions/topologies' -import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' -import { useActiveTopology, useProjectTopologies } from '../../../../data/topology' -import { useMutation } from 'react-query' - -const TopologyListContainer = () => { - const dispatch = useDispatch() - const router = useRouter() - const { project: currentProjectId } = router.query - const topologies = - useProjectTopologies(currentProjectId).data?.map((topology) => ({ _id: topology._id, name: topology.name })) ?? - [] - const currentTopologyId = useActiveTopology()?._id - const [isVisible, setVisible] = useState(false) - - const { mutate: deleteTopology } = useMutation('deleteTopology') - - const onChooseTopology = async (id) => { - dispatch(setCurrentTopology(id)) - await router.push(`/projects/${currentProjectId}/topologies/${id}`) - } - const onDeleteTopology = async (id) => { - if (id) { - deleteTopology(id) - await router.push(`/projects/${currentProjectId}`) - } - } - const onCreateTopology = (name) => { - if (name) { - dispatch(addTopology(currentProjectId, name, undefined)) - } - setVisible(false) - } - const onDuplicateTopology = (name, id) => { - if (name) { - dispatch(addTopology(currentProjectId, name, id)) - } - setVisible(false) - } - const onCancel = () => setVisible(false) - - return ( - <> - setVisible(true)} - onDeleteTopology={onDeleteTopology} - /> - - - ) -} - -export default TopologyListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js deleted file mode 100644 index 42c81c65..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import TopologySidebarComponent from '../../../../components/app/sidebars/topology/TopologySidebarComponent' - -const TopologySidebarContainer = (props) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - return -} - -export default TopologySidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js deleted file mode 100644 index a0b52e56..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js +++ /dev/null @@ -1,5 +0,0 @@ -import BuildingSidebarComponent from '../../../../../components/app/sidebars/topology/building/BuildingSidebarComponent' - -const BuildingSidebarContainer = BuildingSidebarComponent - -export default BuildingSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js deleted file mode 100644 index 96f42a44..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { - cancelNewRoomConstruction, - finishNewRoomConstruction, - startNewRoomConstruction, -} from '../../../../../redux/actions/topology/building' -import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent' - -const NewRoomConstructionButton = (props) => { - const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) - - const dispatch = useDispatch() - const actions = { - onStart: () => dispatch(startNewRoomConstruction()), - onFinish: () => dispatch(finishNewRoomConstruction()), - onCancel: () => dispatch(cancelNewRoomConstruction()), - } - return ( - - ) -} - -export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js deleted file mode 100644 index ea250767..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' -import BackToRackComponent from '../../../../../components/app/sidebars/topology/machine/BackToRackComponent' - -const BackToRackContainer = (props) => { - const dispatch = useDispatch() - return dispatch(goDownOneInteractionLevel())} /> -} - -export default BackToRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js deleted file mode 100644 index 54e406f4..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteMachine } from '../../../../../redux/actions/topology/machine' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' - -const DeleteMachineContainer = () => { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteMachine()) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteMachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js deleted file mode 100644 index 9cbb32c5..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' - -const MachineNameContainer = () => { - const position = useSelector((state) => state.interactionLevel.position) - return

    Machine at slot {position}

    -} - -export default MachineNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js deleted file mode 100644 index 7553c2fe..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import MachineSidebarComponent from '../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent' - -const MachineSidebarContainer = (props) => { - const machineId = useSelector( - (state) => - state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ - state.interactionLevel.position - 1 - ] - ) - return -} - -export default MachineSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js deleted file mode 100644 index 0f85aa76..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addUnit } from '../../../../../redux/actions/topology/machine' -import UnitAddComponent from '../../../../../components/app/sidebars/topology/machine/UnitAddComponent' - -const UnitAddContainer = (props) => { - const units = useSelector((state) => Object.values(state.objects[props.unitType])) - const dispatch = useDispatch() - - const onAdd = (id) => dispatch(addUnit(props.unitType, id)) - - return -} - -export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js deleted file mode 100644 index cdd7e268..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent' -import { deleteUnit } from '../../../../../redux/actions/topology/machine' - -const unitMapping = { - cpu: 'cpus', - gpu: 'gpus', - memory: 'memories', - storage: 'storages', -} - -const UnitListContainer = ({ unitType, ...props }) => { - const dispatch = useDispatch() - const units = useSelector((state) => { - const machine = - state.objects.machine[ - state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ - state.interactionLevel.position - 1 - ] - ] - return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) - }) - const onDelete = (unit, unitType) => dispatch(deleteUnit(unitType, unit._id)) - - return -} - -UnitListContainer.propTypes = { - unitType: PropTypes.string.isRequired, -} - -export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js deleted file mode 100644 index 00fe4067..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js +++ /dev/null @@ -1,5 +0,0 @@ -import UnitTabsComponent from '../../../../../components/app/sidebars/topology/machine/UnitTabsComponent' - -const UnitTabsContainer = UnitTabsComponent - -export default UnitTabsContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js deleted file mode 100644 index c2a0fc48..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { addPrefab } from '../../../../../redux/actions/prefabs' -import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent' - -const AddPrefabContainer = (props) => { - const dispatch = useDispatch() - return dispatch(addPrefab('name'))} /> -} - -export default AddPrefabContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js deleted file mode 100644 index a98728a6..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' -import BackToRoomComponent from '../../../../../components/app/sidebars/topology/rack/BackToRoomComponent' - -const BackToRoomContainer = (props) => { - const dispatch = useDispatch() - return dispatch(goDownOneInteractionLevel())} /> -} - -export default BackToRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js deleted file mode 100644 index 4463530e..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRack } from '../../../../../redux/actions/topology/rack' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' - -const DeleteRackContainer = () => { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRack()) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js deleted file mode 100644 index 2118d915..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js +++ /dev/null @@ -1,29 +0,0 @@ -import React, { useMemo } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import MachineListComponent from '../../../../../components/app/sidebars/topology/rack/MachineListComponent' -import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' -import { addMachine } from '../../../../../redux/actions/topology/rack' - -const MachineListContainer = (props) => { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack]) - const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) - const machinesNull = useMemo(() => { - const res = Array(rack.capacity).fill(null) - for (const machine of machines) { - res[machine.position - 1] = machine - } - return res - }, [rack, machines]) - const dispatch = useDispatch() - - return ( - dispatch(addMachine(index))} - onSelect={(index) => dispatch(goFromRackToMachine(index))} - /> - ) -} - -export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js deleted file mode 100644 index 2c39cf9f..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ /dev/null @@ -1,33 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' -import TextInputModal from '../../../../../components/modals/TextInputModal' -import { editRackName } from '../../../../../redux/actions/topology/rack' - -const RackNameContainer = () => { - const [isVisible, setVisible] = useState(false) - const rackName = useSelector( - (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].name - ) - const dispatch = useDispatch() - const callback = (name) => { - if (name) { - dispatch(editRackName(name)) - } - setVisible(false) - } - return ( - <> - setVisible(true)} /> - - - ) -} - -export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js deleted file mode 100644 index 34777125..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackSidebarComponent from '../../../../../components/app/sidebars/topology/rack/RackSidebarComponent' - -const RackSidebarContainer = (props) => { - const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rack) - return -} - -export default RackSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js deleted file mode 100644 index 9fa1e95f..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' -import BackToBuildingComponent from '../../../../../components/app/sidebars/topology/room/BackToBuildingComponent' - -const BackToBuildingContainer = () => { - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - return -} - -export default BackToBuildingContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js deleted file mode 100644 index 0fbbb036..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import { Button } from 'reactstrap' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRoom } from '../../../../../redux/actions/topology/room' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' - -const DeleteRoomContainer = () => { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRoom()) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js deleted file mode 100644 index ec4f586b..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { finishRoomEdit, startRoomEdit } from '../../../../../redux/actions/topology/building' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCheck, faPencilAlt } from '@fortawesome/free-solid-svg-icons' - -const EditRoomContainer = () => { - const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) - - const dispatch = useDispatch() - const onEdit = () => dispatch(startRoomEdit()) - const onFinish = () => dispatch(finishRoomEdit()) - - return isEditing ? ( - - ) : ( - - ) -} - -export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js deleted file mode 100644 index 79584e98..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { startRackConstruction, stopRackConstruction } from '../../../../../redux/actions/topology/room' -import RackConstructionComponent from '../../../../../components/app/sidebars/topology/room/RackConstructionComponent' - -const RackConstructionContainer = (props) => { - const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) - const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - - const dispatch = useDispatch() - const onStart = () => dispatch(startRackConstruction()) - const onStop = () => dispatch(stopRackConstruction()) - return ( - - ) -} - -export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js deleted file mode 100644 index 3b35a849..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js +++ /dev/null @@ -1,31 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' -import TextInputModal from '../../../../../components/modals/TextInputModal' -import { editRoomName } from '../../../../../redux/actions/topology/room' - -const RoomNameContainer = () => { - const [isVisible, setVisible] = useState(false) - const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name) - const dispatch = useDispatch() - const callback = (name) => { - if (name) { - dispatch(editRoomName(name)) - } - setVisible(false) - } - return ( - <> - setVisible(true)} /> - - - ) -} - -export default RoomNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js deleted file mode 100644 index 252881a0..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RoomSidebarComponent from '../../../../../components/app/sidebars/topology/room/RoomSidebarComponent' - -const RoomSidebarContainer = (props) => { - const roomId = useSelector((state) => state.interactionLevel.roomId) - return -} - -export default RoomSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js deleted file mode 100644 index d8083d89..00000000 --- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react' -import { Button } from 'reactstrap' -import { useAuth } from '../../auth' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faSignInAlt } from '@fortawesome/free-solid-svg-icons' - -function Login({ visible, className }) { - const { loginWithRedirect } = useAuth() - - if (!visible) { - return - } - - return ( - - ) -} - -export default Login diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js deleted file mode 100644 index 37705c5d..00000000 --- a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import LogoutButton from '../../components/navigation/LogoutButton' -import { useAuth } from '../../auth' - -const Logout = (props) => { - const { logout } = useAuth() - return logout({ returnTo: window.location.origin })} /> -} - -export default Logout diff --git a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js deleted file mode 100644 index 70f5b884..00000000 --- a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' -import { useAuth } from '../../auth' - -function ProfileName() { - const { isLoading, user } = useAuth() - return isLoading ? Loading... : {user.name} -} - -export default ProfileName diff --git a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js deleted file mode 100644 index ff9f9fe7..00000000 --- a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import AppNavbarComponent from '../../components/navigation/AppNavbarComponent' -import { useActiveProjectId, useProject } from '../../data/project' - -const AppNavbarContainer = (props) => { - const projectId = useActiveProjectId() - const { data: project } = useProject(projectId) - return -} - -export default AppNavbarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js deleted file mode 100644 index ac0edae4..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import TextInputModal from '../../components/modals/TextInputModal' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faPlus } from '@fortawesome/free-solid-svg-icons' -import { useMutation } from 'react-query' - -/** - * A container for creating a new project. - */ -const NewProjectContainer = () => { - const [isVisible, setVisible] = useState(false) - const { mutate: addProject } = useMutation('addProject') - const callback = (text) => { - if (text) { - addProject({ name: text }) - } - setVisible(false) - } - - return ( - <> -
    - -
    - - - ) -} - -export default NewProjectContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js deleted file mode 100644 index 62985742..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import ProjectActionButtons from '../../components/projects/ProjectActionButtons' -import { useMutation } from 'react-query' - -const ProjectActions = (props) => { - const { mutate: deleteProject } = useMutation('deleteProject') - const actions = { - onViewUsers: (id) => {}, // TODO implement user viewing - onDelete: (id) => deleteProject(id), - } - return -} - -export default ProjectActions diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js deleted file mode 100644 index b5c5dd68..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import ProjectList from '../../components/projects/ProjectList' -import { useAuth } from '../../auth' -import { useProjects } from '../../data/project' - -const getVisibleProjects = (projects, filter, userId) => { - switch (filter) { - case 'SHOW_ALL': - return projects - case 'SHOW_OWN': - return projects.filter((project) => - project.authorizations.some((a) => a.userId === userId && a.level === 'OWN') - ) - case 'SHOW_SHARED': - return projects.filter((project) => - project.authorizations.some((a) => a.userId === userId && a.level !== 'OWN') - ) - default: - return projects - } -} - -const ProjectListContainer = ({ filter }) => { - const { user } = useAuth() - const { data: projects } = useProjects() - return -} - -ProjectListContainer.propTypes = { - filter: PropTypes.string.isRequired, -} - -export default ProjectListContainer diff --git a/opendc-web/opendc-web-ui/src/data/map.js b/opendc-web/opendc-web-ui/src/data/map.js index 6aef6ac5..348a6664 100644 --- a/opendc-web/opendc-web-ui/src/data/map.js +++ b/opendc-web/opendc-web-ui/src/data/map.js @@ -35,7 +35,3 @@ export function useMapScale() { export function useMapPosition() { return useSelector((state) => state.map.position) } - -export function useMapDimensions() { - return useSelector((state) => state.map.dimensions) -} diff --git a/opendc-web/opendc-web-ui/src/data/project.js b/opendc-web/opendc-web-ui/src/data/project.js index 9bdcfb93..9dcd8532 100644 --- a/opendc-web/opendc-web-ui/src/data/project.js +++ b/opendc-web/opendc-web-ui/src/data/project.js @@ -20,9 +20,8 @@ * SOFTWARE. */ -import { useQueries, useQuery } from 'react-query' +import { useQuery } from 'react-query' import { addProject, deleteProject, fetchProject, fetchProjects } from '../api/projects' -import { useRouter } from 'next/router' import { addPortfolio, deletePortfolio, fetchPortfolio, fetchPortfoliosOfProject } from '../api/portfolios' import { addScenario, deleteScenario, fetchScenario, fetchScenariosOfPortfolio } from '../api/scenarios' @@ -38,6 +37,7 @@ export function configureProjectClient(queryClient, auth) { mutationFn: (data) => addProject(auth, data), onSuccess: async (result) => { queryClient.setQueryData('projects', (old = []) => [...old, result]) + queryClient.setQueryData(['projects', result._id], result) }, }) queryClient.setMutationDefaults('deleteProject', { @@ -61,6 +61,7 @@ export function configureProjectClient(queryClient, auth) { ...old, portfolioIds: [...old.portfolioIds, result._id], })) + queryClient.setQueryData(['project-portfolios', result.projectId], (old = []) => [...old, result]) queryClient.setQueryData(['portfolios', result._id], result) }, }) @@ -71,6 +72,9 @@ export function configureProjectClient(queryClient, auth) { ...old, portfolioIds: old.portfolioIds.filter((id) => id !== result._id), })) + queryClient.setQueryData(['project-portfolios', result.projectId], (old = []) => + old.filter((portfolio) => portfolio._id !== result._id) + ) queryClient.removeQueries(['portfolios', result._id]) }, }) @@ -86,6 +90,7 @@ export function configureProjectClient(queryClient, auth) { onSuccess: async (result) => { // Register updated scenario in cache queryClient.setQueryData(['scenarios', result._id], result) + queryClient.setQueryData(['portfolio-scenarios', result.portfolioId], (old = []) => [...old, result]) // Add scenario id to portfolio queryClient.setQueryData(['portfolios', result.portfolioId], (old) => ({ @@ -101,6 +106,9 @@ export function configureProjectClient(queryClient, auth) { ...old, scenarioIds: old.scenarioIds.filter((id) => id !== result._id), })) + queryClient.setQueryData(['portfolio-scenarios', result.portfolioId], (old = []) => + old.filter((scenario) => scenario._id !== result._id) + ) queryClient.removeQueries(['scenarios', result._id]) }, }) @@ -109,54 +117,34 @@ export function configureProjectClient(queryClient, auth) { /** * Return the available projects. */ -export function useProjects() { - return useQuery('projects') +export function useProjects(options = {}) { + return useQuery('projects', options) } /** * Return the project with the specified identifier. */ -export function useProject(projectId) { - return useQuery(['projects', projectId], { enabled: !!projectId }) +export function useProject(projectId, options = {}) { + return useQuery(['projects', projectId], { enabled: !!projectId, ...options }) } /** * Return the portfolio with the specified identifier. */ -export function usePortfolio(portfolioId) { - return useQuery(['portfolios', portfolioId], { enabled: !!portfolioId }) +export function usePortfolio(portfolioId, options = {}) { + return useQuery(['portfolios', portfolioId], { enabled: !!portfolioId, ...options }) } /** * Return the portfolios of the specified project. */ -export function useProjectPortfolios(projectId) { - return useQuery(['project-portfolios', projectId], { enabled: !!projectId }) -} - -/** - * Return the scenarios with the specified identifiers. - */ -export function useScenarios(scenarioIds) { - return useQueries( - scenarioIds.map((scenarioId) => ({ - queryKey: ['scenarios', scenarioId], - })) - ) +export function useProjectPortfolios(projectId, options = {}) { + return useQuery(['project-portfolios', projectId], { enabled: !!projectId, ...options }) } /** * Return the scenarios of the specified portfolio. */ -export function usePortfolioScenarios(portfolioId) { - return useQuery(['portfolio-scenarios', portfolioId], { enabled: !!portfolioId }) -} - -/** - * Return the current active project identifier. - */ -export function useActiveProjectId() { - const router = useRouter() - const { project } = router.query - return project +export function usePortfolioScenarios(portfolioId, options = {}) { + return useQuery(['portfolio-scenarios', portfolioId], { enabled: !!portfolioId, ...options }) } diff --git a/opendc-web/opendc-web-ui/src/data/topology.js b/opendc-web/opendc-web-ui/src/data/topology.js index 8db75877..14bd7562 100644 --- a/opendc-web/opendc-web-ui/src/data/topology.js +++ b/opendc-web/opendc-web-ui/src/data/topology.js @@ -21,7 +21,7 @@ */ import { useSelector } from 'react-redux' -import { useQueries, useQuery } from 'react-query' +import { useQuery } from 'react-query' import { addTopology, deleteTopology, fetchTopologiesOfProject, fetchTopology, updateTopology } from '../api/topologies' /** @@ -40,6 +40,7 @@ export function configureTopologyClient(queryClient, auth) { ...old, topologyIds: [...old.topologyIds, result._id], })) + queryClient.setQueryData(['project-topologies', result.projectId], (old = []) => [...old, result]) queryClient.setQueryData(['topologies', result._id], result) }, }) @@ -54,6 +55,9 @@ export function configureTopologyClient(queryClient, auth) { ...old, topologyIds: old.topologyIds.filter((id) => id !== result._id), })) + queryClient.setQueryData(['project-topologies', result.projectId], (old = []) => + old.filter((topology) => topology._id !== result._id) + ) queryClient.removeQueries(['topologies', result._id]) }, }) @@ -69,6 +73,6 @@ export function useActiveTopology() { /** * Return the topologies of the specified project. */ -export function useProjectTopologies(projectId) { - return useQuery(['project-topologies', projectId], { enabled: !!projectId }) +export function useProjectTopologies(projectId, options = {}) { + return useQuery(['project-topologies', projectId], { enabled: !!projectId, ...options }) } diff --git a/opendc-web/opendc-web-ui/src/index.scss b/opendc-web/opendc-web-ui/src/index.scss deleted file mode 100644 index dbd9550c..00000000 --- a/opendc-web/opendc-web-ui/src/index.scss +++ /dev/null @@ -1,68 +0,0 @@ -@import '~bootstrap/scss/bootstrap'; - -@import './style/_mixins.scss'; -@import './style/_variables.scss'; - -html, -body, -#__next { - margin: 0; - padding: 0; - width: 100%; - height: 100%; - - font-family: Roboto, Helvetica, Verdana, sans-serif; - background: #eee; - - // Scroll padding for top navbar - scroll-padding-top: 60px; -} - -.full-height { - position: relative; - height: 100% !important; -} - -.page-container { - padding-top: 60px; -} - -.text-page-container { - padding-top: 80px; - display: flex; - flex-flow: column; -} - -.vertically-expanding-container { - flex: 1 1 auto; - overflow-y: auto; -} - -.bottom-btn-container { - flex: 0 1 auto; - padding: 20px 0; -} - -.btn, -.list-group-item-action, -.clickable { - @include clickable; -} - -.btn-circle { - border-radius: 50%; -} - -a, -a:hover { - text-decoration: none; -} - -.app-page-container { - padding-left: $side-bar-width; - padding-top: 15px; -} - -.w-70 { - width: 70% !important; -} diff --git a/opendc-web/opendc-web-ui/src/pages/404.js b/opendc-web/opendc-web-ui/src/pages/404.js index cc9281fc..0939bc56 100644 --- a/opendc-web/opendc-web-ui/src/pages/404.js +++ b/opendc-web/opendc-web-ui/src/pages/404.js @@ -1,18 +1,37 @@ import React from 'react' import Head from 'next/head' -import TerminalWindow from '../components/not-found/TerminalWindow' -import style from './404.module.scss' +import { AppPage } from '../components/AppPage' +import { + Bullseye, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + PageSection, + PageSectionVariants, + Title, +} from '@patternfly/react-core' +import { UnknownIcon } from '@patternfly/react-icons' const NotFound = () => { return ( - <> + Page Not Found - OpenDC -
    - -
    - + + + + + + 404: That page does not exist + + + The requested page is not found. Try refreshing the page if it was recently added. + + + + +
    ) } diff --git a/opendc-web/opendc-web-ui/src/pages/404.module.scss b/opendc-web/opendc-web-ui/src/pages/404.module.scss deleted file mode 100644 index e91c2780..00000000 --- a/opendc-web/opendc-web-ui/src/pages/404.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.not-found-backdrop { - display: flex; - - width: 100%; - height: 100%; - - background-image: linear-gradient(135deg, #00678a, #008fbf, #00a6d6); -} diff --git a/opendc-web/opendc-web-ui/src/pages/_app.js b/opendc-web/opendc-web-ui/src/pages/_app.js index 78402323..028dab10 100644 --- a/opendc-web/opendc-web-ui/src/pages/_app.js +++ b/opendc-web/opendc-web-ui/src/pages/_app.js @@ -24,8 +24,6 @@ import PropTypes from 'prop-types' import Head from 'next/head' import { Provider } from 'react-redux' import { useStore } from '../redux' -import '../index.scss' -import '@patternfly/react-core/dist/styles/base.css' import { AuthProvider, useAuth } from '../auth' import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' @@ -35,6 +33,19 @@ import { configureProjectClient } from '../data/project' import { configureExperimentClient } from '../data/experiments' import { configureTopologyClient } from '../data/topology' +import '@patternfly/react-core/dist/styles/base.css' +import '@patternfly/react-styles/css/utilities/Alignment/alignment.css' +import '@patternfly/react-styles/css/utilities/BackgroundColor/BackgroundColor.css' +import '@patternfly/react-styles/css/utilities/BoxShadow/box-shadow.css' +import '@patternfly/react-styles/css/utilities/Display/display.css' +import '@patternfly/react-styles/css/utilities/Flex/flex.css' +import '@patternfly/react-styles/css/utilities/Float/float.css' +import '@patternfly/react-styles/css/utilities/Sizing/sizing.css' +import '@patternfly/react-styles/css/utilities/Spacing/spacing.css' +import '@patternfly/react-styles/css/utilities/Text/text.css' +import '@patternfly/react-styles/css/components/InlineEdit/inline-edit.css' +import '../style/index.scss' + // This setup is necessary to forward the Auth0 context to the Redux context const Inner = ({ Component, pageProps }) => { const auth = useAuth() diff --git a/opendc-web/opendc-web-ui/src/pages/logout.js b/opendc-web/opendc-web-ui/src/pages/logout.js index e96e0605..38d5968e 100644 --- a/opendc-web/opendc-web-ui/src/pages/logout.js +++ b/opendc-web/opendc-web-ui/src/pages/logout.js @@ -22,17 +22,17 @@ import React from 'react' import Head from 'next/head' -import AppNavbarContainer from '../containers/navigation/AppNavbarContainer' +import { AppPage } from '../components/AppPage' +import { PageSection, PageSectionVariants } from '@patternfly/react-core' function Logout() { return ( - <> + Logged Out - OpenDC - - Logged out successfully - + Logged out successfully + ) } diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js index cce887aa..c6ded12b 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js @@ -20,6 +20,113 @@ * SOFTWARE. */ -import Topology from './topologies/[topology]' +import { useRouter } from 'next/router' +import { useProject } from '../../../data/project' +import { AppPage } from '../../../components/AppPage' +import Head from 'next/head' +import { + Breadcrumb, + BreadcrumbItem, + Button, + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Grid, + GridItem, + PageSection, + PageSectionVariants, + Skeleton, + Text, + TextContent, +} from '@patternfly/react-core' +import BreadcrumbLink from '../../../components/util/BreadcrumbLink' +import PortfolioTable from '../../../components/projects/PortfolioTable' +import TopologyTable from '../../../components/projects/TopologyTable' +import NewTopology from '../../../components/projects/NewTopology' +import NewPortfolio from '../../../components/projects/NewPortfolio' -export default Topology +function Project() { + const router = useRouter() + const { project: projectId } = router.query + + const { data: project } = useProject(projectId) + + const breadcrumb = ( + + + Projects + + + Project details + + + ) + + return ( + + + {project?.name ?? 'Project'} - OpenDC + + + + + {project?.name ?? } + + + + + + + + Details + + + + Name + + {project?.name ?? } + + + + + + + + + + + + + Topologies + + + + + + + + + + + + + Portfolios + + + + + + + + + + ) +} + +export default Project diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js index d3d61271..55bee445 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js @@ -22,12 +22,41 @@ import { useRouter } from 'next/router' import Head from 'next/head' -import AppNavbarContainer from '../../../../containers/navigation/AppNavbarContainer' -import React from 'react' -import { useProject } from '../../../../data/project' -import ProjectSidebarContainer from '../../../../containers/app/sidebars/project/ProjectSidebarContainer' -import PortfolioResultsContainer from '../../../../containers/app/results/PortfolioResultsContainer' -import { useDispatch } from 'react-redux' +import React, { useRef } from 'react' +import { usePortfolio, useProject } from '../../../../data/project' +import { + Breadcrumb, + BreadcrumbItem, + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + Chip, + ChipGroup, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Divider, + Grid, + GridItem, + PageSection, + PageSectionVariants, + Skeleton, + Tab, + TabContent, + Tabs, + TabTitleText, + Text, + TextContent, +} from '@patternfly/react-core' +import { AppPage } from '../../../../components/AppPage' +import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' +import ScenarioTable from '../../../../components/projects/ScenarioTable' +import NewScenario from '../../../../components/projects/NewScenario' +import { METRIC_NAMES } from '../../../../util/available-metrics' +import PortfolioResults from '../../../../components/app/results/PortfolioResults' /** * Page that displays the results in a portfolio. @@ -36,24 +65,127 @@ function Portfolio() { const router = useRouter() const { project: projectId, portfolio: portfolioId } = router.query - const project = useProject(projectId) - const title = project?.name ? project?.name + ' - OpenDC' : 'Simulation - OpenDC' + const { data: project } = useProject(projectId) + const { data: portfolio } = usePortfolio(portfolioId) - const dispatch = useDispatch() + const overviewRef = useRef(null) + const resultsRef = useRef(null) + + const breadcrumb = ( + + + Projects + + + Project details + + + Portfolio + + + ) return ( -
    + - {title} + {project?.name ?? 'Portfolios'} - OpenDC - -
    - -
    - -
    -
    -
    + + + Portfolio + + + + + + Overview} + tabContentId="overview" + tabContentRef={overviewRef} + /> + Results} + tabContentId="results" + tabContentRef={resultsRef} + /> + + + + + + + + Details + + + + Name + + {portfolio?.name ?? } + + + + Scenarios + + {portfolio?.scenarioIds.length ?? ( + + )} + + + + Metrics + + {portfolio?.targets?.enabledMetrics ? ( + portfolio.targets.enabledMetrics.length > 0 ? ( + + {portfolio.targets.enabledMetrics.map((metric) => ( + + {METRIC_NAMES[metric]} + + ))} + + ) : ( + 'No metrics enabled' + ) + ) : ( + + )} + + + + Repeats per Scenario + + {portfolio?.targets?.repeatsPerScenario ?? ( + + )} + + + + + + + + + + + + + Scenarios + + + + + + + + + + + ) } diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index a9dfdb19..5873ed11 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -23,18 +23,29 @@ import { useRouter } from 'next/router' import { useProject } from '../../../../data/project' import { useDispatch, useSelector } from 'react-redux' -import React, { useEffect } from 'react' +import React, { useEffect, useState } from 'react' import { HotKeys } from 'react-hotkeys' import { KeymapConfiguration } from '../../../../hotkeys' import Head from 'next/head' -import AppNavbarContainer from '../../../../containers/navigation/AppNavbarContainer' -import LoadingScreen from '../../../../components/app/map/LoadingScreen' -import MapStage from '../../../../containers/app/map/MapStage' -import ScaleIndicatorContainer from '../../../../containers/app/map/controls/ScaleIndicatorContainer' -import ToolPanelComponent from '../../../../components/app/map/controls/ToolPanelComponent' -import ProjectSidebarContainer from '../../../../containers/app/sidebars/project/ProjectSidebarContainer' -import TopologySidebarContainer from '../../../../containers/app/sidebars/topology/TopologySidebarContainer' +import MapStage from '../../../../components/app/map/MapStage' import { openProjectSucceeded } from '../../../../redux/actions/projects' +import { AppPage } from '../../../../components/AppPage' +import { + Bullseye, + Drawer, + DrawerContent, + DrawerContentBody, + EmptyState, + EmptyStateIcon, + Spinner, + Title, +} from '@patternfly/react-core' +import { zoomInOnCenter } from '../../../../redux/actions/map' +import Toolbar from '../../../../components/app/map/controls/Toolbar' +import { useMapScale } from '../../../../data/map' +import ScaleIndicator from '../../../../components/app/map/controls/ScaleIndicator' +import TopologySidebar from '../../../../components/app/sidebars/topology/TopologySidebar' +import Collapse from '../../../../components/app/map/controls/Collapse' /** * Page that displays a datacenter topology. @@ -44,7 +55,6 @@ function Topology() { const { project: projectId, topology: topologyId } = router.query const { data: project } = useProject(projectId) - const title = project?.name ? project?.name + ' - OpenDC' : 'Simulation - OpenDC' const dispatch = useDispatch() useEffect(() => { @@ -54,27 +64,44 @@ function Topology() { }, [projectId, topologyId, dispatch]) const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') + const scale = useMapScale() + const interactionLevel = useSelector((state) => state.interactionLevel) + + const [isExpanded, setExpanded] = useState(true) + const panelContent = setExpanded(false)} /> return ( - + - {title} + {project?.name ?? 'Topologies'} - OpenDC - {topologyIsLoading ? ( -
    - -
    + + + + + Loading Topology + + + ) : ( -
    - - - - - -
    + + + + + + + dispatch(zoomInOnCenter(zoomIn))} + onExport={() => window['exportCanvasToImage']()} + /> + setExpanded(true)} /> + + + + )} -
    + ) } diff --git a/opendc-web/opendc-web-ui/src/pages/projects/index.js b/opendc-web/opendc-web-ui/src/pages/projects/index.js index 2d8e6de7..9dcc9aea 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/index.js +++ b/opendc-web/opendc-web-ui/src/pages/projects/index.js @@ -1,31 +1,87 @@ -import React, { useState } from 'react' +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { useMemo, useState } from 'react' import Head from 'next/head' import ProjectFilterPanel from '../../components/projects/FilterPanel' -import NewProjectContainer from '../../containers/projects/NewProjectContainer' -import ProjectListContainer from '../../containers/projects/ProjectListContainer' -import AppNavbarContainer from '../../containers/navigation/AppNavbarContainer' -import { useRequireAuth } from '../../auth' -import { Container } from 'reactstrap' +import { useAuth, useRequireAuth } from '../../auth' +import { AppPage } from '../../components/AppPage' +import { PageSection, PageSectionVariants, Text, TextContent } from '@patternfly/react-core' +import { useProjects } from '../../data/project' +import ProjectTable from '../../components/projects/ProjectTable' +import { useMutation } from 'react-query' +import NewProject from '../../components/projects/NewProject' + +const getVisibleProjects = (projects, filter, userId) => { + switch (filter) { + case 'SHOW_ALL': + return projects + case 'SHOW_OWN': + return projects.filter((project) => + project.authorizations.some((a) => a.userId === userId && a.level === 'OWN') + ) + case 'SHOW_SHARED': + return projects.filter((project) => + project.authorizations.some((a) => a.userId === userId && a.level !== 'OWN') + ) + default: + return projects + } +} function Projects() { useRequireAuth() - + const { user } = useAuth() + const { status, data: projects } = useProjects() const [filter, setFilter] = useState('SHOW_ALL') + const visibleProjects = useMemo(() => getVisibleProjects(projects ?? [], filter, user?.sub), [ + projects, + filter, + user?.sub, + ]) + + const { mutate: deleteProject } = useMutation('deleteProject') return ( - <> + My Projects - OpenDC -
    - - - - - - -
    - + + + My Projects + + + + + deleteProject(project._id)} + /> + + +
    ) } diff --git a/opendc-web/opendc-web-ui/src/shapes.js b/opendc-web/opendc-web-ui/src/shapes.js index 3c27ad11..abdf146e 100644 --- a/opendc-web/opendc-web-ui/src/shapes.js +++ b/opendc-web/opendc-web-ui/src/shapes.js @@ -149,3 +149,5 @@ export const InteractionLevel = PropTypes.shape({ roomId: PropTypes.string, rackId: PropTypes.string, }) + +export const Status = PropTypes.oneOf(['idle', 'loading', 'error', 'success']) diff --git a/opendc-web/opendc-web-ui/src/style/_mixins.scss b/opendc-web/opendc-web-ui/src/style/_mixins.scss deleted file mode 100644 index 5f103cd7..00000000 --- a/opendc-web/opendc-web-ui/src/style/_mixins.scss +++ /dev/null @@ -1,5 +0,0 @@ -/* General Button Abstractions */ -@mixin clickable { - cursor: pointer; - user-select: none; -} diff --git a/opendc-web/opendc-web-ui/src/style/_variables.scss b/opendc-web/opendc-web-ui/src/style/_variables.scss deleted file mode 100644 index e3df6cbd..00000000 --- a/opendc-web/opendc-web-ui/src/style/_variables.scss +++ /dev/null @@ -1,31 +0,0 @@ -// Sizes and Margins -$document-padding: 20px; -$inter-element-margin: 5px; -$standard-border-radius: 5px; -$side-menu-width: 350px; -$color-indicator-width: 140px; - -$global-padding: 30px; -$side-bar-width: 350px; -$navbar-height: 50px; -$navbar-padding: 10px; - -// Durations -$transition-length: 150ms; - -// Colors -$gray-very-dark: #5c5c5c; -$gray-dark: #aaa; -$gray-semi-dark: #bbb; -$gray-semi-light: #ccc; -$gray-light: #ddd; -$gray-very-light: #eee; -$blue: #00a6d6; -$blue-dark: #0087b5; -$blue-very-dark: #006182; -$blue-light: #deebf7; - -// Media queries -$screen-sm: 768px; -$screen-md: 992px; -$screen-lg: 1200px; diff --git a/opendc-web/opendc-web-ui/src/style/index.scss b/opendc-web/opendc-web-ui/src/style/index.scss new file mode 100644 index 00000000..ff84e24a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/style/index.scss @@ -0,0 +1,36 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +body, +#__next { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + + background: #eee; +} + +.full-height { + position: relative; + height: 100% !important; +} diff --git a/opendc-web/opendc-web-ui/src/util/authorizations.js b/opendc-web/opendc-web-ui/src/util/authorizations.js index eb492d26..ce5d34b6 100644 --- a/opendc-web/opendc-web-ui/src/util/authorizations.js +++ b/opendc-web/opendc-web-ui/src/util/authorizations.js @@ -1,9 +1,11 @@ -import { faHome, faPencilAlt, faEye } from '@fortawesome/free-solid-svg-icons' +import HomeIcon from '@patternfly/react-icons/dist/js/icons/home-icon' +import EditIcon from '@patternfly/react-icons/dist/js/icons/edit-icon' +import EyeIcon from '@patternfly/react-icons/dist/js/icons/eye-icon' export const AUTH_ICON_MAP = { - OWN: faHome, - EDIT: faPencilAlt, - VIEW: faEye, + OWN: HomeIcon, + EDIT: EditIcon, + VIEW: EyeIcon, } export const AUTH_DESCRIPTION_MAP = { diff --git a/opendc-web/opendc-web-ui/src/util/available-metrics.js b/opendc-web/opendc-web-ui/src/util/available-metrics.js index 807bc0c1..b21ab150 100644 --- a/opendc-web/opendc-web-ui/src/util/available-metrics.js +++ b/opendc-web/opendc-web-ui/src/util/available-metrics.js @@ -1,12 +1,28 @@ +export const METRIC_GROUPS = { + 'Host Metrics': [ + 'total_overcommitted_burst', + 'total_power_draw', + 'total_failure_vm_slices', + 'total_granted_burst', + 'total_interfered_burst', + 'total_requested_burst', + 'mean_cpu_usage', + 'mean_cpu_demand', + 'mean_num_deployed_images', + 'max_num_deployed_images', + ], + 'Compute Service Metrics': ['total_vms_submitted', 'total_vms_queued', 'total_vms_finished', 'total_vms_failed'], +} + export const AVAILABLE_METRICS = [ + 'mean_cpu_usage', + 'mean_cpu_demand', + 'total_requested_burst', + 'total_granted_burst', 'total_overcommitted_burst', + 'total_interfered_burst', 'total_power_draw', 'total_failure_vm_slices', - 'total_granted_burst', - 'total_interfered_burst', - 'total_requested_burst', - 'mean_cpu_usage', - 'mean_cpu_demand', 'mean_num_deployed_images', 'max_num_deployed_images', 'total_vms_submitted', @@ -65,3 +81,22 @@ export const METRIC_UNITS = { total_vms_finished: 'VMs', total_vms_failed: 'VMs', } + +export const METRIC_DESCRIPTIONS = { + total_overcommitted_burst: + 'The total CPU clock cycles lost due to overcommitting of resources. This metric is an indicator for resource overload.', + total_requested_burst: 'The total CPU clock cycles that were requested by all virtual machines.', + total_granted_burst: 'The total CPU clock cycles executed by the hosts.', + total_interfered_burst: 'The total CPU clock cycles lost due to resource interference between virtual machines.', + total_power_draw: 'The average power usage in watts.', + mean_cpu_usage: 'The average amount of CPU clock cycles consumed by all virtual machines on a host.', + mean_cpu_demand: 'The average amount of CPU clock cycles requested by all powered on virtual machines on a host.', + mean_num_deployed_images: 'The average number of virtual machines deployed on a host.', + max_num_deployed_images: 'The maximum number of virtual machines deployed at any time.', + total_failure_vm_slices: 'The total amount of CPU clock cycles lost due to failure.', + total_vms_submitted: 'The total number of virtual machines scheduled by the compute service.', + total_vms_queued: + 'The maximum number of virtual machines waiting to be scheduled by the compute service at any point.', + total_vms_finished: 'The total number of virtual machines that completed successfully.', + total_vms_failed: 'The total number of virtual machines that failed during execution.', +} diff --git a/opendc-web/opendc-web-ui/src/util/date-time.js b/opendc-web/opendc-web-ui/src/util/date-time.js index 66efdf5b..7e2f6623 100644 --- a/opendc-web/opendc-web-ui/src/util/date-time.js +++ b/opendc-web/opendc-web-ui/src/util/date-time.js @@ -7,19 +7,7 @@ * @returns {string} A human-friendly string version of that date and time. */ export function parseAndFormatDateTime(dateTimeString) { - return formatDateTime(parseDateTime(dateTimeString)) -} - -/** - * Parses date-time string representations and returns a parsed object. - * - * The format assumed is "YYYY-MM-DDTHH:MM:SS". - * - * @param dateTimeString A string expressing a date and a time, in the above mentioned format. - * @returns {object} A Date object with the parsed date and time information as content. - */ -export function parseDateTime(dateTimeString) { - return new Date(dateTimeString + '.000Z') + return formatDateTime(new Date(dateTimeString)) } /** diff --git a/opendc-web/opendc-web-ui/src/util/date-time.test.js b/opendc-web/opendc-web-ui/src/util/date-time.test.js index 3d95eba6..431e39f7 100644 --- a/opendc-web/opendc-web-ui/src/util/date-time.test.js +++ b/opendc-web/opendc-web-ui/src/util/date-time.test.js @@ -1,18 +1,4 @@ -import { convertSecondsToFormattedTime, parseDateTime } from './date-time' - -describe('date-time parsing', () => { - it('reads components properly', () => { - const dateString = '2017-09-27T20:55:01' - const parsedDate = parseDateTime(dateString) - - expect(parsedDate.getUTCFullYear()).toEqual(2017) - expect(parsedDate.getUTCMonth()).toEqual(8) - expect(parsedDate.getUTCDate()).toEqual(27) - expect(parsedDate.getUTCHours()).toEqual(20) - expect(parsedDate.getUTCMinutes()).toEqual(55) - expect(parsedDate.getUTCSeconds()).toEqual(1) - }) -}) +import { convertSecondsToFormattedTime } from './date-time' describe('tick formatting', () => { it("returns '0s' for numbers <= 0", () => { diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index abd2613e..cd446e99 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -148,14 +148,6 @@ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== -"@hypnosphi/create-react-context@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6" - integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A== - dependencies: - gud "^1.0.0" - warning "^4.0.3" - "@next/env@11.0.1": version "11.0.1" resolved "https://registry.yarnpkg.com/@next/env/-/env-11.0.1.tgz#6dc96ac76f1663ab747340e907e8933f190cc8fd" @@ -214,33 +206,45 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@patternfly/react-core@^4.135.0": - version "4.135.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.135.0.tgz#b64ad4da10a8814926e28fad727bc7690cd60e66" - integrity sha512-DZcONUGOR7Znd6BsUJ4L+KrrnIpyjUvh3JNcYiHW3loytxShCGcx+a04QjOOcZm+MtFhkgs/t51yiC5IP12abA== +"@patternfly/react-core@^4.135.7": + version "4.135.7" + resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.135.7.tgz#7292e4472ffcd519e3db1af782cb4d28024a6992" + integrity sha512-bxYLJ7TTXiEVHscfzqGbI+YFqwQMYWfG2Yknw/b/QqwN/bv5eCpioYOo35Wr4jvFAWkXvUUKp/DUpcSHrrFgTg== dependencies: - "@patternfly/react-icons" "^4.11.0" - "@patternfly/react-styles" "^4.11.0" - "@patternfly/react-tokens" "^4.12.0" + "@patternfly/react-icons" "^4.11.2" + "@patternfly/react-styles" "^4.11.2" + "@patternfly/react-tokens" "^4.12.3" focus-trap "6.2.2" react-dropzone "9.0.0" tippy.js "5.1.2" tslib "1.13.0" -"@patternfly/react-icons@^4.11.0": - version "4.11.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.11.0.tgz#26790eeff22dc3204aa8cd094470f0a2f915634a" - integrity sha512-WsIX34bO9rhVRmPG0jlV3GoFGfYgPC64TscNV0lxQosiVRnYIA6Z3nBSArtJsxo5Yn6c63glIefC/YTy6D/ZYg== - -"@patternfly/react-styles@^4.11.0": - version "4.11.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.11.0.tgz#0068dcb18e1343242f93fa6024dcc077acd57fb9" - integrity sha512-4eIqTwGI4mjt9DMqX6hnan4eRS+3LUWNaneTEJdmk+flKxtAE/O/OmQHvH4GetDnlSbyfATcA0VFbVtR0aRJAg== +"@patternfly/react-icons@^4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.11.2.tgz#46f01197f779996954fd8033681644dd167cebcb" + integrity sha512-BPRWHAopry4a8aFd3VWaqO8h7QDA4NeYZ80YAY1iGqWeClIAmZlxs6jGCUhTC7iuYmjKruiVoDQwuwr/u+p6JQ== + +"@patternfly/react-styles@^4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.11.2.tgz#3548d1c2a5b8a989f9edc6bd31165952e5f8bcb7" + integrity sha512-rUtw2tfniBiVIYEXPO8buisWFEHVR6dO5PH6C2MvbMk+VyUIS31TzOeNFyJs/gCurt7t1dEKjI9yNEGuAOjUPQ== + +"@patternfly/react-table@^4.29.8": + version "4.29.8" + resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.29.8.tgz#9a8f1d1332c2f708427c81a693c2e90f9f52c75e" + integrity sha512-N6oKSE0sRHvkc9KWF03oTISfsc6G5NRBRCedi81hnpOSVo2515lGnA/r1ipR1DwM9qHYxmPNsrkPeoYtDQBOSQ== + dependencies: + "@patternfly/react-core" "^4.135.7" + "@patternfly/react-icons" "^4.11.2" + "@patternfly/react-styles" "^4.11.2" + "@patternfly/react-tokens" "^4.12.3" + lodash "^4.17.19" + tslib "1.13.0" -"@patternfly/react-tokens@^4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.12.0.tgz#2973c7f08a2f35997a0054bbf3c886b3c5c68822" - integrity sha512-Oj+GxqTtx0Yu9IDCTibZLQnpcKp58JneNKEFQkJ29WJydhPG4j6oFFElkK+ub+Ft/f9B1Ky1SsfR9eabo6IykQ== +"@patternfly/react-tokens@^4.12.3": + version "4.12.3" + resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.12.3.tgz#600b77e460e291032d649febf43002fe355a4468" + integrity sha512-RgXPEDdgx/p2VPQyCCxvv+ff9lmgYm4QDcI3c8iIwQjpPnJ5KF/bT6lPoAfeLFocRIZDnDSDcwSINbQwPQGp2A== "@redux-saga/core@^1.1.3": version "1.1.3" @@ -727,11 +731,6 @@ bn.js@^5.0.0, bn.js@^5.1.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -bootstrap@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7" - integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw== - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -958,7 +957,7 @@ classnames@2.2.6, classnames@~2.2.5: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -classnames@^2.2.3, classnames@^2.2.5: +classnames@^2.2.5: version "2.3.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== @@ -1289,18 +1288,6 @@ deep-diff@^0.3.5: resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= -deep-equal@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -1990,11 +1977,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== -gud@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" - integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== - has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -2291,7 +2273,7 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= -is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.3: +is-regex@^1.1.2, is-regex@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== @@ -3153,7 +3135,7 @@ pnp-webpack-plugin@1.6.4: dependencies: ts-pnp "^1.1.6" -popper.js@^1.14.4, popper.js@^1.16.0: +popper.js@^1.16.0: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== @@ -3210,7 +3192,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: +prop-types@15.7.2, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -3367,19 +3349,6 @@ react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== -react-popper@^1.3.6: - version "1.3.11" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd" - integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg== - dependencies: - "@babel/runtime" "^7.1.2" - "@hypnosphi/create-react-context" "^0.3.1" - deep-equal "^1.1.1" - popper.js "^1.14.4" - prop-types "^15.6.1" - typed-styles "^0.0.7" - warning "^4.0.2" - react-query@^3.18.1: version "3.18.1" resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.18.1.tgz#893b5475a7b4add099e007105317446f7a2cd310" @@ -3434,7 +3403,7 @@ react-smooth@^2.0.0: raf "^3.4.0" react-transition-group "2.9.0" -react-transition-group@2.9.0, react-transition-group@^2.3.1: +react-transition-group@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== @@ -3452,17 +3421,6 @@ react@^17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" -reactstrap@^8.9.0: - version "8.9.0" - resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.9.0.tgz#bca4afa3f5cd18899ef9b33d877a141886d5abae" - integrity sha512-pmf33YjpNZk1IfrjqpWCUMq9hk6GzSnMWBAofTBNIRJQB1zQ0Au2kzv3lPUAFsBYgWEuI9iYa/xKXHaboSiMkQ== - dependencies: - "@babel/runtime" "^7.12.5" - classnames "^2.2.3" - prop-types "^15.5.8" - react-popper "^1.3.6" - react-transition-group "^2.3.1" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -3582,7 +3540,7 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: +regexp.prototype.flags@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== @@ -4222,11 +4180,6 @@ typed-function@^2.0.0: resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.0.0.tgz#15ab3825845138a8b1113bd89e60cd6a435739e8" integrity sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA== -typed-styles@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" - integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== - typescript-compare@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/typescript-compare/-/typescript-compare-0.0.2.tgz#7ee40a400a406c2ea0a7e551efd3309021d5f425" @@ -4289,6 +4242,13 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +use-resize-observer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/use-resize-observer/-/use-resize-observer-7.0.0.tgz#15f0efbd5a4e08a8cc51901f21a89ba836f2116e" + integrity sha512-+RjrQsk/mL8aKy4TGBDiPkUv6whyeoGDMIZYk0gOGHOlnrsjImC+jG6lfAFcBCKAG9epGRL419adhDNdkDCQkA== + dependencies: + resize-observer-polyfill "^1.5.1" + use-subscription@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" @@ -4358,7 +4318,7 @@ vm-browserify@1.1.2, vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -warning@^4.0.0, warning@^4.0.2, warning@^4.0.3: +warning@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== -- cgit v1.2.3 From e5caf6c6122684e441d1d73e2e0507fdd36c67e0 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 16 Jul 2021 14:20:34 +0200 Subject: feat(ui): Support panning of the datacenter topology This change enables support for panning the visualized datacenter topology by using the mouse or holding shortcuts. Previously, this could only be done through repeated key presses. --- opendc-web/opendc-web-ui/src/components/app/map/MapStage.js | 2 +- .../src/pages/projects/[project]/topologies/[topology].js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js index 73accf3f..684ddf28 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js @@ -52,7 +52,7 @@ function MapStage() { return ( - + diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index 5873ed11..786bed07 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -24,7 +24,7 @@ import { useRouter } from 'next/router' import { useProject } from '../../../../data/project' import { useDispatch, useSelector } from 'react-redux' import React, { useEffect, useState } from 'react' -import { HotKeys } from 'react-hotkeys' +import {configure, HotKeys} from 'react-hotkeys' import { KeymapConfiguration } from '../../../../hotkeys' import Head from 'next/head' import MapStage from '../../../../components/app/map/MapStage' @@ -70,6 +70,11 @@ function Topology() { const [isExpanded, setExpanded] = useState(true) const panelContent = setExpanded(false)} /> + // Make sure that holding down a key will generate repeated events + configure({ + ignoreRepeatedEventsWhenKeyHeldDown: false + }) + return ( -- cgit v1.2.3 From f2aeecccc096728d3df955b71e711c8d9c429427 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 16 Jul 2021 17:37:01 +0200 Subject: refactor(ui): Isolate world coordinate space This change updates the topology view in the OpenDC frontend to isolate the world coordinate space. This means that zooming and panning should not affect the coordinates in world space (but only in camera space). In turn, this allows us to remove the dependency on Redux for the camera controls. --- .../src/components/app/map/MapConstants.js | 3 - .../src/components/app/map/MapStage.js | 91 +++++++++++++--------- .../components/app/map/RackEnergyFillContainer.js | 13 ++-- .../components/app/map/RackSpaceFillContainer.js | 12 +-- .../src/components/app/map/elements/HoverTile.js | 12 +-- .../src/components/app/map/elements/RackFillBar.js | 2 +- .../components/app/map/elements/TilePlusIcon.js | 26 +++---- .../app/map/layers/HoverLayerComponent.js | 67 +++++++--------- .../src/components/app/map/layers/MapLayer.js | 20 +++-- .../components/app/map/layers/MapLayerComponent.js | 26 ------- .../components/app/map/layers/ObjectHoverLayer.js | 35 ++++----- .../app/map/layers/ObjectHoverLayerComponent.js | 11 --- .../components/app/map/layers/RoomHoverLayer.js | 50 ++++++------ .../app/map/layers/RoomHoverLayerComponent.js | 6 -- opendc-web/opendc-web-ui/src/data/map.js | 37 --------- .../projects/[project]/topologies/[topology].js | 12 +-- opendc-web/opendc-web-ui/src/redux/actions/map.js | 83 -------------------- opendc-web/opendc-web-ui/src/redux/index.js | 3 +- .../src/redux/middleware/viewport-adjustment.js | 73 ----------------- .../opendc-web-ui/src/redux/reducers/index.js | 2 - opendc-web/opendc-web-ui/src/redux/reducers/map.js | 35 --------- opendc-web/opendc-web-ui/src/util/effect-ref.js | 41 ++++++++++ opendc-web/opendc-web-ui/yarn.lock | 14 ++-- 23 files changed, 215 insertions(+), 459 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayerComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayerComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/data/map.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/actions/map.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/map.js create mode 100644 opendc-web/opendc-web-ui/src/util/effect-ref.js diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js b/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js index 45799f70..4c3b2757 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js @@ -12,9 +12,6 @@ export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 export const TILE_PLUS_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 10 -export const SIDEBAR_WIDTH = 350 -export const VIEWPORT_PADDING = 50 - export const RACK_FILL_ICON_WIDTH = OBJECT_SIZE_IN_PIXELS / 3 export const RACK_FILL_ICON_OPACITY = 0.8 diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js index 684ddf28..5d19b3ad 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js @@ -1,64 +1,81 @@ -import React, { useEffect, useRef, useState } from 'react' +import React, { useRef, useState } from 'react' import { HotKeys } from 'react-hotkeys' import { Stage } from 'react-konva' -import { MAP_MOVE_PIXELS_PER_EVENT } from './MapConstants' -import { Provider, useDispatch, useStore } from 'react-redux' +import { MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_MOVE_PIXELS_PER_EVENT, MAP_SCALE_PER_EVENT } from './MapConstants' +import { Provider, useStore } from 'react-redux' import useResizeObserver from 'use-resize-observer' import { mapContainer } from './MapStage.module.scss' -import { useMapPosition } from '../../../data/map' -import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../redux/actions/map' import MapLayer from './layers/MapLayer' import RoomHoverLayer from './layers/RoomHoverLayer' import ObjectHoverLayer from './layers/ObjectHoverLayer' +import ScaleIndicator from './controls/ScaleIndicator' +import Toolbar from './controls/Toolbar' function MapStage() { const store = useStore() - const dispatch = useDispatch() + const { ref, width = 100, height = 100 } = useResizeObserver() + const stageRef = useRef(null) + const [[x, y], setPos] = useState([0, 0]) + const [scale, setScale] = useState(1) + + const clampScale = (target) => Math.min(Math.max(target, MAP_MIN_SCALE), MAP_MAX_SCALE) + const moveWithDelta = (deltaX, deltaY) => setPos(([x, y]) => [x + deltaX, y + deltaY]) + + const onZoom = (e) => { + e.evt.preventDefault() + + const stage = stageRef.current.getStage() + const oldScale = scale + + const pointer = stage.getPointerPosition() + const mousePointTo = { + x: (pointer.x - x) / oldScale, + y: (pointer.y - y) / oldScale, + } + + const newScale = clampScale(e.evt.deltaY > 0 ? oldScale * MAP_SCALE_PER_EVENT : oldScale / MAP_SCALE_PER_EVENT) + + setScale(newScale) + setPos([pointer.x - mousePointTo.x * newScale, pointer.y - mousePointTo.y * newScale]) + } + const onZoomButton = (zoomIn) => + setScale((scale) => clampScale(zoomIn ? scale * MAP_SCALE_PER_EVENT : scale / MAP_SCALE_PER_EVENT)) + const onDragEnd = (e) => setPos([e.target.x(), e.target.y()]) + const onExport = () => { + const download = document.createElement('a') + download.href = stageRef.current.getStage().toDataURL() + download.download = 'opendc-canvas-export-' + Date.now() + '.png' + download.click() + } - const stage = useRef(null) - const [pos, setPos] = useState([0, 0]) - const [x, y] = pos const handlers = { MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), } - const mapPosition = useMapPosition() - const { ref, width = 100, height = 100 } = useResizeObserver() - - const moveWithDelta = (deltaX, deltaY) => - dispatch(setMapPositionWithBoundsCheck(mapPosition.x + deltaX, mapPosition.y + deltaY)) - const updateMousePosition = () => { - if (!stage.current) { - return - } - - const mousePos = stage.current.getStage().getPointerPosition() - setPos([mousePos.x, mousePos.y]) - } - const updateScale = ({ evt }) => dispatch(zoomInOnPosition(evt.deltaY < 0, x, y)) - - useEffect(() => { - window['exportCanvasToImage'] = () => { - const download = document.createElement('a') - download.href = stage.current.getStage().toDataURL() - download.download = 'opendc-canvas-export-' + Date.now() + '.png' - download.click() - } - }, [stage]) - - useEffect(() => dispatch(setMapDimensions(width, height)), [width, height]) // eslint-disable-line react-hooks/exhaustive-deps return ( - + - - + + + + ) } diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js index 838aea5a..dbc26f14 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types' import { useSelector } from 'react-redux' import RackFillBar from '../../../components/app/map/elements/RackFillBar' -const RackSpaceFillContainer = (props) => { - const state = useSelector((state) => { +function RackSpaceFillContainer({ tileId, ...props }) { + const fillFraction = useSelector((state) => { let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[props.tileId].rack] + const rack = state.objects.rack[state.objects.tile[tileId].rack] const machineIds = rack.machines machineIds.forEach((machineId) => { if (machineId !== null) { @@ -22,12 +22,9 @@ const RackSpaceFillContainer = (props) => { } }) - return { - type: 'energy', - fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), - } + return Math.min(1, energyConsumptionTotal / rack.powerCapacityW) }) - return + return } RackSpaceFillContainer.propTypes = { diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js index 6791120e..7ca5c930 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js @@ -25,15 +25,9 @@ import PropTypes from 'prop-types' import { useSelector } from 'react-redux' import RackFillBar from '../../../components/app/map/elements/RackFillBar' -const RackSpaceFillContainer = (props) => { - const state = useSelector((state) => { - const machineIds = state.objects.rack[state.objects.tile[props.tileId].rack].machines - return { - type: 'space', - fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, - } - }) - return +function RackSpaceFillContainer({ tileId, ...props }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + return } RackSpaceFillContainer.propTypes = { diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js index 11bba0e1..0369bb79 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js @@ -4,10 +4,10 @@ import { Rect } from 'react-konva' import { ROOM_HOVER_INVALID_COLOR, ROOM_HOVER_VALID_COLOR } from '../../../../util/colors' import { TILE_SIZE_IN_PIXELS } from '../MapConstants' -const HoverTile = ({ pixelX, pixelY, isValid, scale, onClick }) => ( +const HoverTile = ({ x, y, isValid, scale = 1, onClick }) => ( ( ) HoverTile.propTypes = { - pixelX: PropTypes.number.isRequired, - pixelY: PropTypes.number.isRequired, + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, isValid: PropTypes.bool.isRequired, - scale: PropTypes.number.isRequired, + scale: PropTypes.number, onClick: PropTypes.func.isRequired, } diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js index 8c573a6f..aa284944 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js @@ -16,7 +16,7 @@ import { } from '../MapConstants' import ImageComponent from './ImageComponent' -const RackFillBar = ({ positionX, positionY, type, fillFraction }) => { +function RackFillBar({ positionX, positionY, type, fillFraction }) { const halfOfObjectBorderWidth = OBJECT_BORDER_WIDTH_IN_PIXELS / 2 const x = positionX * TILE_SIZE_IN_PIXELS + diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js index be3a00a8..186c2b3a 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js @@ -4,19 +4,19 @@ import { Group, Line } from 'react-konva' import { TILE_PLUS_COLOR } from '../../../../util/colors' import { TILE_PLUS_MARGIN_IN_PIXELS, TILE_PLUS_WIDTH_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' -const TilePlusIcon = ({ pixelX, pixelY, mapScale }) => { +function TilePlusIcon({ x, y, scale = 1 }) { const linePoints = [ [ - pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - pixelY + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - pixelY + TILE_SIZE_IN_PIXELS * mapScale - TILE_PLUS_MARGIN_IN_PIXELS * mapScale, + x + 0.5 * TILE_SIZE_IN_PIXELS * scale, + y + TILE_PLUS_MARGIN_IN_PIXELS * scale, + x + 0.5 * TILE_SIZE_IN_PIXELS * scale, + y + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, ], [ - pixelX + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - pixelX + TILE_SIZE_IN_PIXELS * mapScale - TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, + x + TILE_PLUS_MARGIN_IN_PIXELS * scale, + y + 0.5 * TILE_SIZE_IN_PIXELS * scale, + x + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, + y + 0.5 * TILE_SIZE_IN_PIXELS * scale, ], ] return ( @@ -27,7 +27,7 @@ const TilePlusIcon = ({ pixelX, pixelY, mapScale }) => { points={points} lineCap="round" stroke={TILE_PLUS_COLOR} - strokeWidth={TILE_PLUS_WIDTH_IN_PIXELS * mapScale} + strokeWidth={TILE_PLUS_WIDTH_IN_PIXELS * scale} listening={false} /> ))} @@ -36,9 +36,9 @@ const TilePlusIcon = ({ pixelX, pixelY, mapScale }) => { } TilePlusIcon.propTypes = { - pixelX: PropTypes.number, - pixelY: PropTypes.number, - mapScale: PropTypes.number, + x: PropTypes.number, + y: PropTypes.number, + scale: PropTypes.number, } export default TilePlusIcon diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js index a88a8b34..2b1060c0 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js @@ -1,61 +1,52 @@ import PropTypes from 'prop-types' -import React, { useEffect, useState } from 'react' -import { Layer } from 'react-konva' +import React, { useMemo, useState } from 'react' +import { Layer } from 'react-konva/lib/ReactKonva' import HoverTile from '../elements/HoverTile' import { TILE_SIZE_IN_PIXELS } from '../MapConstants' +import { useEffectRef } from '../../../../util/effect-ref' -function HoverLayerComponent({ mouseX, mouseY, mapPosition, mapScale, isEnabled, isValid, onClick, children }) { - const [pos, setPos] = useState([-1, -1]) - const [x, y] = pos - const [valid, setValid] = useState(false) +function HoverLayerComponent({ isEnabled, isValid, onClick, children }) { + const [[mouseWorldX, mouseWorldY], setPos] = useState([0, 0]) - useEffect(() => { - if (!isEnabled()) { + const layerRef = useEffectRef((layer) => { + if (!layer) { return } - const positionX = Math.floor((mouseX - mapPosition.x) / (mapScale * TILE_SIZE_IN_PIXELS)) - const positionY = Math.floor((mouseY - mapPosition.y) / (mapScale * TILE_SIZE_IN_PIXELS)) + const stage = layer.getStage() - if (positionX !== x || positionY !== y) { - setPos([positionX, positionY]) - setValid(isValid(positionX, positionY)) - } - }, [isEnabled, isValid, x, y, mouseX, mouseY, mapPosition, mapScale]) + // Transform used to convert mouse coordinates to world coordinates + const transform = stage.getAbsoluteTransform().copy() + transform.invert() + + stage.on('mousemove.hover', () => { + const { x, y } = transform.point(stage.getPointerPosition()) + setPos([x, y]) + }) + return () => stage.off('mousemove.hover') + }) + + const gridX = Math.floor(mouseWorldX / TILE_SIZE_IN_PIXELS) + const gridY = Math.floor(mouseWorldY / TILE_SIZE_IN_PIXELS) + const valid = useMemo(() => isEnabled && isValid(gridX, gridY), [isEnabled, isValid, gridX, gridY]) - if (!isEnabled()) { + if (!isEnabled) { return } - const pixelX = mapScale * x * TILE_SIZE_IN_PIXELS + mapPosition.x - const pixelY = mapScale * y * TILE_SIZE_IN_PIXELS + mapPosition.y + const x = gridX * TILE_SIZE_IN_PIXELS + const y = gridY * TILE_SIZE_IN_PIXELS return ( - - (valid ? onClick(x, y) : undefined)} - /> - {children - ? React.cloneElement(children, { - pixelX, - pixelY, - scale: mapScale, - }) - : undefined} + + (valid ? onClick(gridX, gridY) : undefined)} /> + {children ? React.cloneElement(children, { x, y, scale: 1 }) : undefined} ) } HoverLayerComponent.propTypes = { - mouseX: PropTypes.number.isRequired, - mouseY: PropTypes.number.isRequired, - mapPosition: PropTypes.object.isRequired, - mapScale: PropTypes.number.isRequired, - isEnabled: PropTypes.func.isRequired, + isEnabled: PropTypes.bool.isRequired, isValid: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired, children: PropTypes.node, diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js index badb9f68..c902532b 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js @@ -21,13 +21,21 @@ */ import React from 'react' -import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' -import { useMapPosition, useMapScale } from '../../../../data/map' +import { Group, Layer } from 'react-konva' +import Backdrop from '../elements/Backdrop' +import TopologyContainer from '../TopologyContainer' +import GridGroup from '../groups/GridGroup' -const MapLayer = (props) => { - const position = useMapPosition() - const scale = useMapScale() - return +function MapLayer() { + return ( + + + + + + + + ) } export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js deleted file mode 100644 index efe5b4e5..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayerComponent.js +++ /dev/null @@ -1,26 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group, Layer } from 'react-konva' -import Backdrop from '../elements/Backdrop' -import GridGroup from '../groups/GridGroup' -import TopologyContainer from '../TopologyContainer' - -const MapLayerComponent = ({ mapPosition, mapScale }) => ( - - - - - - - -) - -MapLayerComponent.propTypes = { - mapPosition: PropTypes.shape({ - x: PropTypes.number, - y: PropTypes.number, - }), - mapScale: PropTypes.number, -} - -export default MapLayerComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js index 9a087bd5..47d9c992 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js @@ -23,32 +23,31 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { addRackToTile } from '../../../../redux/actions/topology/room' -import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' import { findTileWithPosition } from '../../../../util/tile-calculations' +import HoverLayerComponent from './HoverLayerComponent' +import TilePlusIcon from '../elements/TilePlusIcon' -const ObjectHoverLayer = (props) => { - const state = useSelector((state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.inRackConstructionMode, - isValid: (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } +function ObjectHoverLayer() { + const isEnabled = useSelector((state) => state.construction.inRackConstructionMode) + const isValid = useSelector((state) => (x, y) => { + if (state.interactionLevel.mode !== 'ROOM') { + return false + } - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) - const tile = findTileWithPosition(tiles, x, y) + const currentRoom = state.objects.room[state.interactionLevel.roomId] + const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) + const tile = findTileWithPosition(tiles, x, y) - return !(tile === null || tile.rack) - }, - } + return !(tile === null || tile.rack) }) const dispatch = useDispatch() const onClick = (x, y) => dispatch(addRackToTile(x, y)) - return + return ( + + + + ) } export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayerComponent.js deleted file mode 100644 index 661fc255..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayerComponent.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import TilePlusIcon from '../elements/TilePlusIcon' -import HoverLayerComponent from './HoverLayerComponent' - -const ObjectHoverLayerComponent = (props) => ( - - - -) - -export default ObjectHoverLayerComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js index 87240813..59f83b2b 100644 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js @@ -23,45 +23,39 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' -import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' import { deriveValidNextTilePositions, findPositionInPositions, findPositionInRooms, } from '../../../../util/tile-calculations' +import HoverLayerComponent from './HoverLayerComponent' -const RoomHoverLayer = (props) => { +function RoomHoverLayer() { const dispatch = useDispatch() const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) + const isEnabled = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + const isValid = useSelector((state) => (x, y) => { + const newRoom = { ...state.objects.room[state.construction.currentRoomInConstruction] } + const oldRooms = Object.keys(state.objects.room) + .map((id) => ({ ...state.objects.room[id] })) + .filter( + (room) => + state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && + room._id !== state.construction.currentRoomInConstruction + ) - const state = useSelector((state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.currentRoomInConstruction !== '-1', - isValid: (x, y) => { - const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) - const oldRooms = Object.keys(state.objects.room) - .map((id) => Object.assign({}, state.objects.room[id])) - .filter( - (room) => - state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && - room._id !== state.construction.currentRoomInConstruction - ) - - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) - }) - if (newRoom.tiles.length === 0) { - return findPositionInRooms(oldRooms, x, y) === -1 - } - - const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) - return findPositionInPositions(validNextPositions, x, y) !== -1 - }, + ;[...oldRooms, newRoom].forEach((room) => { + room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) + }) + if (newRoom.tiles.length === 0) { + return findPositionInRooms(oldRooms, x, y) === -1 } + + const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) + return findPositionInPositions(validNextPositions, x, y) !== -1 }) - return + + return } export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayerComponent.js deleted file mode 100644 index 887e2891..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayerComponent.js +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react' -import HoverLayerComponent from './HoverLayerComponent' - -const RoomHoverLayerComponent = (props) => - -export default RoomHoverLayerComponent diff --git a/opendc-web/opendc-web-ui/src/data/map.js b/opendc-web/opendc-web-ui/src/data/map.js deleted file mode 100644 index 348a6664..00000000 --- a/opendc-web/opendc-web-ui/src/data/map.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import { useSelector } from 'react-redux' - -/** - * Return the map scale. - */ -export function useMapScale() { - return useSelector((state) => state.map.scale) -} - -/** - * Return the map position. - */ -export function useMapPosition() { - return useSelector((state) => state.map.position) -} diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index 786bed07..d79e8e7a 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -24,7 +24,7 @@ import { useRouter } from 'next/router' import { useProject } from '../../../../data/project' import { useDispatch, useSelector } from 'react-redux' import React, { useEffect, useState } from 'react' -import {configure, HotKeys} from 'react-hotkeys' +import { configure, HotKeys } from 'react-hotkeys' import { KeymapConfiguration } from '../../../../hotkeys' import Head from 'next/head' import MapStage from '../../../../components/app/map/MapStage' @@ -40,9 +40,7 @@ import { Spinner, Title, } from '@patternfly/react-core' -import { zoomInOnCenter } from '../../../../redux/actions/map' import Toolbar from '../../../../components/app/map/controls/Toolbar' -import { useMapScale } from '../../../../data/map' import ScaleIndicator from '../../../../components/app/map/controls/ScaleIndicator' import TopologySidebar from '../../../../components/app/sidebars/topology/TopologySidebar' import Collapse from '../../../../components/app/map/controls/Collapse' @@ -64,7 +62,6 @@ function Topology() { }, [projectId, topologyId, dispatch]) const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') - const scale = useMapScale() const interactionLevel = useSelector((state) => state.interactionLevel) const [isExpanded, setExpanded] = useState(true) @@ -72,7 +69,7 @@ function Topology() { // Make sure that holding down a key will generate repeated events configure({ - ignoreRepeatedEventsWhenKeyHeldDown: false + ignoreRepeatedEventsWhenKeyHeldDown: false, }) return ( @@ -95,11 +92,6 @@ function Topology() { - - dispatch(zoomInOnCenter(zoomIn))} - onExport={() => window['exportCanvasToImage']()} - /> setExpanded(true)} /> diff --git a/opendc-web/opendc-web-ui/src/redux/actions/map.js b/opendc-web/opendc-web-ui/src/redux/actions/map.js deleted file mode 100644 index aa14cacd..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/map.js +++ /dev/null @@ -1,83 +0,0 @@ -import { - MAP_MAX_SCALE, - MAP_MIN_SCALE, - MAP_SCALE_PER_EVENT, - MAP_SIZE_IN_PIXELS, -} from '../../components/app/map/MapConstants' - -export const SET_MAP_POSITION = 'SET_MAP_POSITION' -export const SET_MAP_DIMENSIONS = 'SET_MAP_DIMENSIONS' -export const SET_MAP_SCALE = 'SET_MAP_SCALE' - -export function setMapPosition(x, y) { - return { - type: SET_MAP_POSITION, - x, - y, - } -} - -export function setMapDimensions(width, height) { - return { - type: SET_MAP_DIMENSIONS, - width, - height, - } -} - -export function setMapScale(scale) { - return { - type: SET_MAP_SCALE, - scale, - } -} - -export function zoomInOnCenter(zoomIn) { - return (dispatch, getState) => { - const state = getState() - - dispatch(zoomInOnPosition(zoomIn, state.map.dimensions.width / 2, state.map.dimensions.height / 2)) - } -} - -export function zoomInOnPosition(zoomIn, x, y) { - return (dispatch, getState) => { - const state = getState() - - const centerPoint = { - x: x / state.map.scale - state.map.position.x / state.map.scale, - y: y / state.map.scale - state.map.position.y / state.map.scale, - } - const newScale = zoomIn ? state.map.scale * MAP_SCALE_PER_EVENT : state.map.scale / MAP_SCALE_PER_EVENT - const boundedScale = Math.min(Math.max(MAP_MIN_SCALE, newScale), MAP_MAX_SCALE) - - const newX = -(centerPoint.x - x / boundedScale) * boundedScale - const newY = -(centerPoint.y - y / boundedScale) * boundedScale - - dispatch(setMapPositionWithBoundsCheck(newX, newY)) - dispatch(setMapScale(boundedScale)) - } -} - -export function setMapPositionWithBoundsCheck(x, y) { - return (dispatch, getState) => { - const state = getState() - - const scaledMapSize = MAP_SIZE_IN_PIXELS * state.map.scale - - const updatedX = - x > 0 - ? 0 - : x < -scaledMapSize + state.map.dimensions.width - ? -scaledMapSize + state.map.dimensions.width - : x - const updatedY = - y > 0 - ? 0 - : y < -scaledMapSize + state.map.dimensions.height - ? -scaledMapSize + state.map.dimensions.height - : y - - dispatch(setMapPosition(updatedX, updatedY)) - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/index.js b/opendc-web/opendc-web-ui/src/redux/index.js index 3c7ad55f..fa0c9d23 100644 --- a/opendc-web/opendc-web-ui/src/redux/index.js +++ b/opendc-web/opendc-web-ui/src/redux/index.js @@ -5,7 +5,6 @@ import createSagaMiddleware from 'redux-saga' import thunk from 'redux-thunk' import rootReducer from './reducers' import rootSaga from './sagas' -import { viewportAdjustmentMiddleware } from './middleware/viewport-adjustment' import { createReduxEnhancer } from '@sentry/react' let store @@ -13,7 +12,7 @@ let store function initStore(initialState, ctx) { const sagaMiddleware = createSagaMiddleware({ context: ctx }) - const middlewares = [thunk, sagaMiddleware, viewportAdjustmentMiddleware] + const middlewares = [thunk, sagaMiddleware] if (process.env.NODE_ENV !== 'production') { middlewares.push(createLogger()) diff --git a/opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js b/opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js deleted file mode 100644 index c2fc5004..00000000 --- a/opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js +++ /dev/null @@ -1,73 +0,0 @@ -import { SET_MAP_DIMENSIONS, setMapPosition, setMapScale } from '../actions/map' -import { SET_CURRENT_TOPOLOGY } from '../actions/topology/building' -import { - MAP_MAX_SCALE, - MAP_MIN_SCALE, - SIDEBAR_WIDTH, - TILE_SIZE_IN_PIXELS, - VIEWPORT_PADDING, -} from '../../components/app/map/MapConstants' -import { calculateRoomListBounds } from '../../util/tile-calculations' - -export const viewportAdjustmentMiddleware = (store) => (next) => (action) => { - const state = store.getState() - - let topologyId = '-1' - let mapDimensions = {} - if (action.type === SET_CURRENT_TOPOLOGY && action.topologyId !== '-1') { - topologyId = action.topologyId - mapDimensions = state.map.dimensions - } else if (action.type === SET_MAP_DIMENSIONS && state.currentTopologyId !== '-1') { - topologyId = state.currentTopologyId - mapDimensions = { width: action.width, height: action.height } - } - - if (topologyId && topologyId !== '-1') { - const roomIds = state.objects.topology[topologyId].rooms - const rooms = roomIds.map((id) => Object.assign({}, state.objects.room[id])) - rooms.forEach((room) => (room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]))) - - let hasNoTiles = true - for (let i in rooms) { - if (rooms[i].tiles.length > 0) { - hasNoTiles = false - break - } - } - - if (!hasNoTiles) { - const viewportParams = calculateParametersToZoomInOnRooms(rooms, mapDimensions.width, mapDimensions.height) - store.dispatch(setMapPosition(viewportParams.newX, viewportParams.newY)) - store.dispatch(setMapScale(viewportParams.newScale)) - } - } - - next(action) -} - -function calculateParametersToZoomInOnRooms(rooms, mapWidth, mapHeight) { - const bounds = calculateRoomListBounds(rooms) - const newScale = calculateNewScale(bounds, mapWidth, mapHeight) - - // Coordinates of the center of the room, relative to the global origin of the map - const roomCenterCoordinates = { - x: bounds.center.x * TILE_SIZE_IN_PIXELS * newScale, - y: bounds.center.y * TILE_SIZE_IN_PIXELS * newScale, - } - - const newX = -roomCenterCoordinates.x + mapWidth / 2 - const newY = -roomCenterCoordinates.y + mapHeight / 2 - - return { newScale, newX, newY } -} - -function calculateNewScale(bounds, mapWidth, mapHeight) { - const width = bounds.max.x - bounds.min.x - const height = bounds.max.y - bounds.min.y - - const scaleX = (mapWidth - 2 * SIDEBAR_WIDTH) / (width * TILE_SIZE_IN_PIXELS + 2 * VIEWPORT_PADDING) - const scaleY = mapHeight / (height * TILE_SIZE_IN_PIXELS + 2 * VIEWPORT_PADDING) - const newScale = Math.min(scaleX, scaleY) - - return Math.min(Math.max(MAP_MIN_SCALE, newScale), MAP_MAX_SCALE) -} diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/index.js b/opendc-web/opendc-web-ui/src/redux/reducers/index.js index 1b17a206..2f1359d6 100644 --- a/opendc-web/opendc-web-ui/src/redux/reducers/index.js +++ b/opendc-web/opendc-web-ui/src/redux/reducers/index.js @@ -2,13 +2,11 @@ import { combineReducers } from 'redux' import { construction } from './construction-mode' import { currentTopologyId } from './current-ids' import { interactionLevel } from './interaction-level' -import { map } from './map' import { objects } from './objects' const rootReducer = combineReducers({ objects, construction, - map, currentTopologyId, interactionLevel, }) diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/map.js b/opendc-web/opendc-web-ui/src/redux/reducers/map.js deleted file mode 100644 index de712c15..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/map.js +++ /dev/null @@ -1,35 +0,0 @@ -import { combineReducers } from 'redux' -import { SET_MAP_DIMENSIONS, SET_MAP_POSITION, SET_MAP_SCALE } from '../actions/map' - -export function position(state = { x: 0, y: 0 }, action) { - switch (action.type) { - case SET_MAP_POSITION: - return { x: action.x, y: action.y } - default: - return state - } -} - -export function dimensions(state = { width: 600, height: 400 }, action) { - switch (action.type) { - case SET_MAP_DIMENSIONS: - return { width: action.width, height: action.height } - default: - return state - } -} - -export function scale(state = 1, action) { - switch (action.type) { - case SET_MAP_SCALE: - return action.scale - default: - return state - } -} - -export const map = combineReducers({ - position, - dimensions, - scale, -}) diff --git a/opendc-web/opendc-web-ui/src/util/effect-ref.js b/opendc-web/opendc-web-ui/src/util/effect-ref.js new file mode 100644 index 00000000..cda0324b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/util/effect-ref.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useCallback, useRef } from 'react' + +const noop = () => {} + +/** + * A hook that will invoke the specified callback when the reference returned by this function is initialized. + * The callback can return an optional clean up function. + */ +export function useEffectRef(callback) { + const disposeRef = useRef(noop) + return useCallback((element) => { + disposeRef.current() + disposeRef.current = noop + + if (element) { + disposeRef.current = callback(element) || noop + } + }, []) // eslint-disable-line react-hooks/exhaustive-deps +} diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index cd446e99..b0640a01 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -3337,12 +3337,12 @@ react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1: integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-konva@~17.0.2-0: - version "17.0.2-0" - resolved "https://registry.yarnpkg.com/react-konva/-/react-konva-17.0.2-0.tgz#35b1cf1b0ff3ed63b7de16aa6c0744e496391374" - integrity sha512-zT//biPf2UqqE4OIaivY2NfnnYgsEscSFacO9sbiUVrhtaP9mV8YgKx48CA4XjlgvfjjZqAxY6JTTmjJlsVYPw== + version "17.0.2-5" + resolved "https://registry.yarnpkg.com/react-konva/-/react-konva-17.0.2-5.tgz#e70b0acf323402de0a540f27b300fbe7ed151849" + integrity sha512-IyzdfqRDK8r1ulp/jbLPX18AuO+n5yNtL0+4T0QEUsgArRqIl/VRCG1imA5mYJBk0cBNC5+fWDHN+HWEW62ZEQ== dependencies: - react-reconciler "~0.26.1" - scheduler "^0.20.1" + react-reconciler "~0.26.2" + scheduler "^0.20.2" react-lifecycles-compat@^3.0.4: version "3.0.4" @@ -3358,7 +3358,7 @@ react-query@^3.18.1: broadcast-channel "^3.4.1" match-sorter "^6.0.2" -react-reconciler@~0.26.1: +react-reconciler@~0.26.2: version "0.26.2" resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.26.2.tgz#bbad0e2d1309423f76cf3c3309ac6c96e05e9d91" integrity sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q== @@ -3653,7 +3653,7 @@ sass@^1.32.12: dependencies: chokidar ">=3.0.0 <4.0.0" -scheduler@^0.20.1, scheduler@^0.20.2: +scheduler@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== -- cgit v1.2.3 From dc65123da856a09fe346ccd851cb4b78ad07ce5c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 11:48:18 +0200 Subject: perf(ui): Split transpiled modules into separate chunk This change updates the Next.js/Webpack configuration of the OpenDC frontend to split transpiled modules into a separate chunk during development. This prevents the duplication of the transpiled modules across the compiled files. --- opendc-web/opendc-web-ui/next.config.js | 14 + opendc-web/opendc-web-ui/yarn.lock | 1244 +++++++++++++++---------------- 2 files changed, 636 insertions(+), 622 deletions(-) diff --git a/opendc-web/opendc-web-ui/next.config.js b/opendc-web/opendc-web-ui/next.config.js index 9092adc4..1dfe4156 100644 --- a/opendc-web/opendc-web-ui/next.config.js +++ b/opendc-web/opendc-web-ui/next.config.js @@ -43,4 +43,18 @@ module.exports = withTM({ }, ] }, + webpack: (config, options) => { + if (options.dev) { + config.optimization.splitChunks = { + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name: 'transpiled-modules', + chunks: 'all', + }, + }, + } + } + return config + } }) diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index b0640a01..78122b5d 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -4,14 +4,14 @@ "@auth0/auth0-react@^1.5.0": version "1.5.0" - resolved "https://registry.yarnpkg.com/@auth0/auth0-react/-/auth0-react-1.5.0.tgz#f2dcfef1cab59f8555ade4e2b5ec13befce67395" + resolved "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-1.5.0.tgz" integrity sha512-LFJUd3V6aKCKxblJvrz3JIHzyBCz2X3ax5RdSjxZwGr5XxPwdhogeBWcyijnuB8moKD2ncl56OpOslbVGLIJ/w== dependencies: "@auth0/auth0-spa-js" "^1.15.0" "@auth0/auth0-spa-js@^1.15.0": version "1.15.0" - resolved "https://registry.yarnpkg.com/@auth0/auth0-spa-js/-/auth0-spa-js-1.15.0.tgz#9fa563b7b2e49dc4c6a465a0c240078322e80159" + resolved "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-1.15.0.tgz" integrity sha512-d/crchAbhncl9irIMuw1zNSZgX+id0U7mzASQr2htMJ73JCYaAvBSdGXL0WcYS4yBm1Xsx1JYm3b5tEZ5p/ncg== dependencies: abortcontroller-polyfill "^1.7.1" @@ -24,26 +24,26 @@ "@babel/code-frame@7.12.11": version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" "@babel/code-frame@^7.0.0": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz" integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: "@babel/highlight" "^7.12.13" "@babel/helper-validator-identifier@^7.14.0": version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz" integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz" integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== dependencies: "@babel/helper-validator-identifier" "^7.14.0" @@ -52,28 +52,28 @@ "@babel/runtime@7.12.5": version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz" integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.9.2": version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz" integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz" integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== dependencies: regenerator-runtime "^0.13.4" "@babel/types@7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz" integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== dependencies: esutils "^2.0.2" @@ -82,7 +82,7 @@ "@eslint/eslintrc@^0.4.1": version "0.4.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz" integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== dependencies: ajv "^6.12.4" @@ -97,40 +97,40 @@ "@fortawesome/fontawesome-common-types@^0.2.35": version "0.2.35" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz#01dd3d054da07a00b764d78748df20daf2b317e9" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz" integrity sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw== "@fortawesome/fontawesome-svg-core@^1.2.35": version "1.2.35" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz#85aea8c25645fcec88d35f2eb1045c38d3e65cff" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz" integrity sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg== dependencies: "@fortawesome/fontawesome-common-types" "^0.2.35" "@fortawesome/free-brands-svg-icons@^5.15.3": version "5.15.3" - resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz#bec2821d23b9c667be1d192a6c5bfb2667e588eb" + resolved "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz" integrity sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw== dependencies: "@fortawesome/fontawesome-common-types" "^0.2.35" "@fortawesome/free-solid-svg-icons@^5.15.3": version "5.15.3" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz#52eebe354f60dc77e0bde934ffc5c75ffd04f9d8" + resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz" integrity sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q== dependencies: "@fortawesome/fontawesome-common-types" "^0.2.35" "@fortawesome/react-fontawesome@^0.1.14": version "0.1.14" - resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz#bf28875c3935b69ce2dc620e1060b217a47f64ca" + resolved "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz" integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA== dependencies: prop-types "^15.7.2" "@hapi/accept@5.0.2": version "5.0.2" - resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.2.tgz#ab7043b037e68b722f93f376afb05e85c0699523" + resolved "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.2.tgz" integrity sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw== dependencies: "@hapi/boom" "9.x.x" @@ -138,34 +138,34 @@ "@hapi/boom@9.x.x": version "9.1.2" - resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.2.tgz#48bd41d67437164a2d636e3b5bc954f8c8dc5e38" + resolved "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.2.tgz" integrity sha512-uJEJtiNHzKw80JpngDGBCGAmWjBtzxDCz17A9NO2zCi8LLBlb5Frpq4pXwyN+2JQMod4pKz5BALwyneCgDg89Q== dependencies: "@hapi/hoek" "9.x.x" "@hapi/hoek@9.x.x": version "9.2.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" + resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz" integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== "@next/env@11.0.1": version "11.0.1" - resolved "https://registry.yarnpkg.com/@next/env/-/env-11.0.1.tgz#6dc96ac76f1663ab747340e907e8933f190cc8fd" + resolved "https://registry.npmjs.org/@next/env/-/env-11.0.1.tgz" integrity sha512-yZfKh2U6R9tEYyNUrs2V3SBvCMufkJ07xMH5uWy8wqcl5gAXoEw6A/1LDqwX3j7pUutF9d1ZxpdGDA3Uag+aQQ== "@next/eslint-plugin-next@10.2.3": version "10.2.3" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-10.2.3.tgz#5e62d0f029c435d0ba0222637b77611ff51f9e1a" + resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-10.2.3.tgz" integrity sha512-XkYm3cMxY2RZgbGyZLDN3vR9StFyiQVdwdS/EL6NxOerzt0To03/coY22p4jcFLtLYlQxAivJRicMTDNhRzPog== "@next/polyfill-module@11.0.1": version "11.0.1" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.0.1.tgz#ca2a110c1c44672cbcff6c2b983f0c0549d87291" + resolved "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-11.0.1.tgz" integrity sha512-Cjs7rrKCg4CF4Jhri8PCKlBXhszTfOQNl9AjzdNy4K5jXFyxyoSzuX2rK4IuoyE+yGp5A3XJCBEmOQ4xbUp9Mg== "@next/react-dev-overlay@11.0.1": version "11.0.1" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.0.1.tgz#3c481e83347255abd466dcf7e59ac8a79a0d7fd6" + resolved "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-11.0.1.tgz" integrity sha512-lvUjMVpLsgzADs9Q8wtC5LNqvfdN+M0BDMSrqr04EDWAyyX0vURHC9hkvLbyEYWyh+WW32pwjKBXdkMnJhoqMg== dependencies: "@babel/code-frame" "7.12.11" @@ -182,12 +182,12 @@ "@next/react-refresh-utils@11.0.1": version "11.0.1" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.0.1.tgz#a7509f22b6f70c13101a26573afd295295f1c020" + resolved "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-11.0.1.tgz" integrity sha512-K347DM6Z7gBSE+TfUaTTceWvbj0B6iNAsFZXbFZOlfg3uyz2sbKpzPYYFocCc27yjLaS8OfR8DEdS2mZXi8Saw== "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -195,12 +195,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.7" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz" integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -208,7 +208,7 @@ "@patternfly/react-core@^4.135.7": version "4.135.7" - resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.135.7.tgz#7292e4472ffcd519e3db1af782cb4d28024a6992" + resolved "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.135.7.tgz" integrity sha512-bxYLJ7TTXiEVHscfzqGbI+YFqwQMYWfG2Yknw/b/QqwN/bv5eCpioYOo35Wr4jvFAWkXvUUKp/DUpcSHrrFgTg== dependencies: "@patternfly/react-icons" "^4.11.2" @@ -221,17 +221,17 @@ "@patternfly/react-icons@^4.11.2": version "4.11.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.11.2.tgz#46f01197f779996954fd8033681644dd167cebcb" + resolved "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.11.2.tgz" integrity sha512-BPRWHAopry4a8aFd3VWaqO8h7QDA4NeYZ80YAY1iGqWeClIAmZlxs6jGCUhTC7iuYmjKruiVoDQwuwr/u+p6JQ== "@patternfly/react-styles@^4.11.2": version "4.11.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.11.2.tgz#3548d1c2a5b8a989f9edc6bd31165952e5f8bcb7" + resolved "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-4.11.2.tgz" integrity sha512-rUtw2tfniBiVIYEXPO8buisWFEHVR6dO5PH6C2MvbMk+VyUIS31TzOeNFyJs/gCurt7t1dEKjI9yNEGuAOjUPQ== "@patternfly/react-table@^4.29.8": version "4.29.8" - resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.29.8.tgz#9a8f1d1332c2f708427c81a693c2e90f9f52c75e" + resolved "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.29.8.tgz" integrity sha512-N6oKSE0sRHvkc9KWF03oTISfsc6G5NRBRCedi81hnpOSVo2515lGnA/r1ipR1DwM9qHYxmPNsrkPeoYtDQBOSQ== dependencies: "@patternfly/react-core" "^4.135.7" @@ -243,12 +243,12 @@ "@patternfly/react-tokens@^4.12.3": version "4.12.3" - resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.12.3.tgz#600b77e460e291032d649febf43002fe355a4468" + resolved "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-4.12.3.tgz" integrity sha512-RgXPEDdgx/p2VPQyCCxvv+ff9lmgYm4QDcI3c8iIwQjpPnJ5KF/bT6lPoAfeLFocRIZDnDSDcwSINbQwPQGp2A== "@redux-saga/core@^1.1.3": version "1.1.3" - resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4" + resolved "https://registry.npmjs.org/@redux-saga/core/-/core-1.1.3.tgz" integrity sha512-8tInBftak8TPzE6X13ABmEtRJGjtK17w7VUs7qV17S8hCO5S3+aUTWZ/DBsBJPdE8Z5jOPwYALyvofgq1Ws+kg== dependencies: "@babel/runtime" "^7.6.3" @@ -262,19 +262,19 @@ "@redux-saga/deferred@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.1.2.tgz#59937a0eba71fff289f1310233bc518117a71888" + resolved "https://registry.npmjs.org/@redux-saga/deferred/-/deferred-1.1.2.tgz" integrity sha512-908rDLHFN2UUzt2jb4uOzj6afpjgJe3MjICaUNO3bvkV/kN/cNeI9PMr8BsFXB/MR8WTAZQq/PlTq8Kww3TBSQ== "@redux-saga/delay-p@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.1.2.tgz#8f515f4b009b05b02a37a7c3d0ca9ddc157bb355" + resolved "https://registry.npmjs.org/@redux-saga/delay-p/-/delay-p-1.1.2.tgz" integrity sha512-ojc+1IoC6OP65Ts5+ZHbEYdrohmIw1j9P7HS9MOJezqMYtCDgpkoqB5enAAZrNtnbSL6gVCWPHaoaTY5KeO0/g== dependencies: "@redux-saga/symbols" "^1.1.2" "@redux-saga/is@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.1.2.tgz#ae6c8421f58fcba80faf7cadb7d65b303b97e58e" + resolved "https://registry.npmjs.org/@redux-saga/is/-/is-1.1.2.tgz" integrity sha512-OLbunKVsCVNTKEf2cH4TYyNbbPgvmZ52iaxBD4I1fTif4+MTXMa4/Z07L83zW/hTCXwpSZvXogqMqLfex2Tg6w== dependencies: "@redux-saga/symbols" "^1.1.2" @@ -282,22 +282,22 @@ "@redux-saga/symbols@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.1.2.tgz#216a672a487fc256872b8034835afc22a2d0595d" + resolved "https://registry.npmjs.org/@redux-saga/symbols/-/symbols-1.1.2.tgz" integrity sha512-EfdGnF423glv3uMwLsGAtE6bg+R9MdqlHEzExnfagXPrIiuxwr3bdiAwz3gi+PsrQ3yBlaBpfGLtDG8rf3LgQQ== "@redux-saga/types@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204" + resolved "https://registry.npmjs.org/@redux-saga/types/-/types-1.1.0.tgz" integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg== "@rushstack/eslint-patch@^1.0.6": version "1.0.6" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz#023d72a5c4531b4ce204528971700a78a85a0c50" + resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz" integrity sha512-Myxw//kzromB9yWgS8qYGuGVf91oBUUJpNvy5eM50sqvmKLbKjwLxohJnkWGTeeI9v9IBMtPLxz5Gc60FIfvCA== "@sentry/browser@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.30.0.tgz#c28f49d551db3172080caef9f18791a7fd39e3b3" + resolved "https://registry.npmjs.org/@sentry/browser/-/browser-5.30.0.tgz" integrity sha512-rOb58ZNVJWh1VuMuBG1mL9r54nZqKeaIlwSlvzJfc89vyfd7n6tQ1UXMN383QBz/MS5H5z44Hy5eE+7pCrYAfw== dependencies: "@sentry/core" "5.30.0" @@ -307,7 +307,7 @@ "@sentry/core@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + resolved "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz" integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== dependencies: "@sentry/hub" "5.30.0" @@ -318,7 +318,7 @@ "@sentry/hub@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz" integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== dependencies: "@sentry/types" "5.30.0" @@ -327,7 +327,7 @@ "@sentry/minimal@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz" integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== dependencies: "@sentry/hub" "5.30.0" @@ -336,7 +336,7 @@ "@sentry/react@^5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.30.0.tgz#320e05f766b6a26faefa8d76d1101fd50c69f541" + resolved "https://registry.npmjs.org/@sentry/react/-/react-5.30.0.tgz" integrity sha512-dvn4mqCgbeEuUXEGp5P9PaW5j4GWTFUSdx/yG8f9IxNZv5zM+7otjog9ukrubFZvlxVxD/PrIxK0MhadfFY/Dw== dependencies: "@sentry/browser" "5.30.0" @@ -348,7 +348,7 @@ "@sentry/tracing@^5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + resolved "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz" integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== dependencies: "@sentry/hub" "5.30.0" @@ -359,12 +359,12 @@ "@sentry/types@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + resolved "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz" integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== "@sentry/utils@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz" integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== dependencies: "@sentry/types" "5.30.0" @@ -372,31 +372,31 @@ "@types/d3-path@^1": version "1.0.9" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz" integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== "@types/d3-scale@^3.0.0": version "3.2.2" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.2.2.tgz#5e28d0b1c599328aaec6094219f10a2570be6d74" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.2.2.tgz" integrity sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ== dependencies: "@types/d3-time" "*" "@types/d3-shape@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.0.0.tgz#61aa065726f3c2641aedc59c3603475ab11aeb2f" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.0.0.tgz" integrity sha512-NLzD02m5PiD1KLEDjLN+MtqEcFYn4ZL9+Rqc9ZwARK1cpKZXd91zBETbe6wpBB6Ia0D0VZbpmbW3+BsGPGnCpA== dependencies: "@types/d3-path" "^1" "@types/d3-time@*": version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.0.0.tgz#831dd093db91f16b83ba980e194bb8e4bcef44d6" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.0.0.tgz" integrity sha512-Abz8bTzy8UWDeYs9pCa3D37i29EWDjNTjemdk0ei1ApYVNqulYlGUKip/jLOpogkPSsPz/GvZCYiC7MFlEk0iQ== "@types/hoist-non-react-statics@^3.3.0": version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== dependencies: "@types/react" "*" @@ -404,27 +404,27 @@ "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/node@*": version "15.0.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" + resolved "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz" integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== "@types/parse-json@^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prop-types@*": version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz" integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== "@types/react-redux@^7.1.16": version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" + resolved "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz" integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== dependencies: "@types/hoist-non-react-statics" "^3.3.0" @@ -434,7 +434,7 @@ "@types/react@*": version "17.0.5" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.5.tgz#3d887570c4489011f75a3fc8f965bf87d09a1bea" + resolved "https://registry.npmjs.org/@types/react/-/react-17.0.5.tgz" integrity sha512-bj4biDB9ZJmGAYTWSKJly6bMr4BLUiBrx9ujiJEoP9XIDY9CTaPGxE5QWN/1WjpPLzYF7/jRNnV2nNxNe970sw== dependencies: "@types/prop-types" "*" @@ -443,22 +443,22 @@ "@types/resize-observer-browser@^0.1.5": version "0.1.5" - resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz#36d897708172ac2380cd486da7a3daf1161c1e23" + resolved "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz" integrity sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ== "@types/scheduler@*": version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz" integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== "@types/uuid@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" + resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.0.0.tgz" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== "@typescript-eslint/parser@^4.20.0": version "4.26.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.0.tgz#31b6b732c9454f757b020dab9b6754112aa5eeaf" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.0.tgz" integrity sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg== dependencies: "@typescript-eslint/scope-manager" "4.26.0" @@ -468,7 +468,7 @@ "@typescript-eslint/scope-manager@4.26.0": version "4.26.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz#60d1a71df162404e954b9d1c6343ff3bee496194" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz" integrity sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg== dependencies: "@typescript-eslint/types" "4.26.0" @@ -476,12 +476,12 @@ "@typescript-eslint/types@4.26.0": version "4.26.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.0.tgz#7c6732c0414f0a69595f4f846ebe12616243d546" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.0.tgz" integrity sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A== "@typescript-eslint/typescript-estree@4.26.0": version "4.26.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz#aea17a40e62dc31c63d5b1bbe9a75783f2ce7109" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz" integrity sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg== dependencies: "@typescript-eslint/types" "4.26.0" @@ -494,7 +494,7 @@ "@typescript-eslint/visitor-keys@4.26.0": version "4.26.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz#26d2583169222815be4dcd1da4fe5459bc3bcc23" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz" integrity sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg== dependencies: "@typescript-eslint/types" "4.26.0" @@ -502,22 +502,22 @@ abortcontroller-polyfill@^1.7.1: version "1.7.3" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" + resolved "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz" integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== acorn-jsx@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== acorn@^7.4.0: version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -525,7 +525,7 @@ aggregate-error@^3.0.0: ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -535,7 +535,7 @@ ajv@^6.10.0, ajv@^6.12.4: ajv@^8.0.1: version "8.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz" integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== dependencies: fast-deep-equal "^3.1.1" @@ -545,43 +545,43 @@ ajv@^8.0.1: anser@1.4.9: version "1.4.9" - resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" + resolved "https://registry.npmjs.org/anser/-/anser-1.4.9.tgz" integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== ansi-colors@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-regex@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" anymatch@~3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" @@ -589,24 +589,24 @@ anymatch@~3.1.1: approximate-number@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/approximate-number/-/approximate-number-2.0.0.tgz#43c7fbfbbb0070a412131d65581f868b24d1eb29" + resolved "https://registry.npmjs.org/approximate-number/-/approximate-number-2.0.0.tgz" integrity sha1-Q8f7+7sAcKQSEx1lWB+GiyTR6yk= argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" array-filter@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" + resolved "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz" integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= array-includes@^3.1.2, array-includes@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz" integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== dependencies: call-bind "^1.0.2" @@ -617,12 +617,12 @@ array-includes@^3.1.2, array-includes@^3.1.3: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.flat@^1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz" integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== dependencies: call-bind "^1.0.0" @@ -631,7 +631,7 @@ array.prototype.flat@^1.2.4: array.prototype.flatmap@^1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz" integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== dependencies: call-bind "^1.0.0" @@ -641,7 +641,7 @@ array.prototype.flatmap@^1.2.4: asn1.js@^5.2.0: version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz" integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" @@ -651,7 +651,7 @@ asn1.js@^5.2.0: assert@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" + resolved "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz" integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== dependencies: es6-object-assign "^1.1.0" @@ -661,7 +661,7 @@ assert@2.0.0: assert@^1.1.1: version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: object-assign "^4.1.1" @@ -669,71 +669,71 @@ assert@^1.1.1: ast-types@0.13.2: version "0.13.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" + resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.2.tgz" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== attr-accept@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-1.1.3.tgz#48230c79f93790ef2775fcec4f0db0f5db41ca52" + resolved "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz" integrity sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ== dependencies: core-js "^2.5.0" available-typed-arrays@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz" integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== dependencies: array-filter "^1.0.0" babel-plugin-syntax-jsx@6.18.0: version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== big-integer@^1.6.16: version "1.6.48" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz" integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== big.js@^5.2.2: version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.0.0, bn.js@^5.1.1: version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -741,14 +741,14 @@ brace-expansion@^1.1.7: braces@^3.0.1, braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" broadcast-channel@^3.4.1: version "3.7.0" - resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937" + resolved "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz" integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg== dependencies: "@babel/runtime" "^7.7.2" @@ -762,19 +762,19 @@ broadcast-channel@^3.4.1: brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= browser-tabs-lock@^1.2.13: version "1.2.14" - resolved "https://registry.yarnpkg.com/browser-tabs-lock/-/browser-tabs-lock-1.2.14.tgz#f4ba30810d20199a1858c102da1f91e339250728" + resolved "https://registry.npmjs.org/browser-tabs-lock/-/browser-tabs-lock-1.2.14.tgz" integrity sha512-ssSpCRcvFe4vc098LDnrJOQDfZiG35KhQGB9hthTbwJk5mmUkePwhcMlW61NH3YuIE2Y9uGLqf9yxEBKbaDlaw== dependencies: lodash ">=4.17.21" browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" @@ -786,7 +786,7 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: browserify-cipher@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz" integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" @@ -795,7 +795,7 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz" integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" @@ -805,7 +805,7 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: bn.js "^5.0.0" @@ -813,7 +813,7 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: browserify-sign@^4.0.0: version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz" integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== dependencies: bn.js "^5.1.1" @@ -828,14 +828,14 @@ browserify-sign@^4.0.0: browserify-zlib@0.2.0, browserify-zlib@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz" integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: pako "~1.0.5" browserslist@4.16.6: version "4.16.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: caniuse-lite "^1.0.30001219" @@ -846,12 +846,12 @@ browserslist@4.16.6: buffer-xor@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@5.6.0: version "5.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz" integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== dependencies: base64-js "^1.0.2" @@ -859,7 +859,7 @@ buffer@5.6.0: buffer@^4.3.0: version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz" integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" @@ -868,17 +868,17 @@ buffer@^4.3.0: builtin-status-codes@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= bytes@3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" @@ -886,22 +886,22 @@ call-bind@^1.0.0, call-bind@^1.0.2: callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== caniuse-lite@^1.0.30001202: version "1.0.30001228" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: version "1.0.30001232" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz#2ebc8b6a77656fd772ab44a82a332a26a17e9527" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz" integrity sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg== chalk@2.4.2, chalk@^2.0.0: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -910,7 +910,7 @@ chalk@2.4.2, chalk@^2.0.0: chalk@4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz" integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== dependencies: ansi-styles "^4.1.0" @@ -918,7 +918,7 @@ chalk@4.0.0: chalk@^4.0.0, chalk@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz" integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" @@ -926,7 +926,7 @@ chalk@^4.0.0, chalk@^4.1.0: chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0": version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" @@ -941,12 +941,12 @@ chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0": ci-info@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" @@ -954,29 +954,29 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: classnames@2.2.6, classnames@~2.2.5: version "2.2.6" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== classnames@^2.2.5: version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-truncate@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== dependencies: slice-ansi "^3.0.0" @@ -984,98 +984,98 @@ cli-truncate@^2.1.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== commander@^6.0.0: version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== commondir@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= compare-versions@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + resolved "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz" integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== complex.js@^2.0.11: version "2.0.12" - resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.12.tgz#fa4df97d8928e5f7b6a86b35bdeecc3a3eda8a22" + resolved "https://registry.npmjs.org/complex.js/-/complex.js-2.0.12.tgz" integrity sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw== computed-styles@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/computed-styles/-/computed-styles-1.1.2.tgz#a7e732ba145149399ade70c2f94b353dd8ad629d" + resolved "https://registry.npmjs.org/computed-styles/-/computed-styles-1.1.2.tgz" integrity sha1-p+cyuhRRSTma3nDC+Us1PditYp0= concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= console-browserify@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== constants-browserify@1.0.0, constants-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= convert-source-map@1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" core-js@^2.5.0: version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.11.0: version "3.12.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz" integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== core-util-is@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cosmiconfig@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== dependencies: "@types/parse-json" "^4.0.0" @@ -1086,7 +1086,7 @@ cosmiconfig@^6.0.0: cosmiconfig@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz" integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== dependencies: "@types/parse-json" "^4.0.0" @@ -1097,7 +1097,7 @@ cosmiconfig@^7.0.0: create-ecdh@^4.0.0: version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz" integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" @@ -1105,7 +1105,7 @@ create-ecdh@^4.0.0: create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" @@ -1116,7 +1116,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" @@ -1128,7 +1128,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -1137,7 +1137,7 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: crypto-browserify@3.12.0, crypto-browserify@^3.11.0: version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz" integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" @@ -1154,65 +1154,65 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0: css-unit-converter@^1.1.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" + resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== css.escape@1.5.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= cssnano-preset-simple@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-2.0.0.tgz#b55e72cb970713f425560a0e141b0335249e2f96" + resolved "https://registry.npmjs.org/cssnano-preset-simple/-/cssnano-preset-simple-2.0.0.tgz" integrity sha512-HkufSLkaBJbKBFx/7aj5HmCK9Ni/JedRQm0mT2qBzMG/dEuJOLnMt2lK6K1rwOOyV4j9aSY+knbW9WoS7BYpzg== dependencies: caniuse-lite "^1.0.30001202" cssnano-simple@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-2.0.0.tgz#930d9dcd8ba105c5a62ce719cb00854da58b5c05" + resolved "https://registry.npmjs.org/cssnano-simple/-/cssnano-simple-2.0.0.tgz" integrity sha512-0G3TXaFxlh/szPEG/o3VcmCwl0N3E60XNb9YZZijew5eIs6fLjJuOPxQd9yEBaX2p/YfJtt49i4vYi38iH6/6w== dependencies: cssnano-preset-simple "^2.0.0" csstype@^3.0.2: version "3.0.8" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz" integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== d3-array@2, d3-array@^2.3.0: version "2.12.1" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== dependencies: internmap "^1.0.0" "d3-color@1 - 2": version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz" integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== "d3-format@1 - 2": version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz" integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== "d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz" integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== dependencies: d3-color "1 - 2" "d3-path@1 - 2": version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz" integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== d3-scale@^3.2.3: version "3.3.0" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz" integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== dependencies: d3-array "^2.3.0" @@ -1223,91 +1223,91 @@ d3-scale@^3.2.3: d3-shape@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz" integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== dependencies: d3-path "1 - 2" "d3-time-format@2 - 3": version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz" integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== dependencies: d3-time "1 - 2" "d3-time@1 - 2", d3-time@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz" integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== dependencies: d3-array "2" data-uri-to-buffer@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== debug@2, debug@^2.6.9: version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.2.7: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" decimal.js-light@^2.4.1: version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + resolved "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== decimal.js@^10.2.1: version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" + resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== dedent@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= deep-diff@^0.3.5: version "0.3.8" - resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" + resolved "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz" integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= deep-is@^0.1.3: version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= define-properties@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" depd@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz" integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" @@ -1315,12 +1315,12 @@ des.js@^1.0.0: detect-node@^2.0.4, detect-node@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== diffie-hellman@^5.0.0: version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz" integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" @@ -1329,50 +1329,50 @@ diffie-hellman@^5.0.0: dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-helpers@^3.4.0: version "3.4.0" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz" integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== dependencies: "@babel/runtime" "^7.1.2" domain-browser@4.19.0: version "4.19.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1" + resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-4.19.0.tgz" integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ== domain-browser@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== electron-to-chromium@^1.3.723: version "1.3.743" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz#fcec24d6d647cb84fd796b42caa1b4039a180894" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz" integrity sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg== elliptic@^6.5.3: version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: bn.js "^4.11.9" @@ -1385,31 +1385,31 @@ elliptic@^6.5.3: emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emojis-list@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= encoding@0.1.13: version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: iconv-lite "^0.6.2" end-of-stream@^1.1.0: version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enhanced-resolve@^5.7.0: version "5.8.2" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz" integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== dependencies: graceful-fs "^4.2.4" @@ -1417,21 +1417,21 @@ enhanced-resolve@^5.7.0: enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: version "1.18.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz" integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== dependencies: call-bind "^1.0.2" @@ -1453,7 +1453,7 @@ es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: es-abstract@^1.18.2: version "1.18.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz" integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== dependencies: call-bind "^1.0.2" @@ -1475,12 +1475,12 @@ es-abstract@^1.18.2: es-cookie@^1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/es-cookie/-/es-cookie-1.3.2.tgz#80e831597f72a25721701bdcb21d990319acd831" + resolved "https://registry.npmjs.org/es-cookie/-/es-cookie-1.3.2.tgz" integrity sha512-UTlYYhXGLOy05P/vKVT2Ui7WtC7NiRzGtJyAKKn32g5Gvcjn7KAClLPWlipCtxIus934dFg9o9jXiBL0nP+t9Q== es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -1489,32 +1489,32 @@ es-to-primitive@^1.2.1: es6-object-assign@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" + resolved "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz" integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-latex@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" + resolved "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz" integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-config-next@^10.2.3: version "10.2.3" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-10.2.3.tgz#042f01685a81699f1db82216b50ed891515a3510" + resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-10.2.3.tgz" integrity sha512-ubpv6YHqd3UFVPTz8z+Nih+H77rORLXrB7ZinIhrI7ZzZn5rvZ6V7AkcVrI8mVoYVyOo0qZ7vN8D2/Q7vxLMfg== dependencies: "@next/eslint-plugin-next" "10.2.3" @@ -1527,7 +1527,7 @@ eslint-config-next@^10.2.3: eslint-import-resolver-node@^0.3.4: version "0.3.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz" integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== dependencies: debug "^2.6.9" @@ -1535,7 +1535,7 @@ eslint-import-resolver-node@^0.3.4: eslint-module-utils@^2.6.1: version "2.6.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz" integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== dependencies: debug "^3.2.7" @@ -1543,7 +1543,7 @@ eslint-module-utils@^2.6.1: eslint-plugin-import@^2.22.1: version "2.23.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz" integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ== dependencies: array-includes "^3.1.3" @@ -1564,12 +1564,12 @@ eslint-plugin-import@^2.22.1: eslint-plugin-react-hooks@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz" integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== eslint-plugin-react@^7.23.1: version "7.24.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz#eadedfa351a6f36b490aa17f4fa9b14e842b9eb4" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz" integrity sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q== dependencies: array-includes "^3.1.3" @@ -1587,7 +1587,7 @@ eslint-plugin-react@^7.23.1: eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -1595,24 +1595,24 @@ eslint-scope@^5.1.1: eslint-utils@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint@^7.27.0: version "7.27.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.27.0.tgz#665a1506d8f95655c9274d84bd78f7166b07e9c7" + resolved "https://registry.npmjs.org/eslint/-/eslint-7.27.0.tgz" integrity sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA== dependencies: "@babel/code-frame" "7.12.11" @@ -1657,7 +1657,7 @@ eslint@^7.27.0: espree@^7.3.0, espree@^7.3.1: version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" @@ -1666,56 +1666,56 @@ espree@^7.3.0, espree@^7.3.1: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eventemitter3@^4.0.1: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" @@ -1723,7 +1723,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: execa@^4.0.3: version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" @@ -1738,17 +1738,17 @@ execa@^4.0.3: fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-equals@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.2.tgz#f4029b437d9e8184b807233bdbcd371e3bc73cf7" + resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.2.tgz" integrity sha512-ehHsR38w6sqy5E0QrWQxclb+zl3ulNsgCVWt1cMoZ6QBFgtkr4lKZWpQP1kfEFn6bWnm78pmiDGak+zUvQ2/DQ== fast-glob@^3.1.1: version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz" integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -1760,62 +1760,62 @@ fast-glob@^3.1.1: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-text-encoding@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" + resolved "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz" integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== fastq@^1.6.0: version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz" integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== dependencies: reusify "^1.0.4" figures@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" file-saver@^1.3.3: version "1.3.8" - resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.8.tgz#e68a30c7cb044e2fb362b428469feb291c2e09d8" + resolved "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz" integrity sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg== file-selector@^0.1.8: version "0.1.19" - resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.19.tgz#8ecc9d069a6f544f2e4a096b64a8052e70ec8abf" + resolved "https://registry.npmjs.org/file-selector/-/file-selector-0.1.19.tgz" integrity sha512-kCWw3+Aai8Uox+5tHCNgMFaUdgidxvMnLWO6fM5sZ0hA2wlHP5/DHGF0ECe84BiB95qdJbKNEJhWKVDvMN+JDQ== dependencies: tslib "^2.0.1" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" find-cache-dir@3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== dependencies: commondir "^1.0.1" @@ -1824,14 +1824,14 @@ find-cache-dir@3.3.1: find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= dependencies: locate-path "^2.0.0" find-up@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -1839,14 +1839,14 @@ find-up@^4.0.0: find-versions@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" + resolved "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz" integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== dependencies: semver-regex "^2.0.0" flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" @@ -1854,49 +1854,49 @@ flat-cache@^3.0.4: flatted@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== focus-trap@6.2.2: version "6.2.2" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.2.2.tgz#0e6f391415b0697c99da932702dedd13084fa131" + resolved "https://registry.npmjs.org/focus-trap/-/focus-trap-6.2.2.tgz" integrity sha512-qWovH9+LGoKqREvJaTCzJyO0hphQYGz+ap5Hc4NqXHNhZBdxCi5uBPPcaOUw66fHmzXLVwvETLvFgpwPILqKpg== dependencies: tabbable "^5.1.4" foreach@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= fraction.js@^4.0.12: version "4.0.13" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz" integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@~2.3.1: version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== functional-red-black-tree@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" @@ -1905,38 +1905,38 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: get-orientation@1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/get-orientation/-/get-orientation-1.1.2.tgz#20507928951814f8a91ded0a0e67b29dfab98947" + resolved "https://registry.npmjs.org/get-orientation/-/get-orientation-1.1.2.tgz" integrity sha512-/pViTfifW+gBbh/RnlFYHINvELT9Znt+SYyDKAUL6uV6By019AK/s+i9XP4jSwq7lwP38Fd8HVeTxym3+hkwmQ== dependencies: stream-parser "^0.3.1" get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-stream@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-to-regexp@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== glob@^7.1.3: version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" @@ -1948,21 +1948,21 @@ glob@^7.1.3: globals@^12.1.0: version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + resolved "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz" integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== dependencies: type-fest "^0.8.1" globals@^13.6.0: version "13.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + resolved "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz" integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== dependencies: type-fest "^0.20.2" globby@^11.0.3: version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" + resolved "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz" integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== dependencies: array-union "^2.1.0" @@ -1974,39 +1974,39 @@ globby@^11.0.3: graceful-fs@^4.1.2, graceful-fs@^4.2.4: version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== has-bigints@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hash-base@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz" integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: inherits "^2.0.4" @@ -2015,7 +2015,7 @@ hash-base@^3.0.0: hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" @@ -2023,12 +2023,12 @@ hash.js@^1.0.0, hash.js@^1.0.3: he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" @@ -2037,19 +2037,19 @@ hmac-drbg@^1.0.1: hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: react-is "^16.7.0" hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== http-errors@1.7.3: version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== dependencies: depd "~1.1.2" @@ -2060,17 +2060,17 @@ http-errors@1.7.3: https-browserify@1.0.0, https-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= human-signals@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== husky@~4.2.5: version "4.2.5" - resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.5.tgz#2b4f7622673a71579f901d9885ed448394b5fa36" + resolved "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz" integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ== dependencies: chalk "^4.0.0" @@ -2086,43 +2086,43 @@ husky@~4.2.5: iconv-lite@0.4.24: version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.6.2: version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz" integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" ieee754@^1.1.4: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.4: version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== image-size@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.0.tgz#58b31fe4743b1cec0a0ac26f5c914d3c5b2f0750" + resolved "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz" integrity sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw== dependencies: queue "6.0.2" import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -2130,17 +2130,17 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" @@ -2148,22 +2148,22 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inherits@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= inherits@2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= internal-slot@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== dependencies: get-intrinsic "^1.1.0" @@ -2172,82 +2172,82 @@ internal-slot@^1.0.3: internmap@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== is-arguments@^1.0.4: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz" integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== dependencies: call-bind "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-bigint@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz" integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz" integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== dependencies: call-bind "^1.0.2" is-callable@^1.1.4, is-callable@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-core-module@^2.2.0, is-core-module@^2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz" integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" is-date-object@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz" integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-function@^1.0.7: version "1.0.9" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c" + resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz" integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" is-nan@^1.2.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + resolved "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz" integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== dependencies: call-bind "^1.0.0" @@ -2255,27 +2255,27 @@ is-nan@^1.2.1: is-negative-zero@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number-object@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz" integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-regex@^1.1.2, is-regex@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz" integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== dependencies: call-bind "^1.0.2" @@ -2283,29 +2283,29 @@ is-regex@^1.1.2, is-regex@^1.1.3: is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= is-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== is-string@^1.0.5, is-string@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz" integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-typed-array@^1.1.3: version "1.1.5" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz" integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== dependencies: available-typed-arrays "^1.0.2" @@ -2316,27 +2316,27 @@ is-typed-array@^1.1.3: is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= javascript-natural-sort@^0.7.1: version "0.7.1" - resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" + resolved "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz" integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k= jest-worker@27.0.0-next.5: version "27.0.0-next.5" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.0-next.5.tgz" integrity sha512-mk0umAQ5lT+CaOJ+Qp01N6kz48sJG2kr2n1rX0koqKf6FIygQV0qLOdN9SCYID4IVeSigDOcPeGLozdMLYfb5g== dependencies: "@types/node" "*" @@ -2345,17 +2345,17 @@ jest-worker@27.0.0-next.5: js-sha3@0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -2363,39 +2363,39 @@ js-yaml@^3.13.1: json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= json5@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: minimist "^1.2.0" "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.2.0" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz" integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== dependencies: array-includes "^3.1.2" @@ -2403,12 +2403,12 @@ json5@^1.0.1: konva@~7.2.5: version "7.2.5" - resolved "https://registry.yarnpkg.com/konva/-/konva-7.2.5.tgz#9b4ac3a353e6be66e3e69123bf2a0cbc61efeb26" + resolved "https://registry.npmjs.org/konva/-/konva-7.2.5.tgz" integrity sha512-yk/li8rUF+09QNlOdkwbEId+QvfATMe/aMGVouWW1oFoUVTYWHsQuIAE6lWy11DK8mLJEJijkNAXC5K+NVlMew== levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -2416,12 +2416,12 @@ levn@^0.4.1: lines-and-columns@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= lint-staged@~10.2.2: version "10.2.13" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.13.tgz#b9c504683470edfc464b7d3fe3845a5a1efcd814" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.2.13.tgz" integrity sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA== dependencies: chalk "^4.1.0" @@ -2442,7 +2442,7 @@ lint-staged@~10.2.2: listr2@^2.6.0: version "2.6.2" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" + resolved "https://registry.npmjs.org/listr2/-/listr2-2.6.2.tgz" integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== dependencies: chalk "^4.1.0" @@ -2456,7 +2456,7 @@ listr2@^2.6.0: load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= dependencies: graceful-fs "^4.1.2" @@ -2466,7 +2466,7 @@ load-json-file@^4.0.0: loader-utils@1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== dependencies: big.js "^5.2.2" @@ -2475,7 +2475,7 @@ loader-utils@1.2.3: locate-path@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= dependencies: p-locate "^2.0.0" @@ -2483,49 +2483,49 @@ locate-path@^2.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" lodash.clonedeep@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= lodash.debounce@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.sortby@^4.7.0: version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= lodash.throttle@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + resolved "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= lodash.truncate@^4.4.2: version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= lodash@>=4.17.21, lodash@^4.17.13, lodash@^4.17.19: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -2533,7 +2533,7 @@ log-symbols@^4.0.0: log-update@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: ansi-escapes "^4.3.0" @@ -2543,28 +2543,28 @@ log-update@^4.0.0: loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" make-dir@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" match-sorter@^6.0.2: version "6.3.0" - resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.0.tgz#454a1b31ed218cddbce6231a0ecb5fdc549fed01" + resolved "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.0.tgz" integrity sha512-efYOf/wUpNb8FgNY+cOD2EIJI1S5I7YPKsw0LBp7wqPh5pmMS6i/wr3ZWwfwrAw1NvqTA2KUReVRWDX84lUcOQ== dependencies: "@babel/runtime" "^7.12.5" @@ -2572,7 +2572,7 @@ match-sorter@^6.0.2: mathjs@~7.6.0: version "7.6.0" - resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-7.6.0.tgz#f0b7579e0756b13422995d0c4f29bd17d65d4dcc" + resolved "https://registry.npmjs.org/mathjs/-/mathjs-7.6.0.tgz" integrity sha512-abywR28hUpKF4at5jE8Ys+Kigk40eKMT5mcBLD0/dtsqjfOLbtzd3WjlRqIopNo7oQ6FME51qph6lb8h/bhpUg== dependencies: complex.js "^2.0.11" @@ -2586,7 +2586,7 @@ mathjs@~7.6.0: md5.js@^1.3.4: version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz" integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" @@ -2595,17 +2595,17 @@ md5.js@^1.3.4: merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.2: version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: braces "^3.0.1" @@ -2613,12 +2613,12 @@ micromatch@^4.0.2: microseconds@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" + resolved "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz" integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== miller-rabin@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz" integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" @@ -2626,73 +2626,73 @@ miller-rabin@^4.0.0: mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= minimatch@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@^1.2.0: version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== ms@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== ms@^2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== nano-time@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" + resolved "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz" integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= dependencies: big-integer "^1.6.16" nanoid@^3.1.22: version "3.1.22" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz" integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== native-url@0.3.4: version "0.3.4" - resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" + resolved "https://registry.npmjs.org/native-url/-/native-url-0.3.4.tgz" integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA== dependencies: querystring "^0.2.0" natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= next-transpile-modules@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-8.0.0.tgz#56375cdc25ae5d23a834195f277fc2737b26cb97" + resolved "https://registry.npmjs.org/next-transpile-modules/-/next-transpile-modules-8.0.0.tgz" integrity sha512-Q2f2yB0zMJ8KJbIYAeZoIxG6cSfVk813zr6B5HzsLMBVcJ3FaF8lKr7WG66n0KlHCwjLSmf/6EkgI6QQVWHrDw== dependencies: enhanced-resolve "^5.7.0" @@ -2700,7 +2700,7 @@ next-transpile-modules@^8.0.0: next@^11.0.1: version "11.0.1" - resolved "https://registry.yarnpkg.com/next/-/next-11.0.1.tgz#b8e3914d153aaf7143cb98c09bcd3c8230eeb17a" + resolved "https://registry.npmjs.org/next/-/next-11.0.1.tgz" integrity sha512-yR7be7asNbvpVNpi6xxEg28wZ7Gqmj1nOt0sABH9qORmF3+pms2KZ7Cng33oK5nqPIzEEFJD0pp2PCe3/ueMIg== dependencies: "@babel/runtime" "7.12.5" @@ -2756,19 +2756,19 @@ next@^11.0.1: node-fetch@2.6.1: version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== node-html-parser@1.4.9: version "1.4.9" - resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-1.4.9.tgz#3c8f6cac46479fae5800725edb532e9ae8fd816c" + resolved "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.4.9.tgz" integrity sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw== dependencies: he "1.2.0" node-libs-browser@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz" integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== dependencies: assert "^1.1.1" @@ -2797,12 +2797,12 @@ node-libs-browser@^2.2.1: node-releases@^1.1.71: version "1.1.72" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz" integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== normalize-package-data@^2.3.2: version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -2812,34 +2812,34 @@ normalize-package-data@^2.3.2: normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalizr@^3.6.1: version "3.6.1" - resolved "https://registry.yarnpkg.com/normalizr/-/normalizr-3.6.1.tgz#d367ab840e031ff382141b8d81ce279292ff69fe" + resolved "https://registry.npmjs.org/normalizr/-/normalizr-3.6.1.tgz" integrity sha512-8iEmqXmPtll8PwbEFrbPoDxVw7MKnNvt3PZzR2Xvq9nggEEOgBlNICPXYzyZ4w4AkHUzCU998mdatER3n2VaMA== npm-run-path@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-inspect@^1.10.3, object-inspect@^1.9.0: version "1.10.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz" integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== object-is@^1.0.1: version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: call-bind "^1.0.2" @@ -2847,12 +2847,12 @@ object-is@^1.0.1: object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: call-bind "^1.0.0" @@ -2862,7 +2862,7 @@ object.assign@^4.1.2: object.entries@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz" integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== dependencies: call-bind "^1.0.2" @@ -2871,7 +2871,7 @@ object.entries@^1.1.4: object.fromentries@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz" integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ== dependencies: call-bind "^1.0.2" @@ -2881,7 +2881,7 @@ object.fromentries@^2.0.4: object.values@^1.1.3, object.values@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz" integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== dependencies: call-bind "^1.0.2" @@ -2890,31 +2890,31 @@ object.values@^1.1.3, object.values@^1.1.4: oblivious-set@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" + resolved "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz" integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^5.1.0: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" opencollective-postinstall@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" + resolved "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz" integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== optionator@^0.9.1: version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -2926,76 +2926,76 @@ optionator@^0.9.1: os-browserify@0.3.0, os-browserify@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= p-limit@3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-limit@^1.1.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-locate@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= dependencies: p-limit "^1.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-map@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-try@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: asn1.js "^5.2.0" @@ -3006,7 +3006,7 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= dependencies: error-ex "^1.3.1" @@ -3014,7 +3014,7 @@ parse-json@^4.0.0: parse-json@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -3024,54 +3024,54 @@ parse-json@^5.0.0: path-browserify@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz" integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== path-browserify@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" @@ -3082,72 +3082,72 @@ pbkdf2@^3.0.3: performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.2.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz" integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== pify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pkg-dir@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz" integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= dependencies: find-up "^2.1.0" pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" pkg-up@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz" integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= dependencies: find-up "^2.1.0" platform@1.3.6: version "1.3.6" - resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + resolved "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz" integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== please-upgrade-node@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz" integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" pnp-webpack-plugin@1.6.4: version "1.6.4" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz" integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== dependencies: ts-pnp "^1.1.6" popper.js@^1.16.0: version "1.16.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + resolved "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== postcss-value-parser@^3.3.0: version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss@8.2.13: version "8.2.13" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.13.tgz#dbe043e26e3c068e45113b1ed6375d2d37e2129f" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.13.tgz" integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ== dependencies: colorette "^1.2.2" @@ -3156,37 +3156,37 @@ postcss@8.2.13: prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier@~2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz" integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@0.11.10, process@^0.11.10: version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= progress@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-polyfill@^8.2.0: version "8.2.0" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.0.tgz#367394726da7561457aba2133c9ceefbd6267da0" + resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.0.tgz" integrity sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g== prop-types-extra@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" + resolved "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz" integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== dependencies: react-is "^16.3.2" @@ -3194,7 +3194,7 @@ prop-types-extra@^1.1.0: prop-types@15.7.2, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== dependencies: loose-envify "^1.4.0" @@ -3203,7 +3203,7 @@ prop-types@15.7.2, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, p public-encrypt@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" @@ -3215,7 +3215,7 @@ public-encrypt@^4.0.0: pump@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -3223,63 +3223,63 @@ pump@^3.0.0: punycode@1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@^1.2.4: version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== querystring-es3@0.2.1, querystring-es3@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= querystring@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= querystring@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz" integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== queue@6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" + resolved "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz" integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== dependencies: inherits "~2.0.3" raf@^3.4.0: version "3.4.1" - resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz" integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== dependencies: performance-now "^2.1.0" randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz" integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" @@ -3287,7 +3287,7 @@ randomfill@^1.0.3: raw-body@2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz" integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== dependencies: bytes "3.1.0" @@ -3297,7 +3297,7 @@ raw-body@2.4.1: react-dom@^17.0.2: version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: loose-envify "^1.1.0" @@ -3306,7 +3306,7 @@ react-dom@^17.0.2: react-dropzone@9.0.0: version "9.0.0" - resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-9.0.0.tgz#4f5223cdcb4d3bd8a66e3298c4041eb0c75c4634" + resolved "https://registry.npmjs.org/react-dropzone/-/react-dropzone-9.0.0.tgz" integrity sha512-wZ2o9B2qkdE3RumWhfyZT9swgJYJPeU5qHEcMU8weYpmLex1eeWX0CC32/Y0VutB+BBi2D+iePV/YZIiB4kZGw== dependencies: attr-accept "^1.1.3" @@ -3316,29 +3316,29 @@ react-dropzone@9.0.0: react-hotkeys@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0.tgz#a7719c7340cbba888b0e9184f806a9ec0ac2c53f" + resolved "https://registry.npmjs.org/react-hotkeys/-/react-hotkeys-2.0.0.tgz" integrity sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q== dependencies: prop-types "^15.6.1" react-is@16.10.2: version "16.10.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.10.2.tgz" integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA== react-is@17.0.2: version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-konva@~17.0.2-0: version "17.0.2-5" - resolved "https://registry.yarnpkg.com/react-konva/-/react-konva-17.0.2-5.tgz#e70b0acf323402de0a540f27b300fbe7ed151849" + resolved "https://registry.npmjs.org/react-konva/-/react-konva-17.0.2-5.tgz" integrity sha512-IyzdfqRDK8r1ulp/jbLPX18AuO+n5yNtL0+4T0QEUsgArRqIl/VRCG1imA5mYJBk0cBNC5+fWDHN+HWEW62ZEQ== dependencies: react-reconciler "~0.26.2" @@ -3346,12 +3346,12 @@ react-konva@~17.0.2-0: react-lifecycles-compat@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== react-query@^3.18.1: version "3.18.1" - resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.18.1.tgz#893b5475a7b4add099e007105317446f7a2cd310" + resolved "https://registry.npmjs.org/react-query/-/react-query-3.18.1.tgz" integrity sha512-17lv3pQxU9n+cB5acUv0/cxNTjo9q8G+RsedC6Ax4V9D8xEM7Q5xf9xAbCPdEhDrrnzPjTls9fQEABKRSi7OJA== dependencies: "@babel/runtime" "^7.5.5" @@ -3360,7 +3360,7 @@ react-query@^3.18.1: react-reconciler@~0.26.2: version "0.26.2" - resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.26.2.tgz#bbad0e2d1309423f76cf3c3309ac6c96e05e9d91" + resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz" integrity sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q== dependencies: loose-envify "^1.1.0" @@ -3369,7 +3369,7 @@ react-reconciler@~0.26.2: react-redux@~7.2.0: version "7.2.4" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" + resolved "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz" integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== dependencies: "@babel/runtime" "^7.12.1" @@ -3381,12 +3381,12 @@ react-redux@~7.2.0: react-refresh@0.8.3: version "0.8.3" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" + resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== react-resize-detector@^6.6.3: version "6.7.1" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-6.7.1.tgz#bbc8269ab814fa3b01f7d4e9c38805b877d08f18" + resolved "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.1.tgz" integrity sha512-54l8LWPBIRdtv0I/W/fMkmtgWX0mUIxKKAJKKimihNFueXtHuElDdXDyinQRmV7iku99AoyrSAhkCU/zjFG5+Q== dependencies: "@types/resize-observer-browser" "^0.1.5" @@ -3396,7 +3396,7 @@ react-resize-detector@^6.6.3: react-smooth@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91" + resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz" integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw== dependencies: fast-equals "^2.0.0" @@ -3405,7 +3405,7 @@ react-smooth@^2.0.0: react-transition-group@2.9.0: version "2.9.0" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== dependencies: dom-helpers "^3.4.0" @@ -3415,7 +3415,7 @@ react-transition-group@2.9.0: react@^17.0.2: version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz" integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" @@ -3423,7 +3423,7 @@ react@^17.0.2: read-pkg-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz" integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= dependencies: find-up "^2.0.0" @@ -3431,7 +3431,7 @@ read-pkg-up@^3.0.0: read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= dependencies: load-json-file "^4.0.0" @@ -3440,7 +3440,7 @@ read-pkg@^3.0.0: readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -3453,7 +3453,7 @@ readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6: readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" @@ -3462,21 +3462,21 @@ readable-stream@^3.5.0, readable-stream@^3.6.0: readdirp@~3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz" integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: picomatch "^2.2.1" recharts-scale@^0.4.4: version "0.4.5" - resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz" integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== dependencies: decimal.js-light "^2.4.1" recharts@~2.0.9: version "2.0.9" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.0.9.tgz#048068eb01383291104548388712026948275f70" + resolved "https://registry.npmjs.org/recharts/-/recharts-2.0.9.tgz" integrity sha512-JNsXE80PuF3hugUCE7JqDOMSvu5xQLxtjOaqFKKZI2pCJ1PVJzhwDv4TWk0nO4AvADbeWzYEHbg8C5Hcrh42UA== dependencies: "@types/d3-scale" "^3.0.0" @@ -3495,7 +3495,7 @@ recharts@~2.0.9: reduce-css-calc@^2.1.8: version "2.1.8" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + resolved "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz" integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== dependencies: css-unit-converter "^1.1.1" @@ -3503,33 +3503,33 @@ reduce-css-calc@^2.1.8: redux-logger@~3.0.6: version "3.0.6" - resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" + resolved "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz" integrity sha1-91VZZvMJjzyIYExEnPC69XeCdL8= dependencies: deep-diff "^0.3.5" redux-saga@~1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.1.3.tgz#9f3e6aebd3c994bbc0f6901a625f9a42b51d1112" + resolved "https://registry.npmjs.org/redux-saga/-/redux-saga-1.1.3.tgz" integrity sha512-RkSn/z0mwaSa5/xH/hQLo8gNf4tlvT18qXDNvedihLcfzh+jMchDgaariQoehCpgRltEm4zHKJyINEz6aqswTw== dependencies: "@redux-saga/core" "^1.1.3" redux-thunk@~2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== redux@^4.0.0, redux@^4.0.4: version "4.1.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" + resolved "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz" integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== dependencies: "@babel/runtime" "^7.9.2" redux@~4.0.5: version "4.0.5" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" + resolved "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== dependencies: loose-envify "^1.4.0" @@ -3537,12 +3537,12 @@ redux@~4.0.5: regenerator-runtime@^0.13.4: version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== regexp.prototype.flags@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== dependencies: call-bind "^1.0.2" @@ -3550,32 +3550,32 @@ regexp.prototype.flags@^1.3.1: regexpp@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== remove-accents@0.4.2: version "0.4.2" - resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" + resolved "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz" integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== resize-observer-polyfill@^1.5.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve@^1.10.0, resolve@^1.13.1, resolve@^1.20.0: version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: is-core-module "^2.2.0" @@ -3583,7 +3583,7 @@ resolve@^1.10.0, resolve@^1.13.1, resolve@^1.20.0: resolve@^2.0.0-next.3: version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz" integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== dependencies: is-core-module "^2.2.0" @@ -3591,7 +3591,7 @@ resolve@^2.0.0-next.3: restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -3599,19 +3599,19 @@ restore-cursor@^3.1.0: reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@3.0.2, rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" @@ -3619,43 +3619,43 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" rxjs@^6.6.2: version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sass@^1.32.12: version "1.32.12" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.12.tgz#a2a47ad0f1c168222db5206444a30c12457abb9f" + resolved "https://registry.npmjs.org/sass/-/sass-1.32.12.tgz" integrity sha512-zmXn03k3hN0KaiVTjohgkg98C3UowhL1/VSGdj4/VAAiMKGQOE80PFPxFP2Kyq0OUskPKcY5lImkhBKEHlypJA== dependencies: chokidar ">=3.0.0 <4.0.0" scheduler@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz" integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== dependencies: loose-envify "^1.1.0" @@ -3663,49 +3663,49 @@ scheduler@^0.20.2: seed-random@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" + resolved "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz" integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ= semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= semver-regex@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz" integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== "semver@2 || 3 || 4 || 5": version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^6.0.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.2.1, semver@^7.3.5: version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" setimmediate@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= setprototypeof@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -3713,24 +3713,24 @@ sha.js@^2.4.0, sha.js@^2.4.8: shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@1.7.2: version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -3739,17 +3739,17 @@ side-channel@^1.0.4: signal-exit@^3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: ansi-styles "^4.0.0" @@ -3758,7 +3758,7 @@ slice-ansi@^3.0.0: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -3767,24 +3767,24 @@ slice-ansi@^4.0.0: source-map@0.7.3: version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== source-map@0.8.0-beta.0: version "0.8.0-beta.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== dependencies: whatwg-url "^7.0.0" source-map@^0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== spdx-correct@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" @@ -3792,12 +3792,12 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" @@ -3805,29 +3805,29 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz" integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= stacktrace-parser@0.1.10: version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz" integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== dependencies: type-fest "^0.7.1" "statuses@>= 1.5.0 < 2": version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= stream-browserify@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz" integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== dependencies: inherits "~2.0.4" @@ -3835,7 +3835,7 @@ stream-browserify@3.0.0: stream-browserify@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz" integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" @@ -3843,7 +3843,7 @@ stream-browserify@^2.0.1: stream-http@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564" + resolved "https://registry.npmjs.org/stream-http/-/stream-http-3.1.1.tgz" integrity sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg== dependencies: builtin-status-codes "^3.0.0" @@ -3853,7 +3853,7 @@ stream-http@3.1.1: stream-http@^2.7.2: version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz" integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" @@ -3864,24 +3864,24 @@ stream-http@^2.7.2: stream-parser@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" + resolved "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz" integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M= dependencies: debug "2" string-argv@0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== string-hash@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" + resolved "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" @@ -3890,7 +3890,7 @@ string-width@^4.1.0, string-width@^4.2.0: string.prototype.matchall@^4.0.5: version "4.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz" integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q== dependencies: call-bind "^1.0.2" @@ -3904,7 +3904,7 @@ string.prototype.matchall@^4.0.5: string.prototype.trimend@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz" integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: call-bind "^1.0.2" @@ -3912,7 +3912,7 @@ string.prototype.trimend@^1.0.4: string.prototype.trimstart@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz" integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: call-bind "^1.0.2" @@ -3920,21 +3920,21 @@ string.prototype.trimstart@^1.0.4: string_decoder@1.3.0, string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" @@ -3943,29 +3943,29 @@ stringify-object@^3.3.0: strip-ansi@6.0.0, strip-ansi@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== dependencies: ansi-regex "^5.0.0" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== styled-jsx@3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.3.2.tgz#2474601a26670a6049fb4d3f94bd91695b3ce018" + resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-3.3.2.tgz" integrity sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g== dependencies: "@babel/types" "7.8.3" @@ -3979,38 +3979,38 @@ styled-jsx@3.3.2: stylis-rule-sheet@0.0.10: version "0.0.10" - resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" + resolved "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz" integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== stylis@3.5.4: version "3.5.4" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" + resolved "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" svgsaver@~0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/svgsaver/-/svgsaver-0.9.0.tgz#93d5dbb3f840953b8df0a14a942f4cc8d552335e" + resolved "https://registry.npmjs.org/svgsaver/-/svgsaver-0.9.0.tgz" integrity sha1-k9Xbs/hAlTuN8KFKlC9MyNVSM14= dependencies: computed-styles "^1.1.2" @@ -4018,17 +4018,17 @@ svgsaver@~0.9.0: symbol-observable@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== tabbable@^5.1.4: version "5.2.0" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.0.tgz#4fba60991d8bb89d06e5d9455c92b453acf88fb2" + resolved "https://registry.npmjs.org/tabbable/-/tabbable-5.2.0.tgz" integrity sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg== table@^6.0.9: version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + resolved "https://registry.npmjs.org/table/-/table-6.7.1.tgz" integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== dependencies: ajv "^8.0.1" @@ -4040,75 +4040,75 @@ table@^6.0.9: tapable@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= through@^2.3.8: version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timers-browserify@2.0.12, timers-browserify@^2.0.4: version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz" integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" tiny-emitter@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + resolved "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== tippy.js@5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-5.1.2.tgz#5ac91233c59ab482ef5988cffe6e08bd26528e66" + resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-5.1.2.tgz" integrity sha512-Qtrv2wqbRbaKMUb6bWWBQWPayvcDKNrGlvihxtsyowhT7RLGEh1STWuy6EMXC6QLkfKPB2MLnf8W2mzql9VDAw== dependencies: popper.js "^1.16.0" to-arraybuffer@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= to-fast-properties@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toidentifier@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== tr46@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= dependencies: punycode "^2.1.0" ts-pnp@^1.1.6: version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + resolved "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tsconfig-paths@^3.9.0: version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz" integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== dependencies: "@types/json5" "^0.0.29" @@ -4118,90 +4118,90 @@ tsconfig-paths@^3.9.0: tslib@1.13.0: version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" tty-browserify@0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= tty-browserify@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz" integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.7.1: version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== type-fest@^0.8.1: version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== typed-function@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.0.0.tgz#15ab3825845138a8b1113bd89e60cd6a435739e8" + resolved "https://registry.npmjs.org/typed-function/-/typed-function-2.0.0.tgz" integrity sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA== typescript-compare@^0.0.2: version "0.0.2" - resolved "https://registry.yarnpkg.com/typescript-compare/-/typescript-compare-0.0.2.tgz#7ee40a400a406c2ea0a7e551efd3309021d5f425" + resolved "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz" integrity sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA== dependencies: typescript-logic "^0.0.0" typescript-logic@^0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/typescript-logic/-/typescript-logic-0.0.0.tgz#66ebd82a2548f2b444a43667bec120b496890196" + resolved "https://registry.npmjs.org/typescript-logic/-/typescript-logic-0.0.0.tgz" integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== typescript-tuple@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/typescript-tuple/-/typescript-tuple-2.2.1.tgz#7d9813fb4b355f69ac55032e0363e8bb0f04dad2" + resolved "https://registry.npmjs.org/typescript-tuple/-/typescript-tuple-2.2.1.tgz" integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q== dependencies: typescript-compare "^0.0.2" unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz" integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== dependencies: function-bind "^1.1.1" @@ -4211,12 +4211,12 @@ unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: unfetch@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + resolved "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz" integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== unload@2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" + resolved "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz" integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== dependencies: "@babel/runtime" "^7.6.2" @@ -4224,19 +4224,19 @@ unload@2.2.0: unpipe@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" url@^0.11.0: version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= dependencies: punycode "1.3.2" @@ -4244,33 +4244,33 @@ url@^0.11.0: use-resize-observer@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/use-resize-observer/-/use-resize-observer-7.0.0.tgz#15f0efbd5a4e08a8cc51901f21a89ba836f2116e" + resolved "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-7.0.0.tgz" integrity sha512-+RjrQsk/mL8aKy4TGBDiPkUv6whyeoGDMIZYk0gOGHOlnrsjImC+jG6lfAFcBCKAG9epGRL419adhDNdkDCQkA== dependencies: resize-observer-polyfill "^1.5.1" use-subscription@1.5.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" + resolved "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz" integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA== dependencies: object-assign "^4.1.1" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util@0.10.3: version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + resolved "https://registry.npmjs.org/util/-/util-0.10.3.tgz" integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" util@0.12.3, util@^0.12.0: version "0.12.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" + resolved "https://registry.npmjs.org/util/-/util-0.12.3.tgz" integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== dependencies: inherits "^2.0.3" @@ -4282,19 +4282,19 @@ util@0.12.3, util@^0.12.0: util@^0.11.0: version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + resolved "https://registry.npmjs.org/util/-/util-0.11.1.tgz" integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== dependencies: inherits "2.0.3" uuid@8.2.0: version "8.2.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.2.0.tgz#cb10dd6b118e2dada7d0cd9730ba7417c93d920e" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz" integrity sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q== uuidv4@~6.1.1: version "6.1.1" - resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-6.1.1.tgz#6565b4f2be7d6f841c14106f420fdb701eae5c81" + resolved "https://registry.npmjs.org/uuidv4/-/uuidv4-6.1.1.tgz" integrity sha512-ZplGb1SHFMVH3l7PUQl2Uwo+FpJQV6IPOoU+MjjbqrNYQolqbGwv+/sn9F+AGMsMOgGz3r9JN3ztGUi0VzMxmw== dependencies: "@types/uuid" "8.0.0" @@ -4302,12 +4302,12 @@ uuidv4@~6.1.1: v8-compile-cache@^2.0.3: version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -4315,19 +4315,19 @@ validate-npm-package-license@^3.0.1: vm-browserify@1.1.2, vm-browserify@^1.0.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== warning@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== dependencies: loose-envify "^1.0.0" watchpack@2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz" integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw== dependencies: glob-to-regexp "^0.4.1" @@ -4335,12 +4335,12 @@ watchpack@2.1.1: webidl-conversions@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== whatwg-url@^7.0.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz" integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== dependencies: lodash.sortby "^4.7.0" @@ -4349,7 +4349,7 @@ whatwg-url@^7.0.0: which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -4360,12 +4360,12 @@ which-boxed-primitive@^1.0.2: which-pm-runs@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz" integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= which-typed-array@^1.1.2: version "1.1.4" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz" integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== dependencies: available-typed-arrays "^1.0.2" @@ -4378,19 +4378,19 @@ which-typed-array@^1.1.2: which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" word-wrap@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" @@ -4399,25 +4399,25 @@ wrap-ansi@^6.2.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^1.10.0, yaml@^1.7.2: version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -- cgit v1.2.3 From 54d07120191eb81de91a49cdebf619cfecce2666 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 14:45:25 +0200 Subject: refactor(ui): Encode state in topology actions This change updates the OpenDC frontend to reduce its reliance of global state during the execution of actions. Actions that modify the topology now require parameters to be passed via the action constructor instead of relying on the global interactionLevel state. --- .../app/sidebars/topology/TopologySidebar.js | 18 +++--- .../sidebars/topology/building/BuildingSidebar.js | 8 +++ .../topology/building/BuildingSidebarComponent.js | 8 --- .../building/NewRoomConstructionComponent.js | 2 +- .../building/NewRoomConstructionContainer.js | 2 +- .../app/sidebars/topology/machine/DeleteMachine.js | 8 ++- .../sidebars/topology/machine/MachineSidebar.js | 49 ++++++++++++++++ .../topology/machine/MachineSidebarComponent.js | 44 -------------- .../topology/machine/MachineSidebarContainer.js | 37 ------------ .../sidebars/topology/machine/UnitAddContainer.js | 5 +- .../sidebars/topology/machine/UnitListComponent.js | 4 +- .../sidebars/topology/machine/UnitListContainer.js | 15 ++--- .../sidebars/topology/machine/UnitTabsComponent.js | 23 +++++--- .../app/sidebars/topology/rack/AddPrefab.js | 44 ++++++++++++++ .../sidebars/topology/rack/AddPrefabComponent.js | 16 ------ .../sidebars/topology/rack/AddPrefabContainer.js | 33 ----------- .../sidebars/topology/rack/DeleteRackContainer.js | 9 ++- .../app/sidebars/topology/rack/MachineComponent.js | 2 +- .../sidebars/topology/rack/MachineListContainer.js | 2 +- .../sidebars/topology/rack/RackNameContainer.js | 4 +- .../app/sidebars/topology/rack/RackSidebar.js | 58 +++++++++++++++++++ .../sidebars/topology/rack/RackSidebar.module.scss | 12 ++++ .../sidebars/topology/rack/RackSidebarComponent.js | 58 ------------------- .../topology/rack/RackSidebarComponent.module.scss | 12 ---- .../sidebars/topology/rack/RackSidebarContainer.js | 32 ----------- .../sidebars/topology/room/DeleteRoomContainer.js | 9 ++- .../sidebars/topology/room/EditRoomContainer.js | 9 ++- .../topology/room/RackConstructionComponent.js | 2 +- .../topology/room/RackConstructionContainer.js | 2 +- .../app/sidebars/topology/room/RoomName.js | 4 +- .../app/sidebars/topology/room/RoomSidebar.js | 43 ++++++++++++++ .../sidebars/topology/room/RoomSidebarComponent.js | 43 -------------- .../sidebars/topology/room/RoomSidebarContainer.js | 32 ----------- .../projects/[project]/topologies/[topology].js | 2 - .../opendc-web-ui/src/redux/actions/prefabs.js | 3 +- .../src/redux/actions/topology/building.js | 11 ++-- .../src/redux/actions/topology/machine.js | 10 +++- .../src/redux/actions/topology/rack.js | 9 ++- .../src/redux/actions/topology/room.js | 6 +- .../opendc-web-ui/src/redux/sagas/prefabs.js | 7 +-- .../opendc-web-ui/src/redux/sagas/topology.js | 67 ++++++++-------------- opendc-web/opendc-web-ui/src/util/sidebar-space.js | 2 - opendc-web/opendc-web-ui/src/util/state-utils.js | 6 -- .../opendc-web-ui/src/util/tile-calculations.js | 4 +- 44 files changed, 337 insertions(+), 439 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefab.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/util/sidebar-space.js delete mode 100644 opendc-web/opendc-web-ui/src/util/state-utils.js diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js index c4a880b1..564f4030 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types' import React from 'react' import { InteractionLevel } from '../../../../shapes' -import BuildingSidebarComponent from './building/BuildingSidebarComponent' +import BuildingSidebar from './building/BuildingSidebar' import { Button, DrawerActions, @@ -16,9 +16,9 @@ import { AngleLeftIcon } from '@patternfly/react-icons' import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../redux/actions/interaction-level' import { backButton } from './TopologySidebar.module.scss' -import RoomSidebarContainer from './room/RoomSidebarContainer' -import RackSidebarContainer from './rack/RackSidebarContainer' -import MachineSidebarContainer from './machine/MachineSidebarContainer' +import RoomSidebar from './room/RoomSidebar' +import RackSidebar from './rack/RackSidebar' +import MachineSidebar from './machine/MachineSidebar' const name = { BUILDING: 'Building', @@ -27,21 +27,21 @@ const name = { MACHINE: 'Machine', } -const TopologySidebar = ({ interactionLevel, onClose }) => { +function TopologySidebar({ interactionLevel, onClose }) { let sidebarContent switch (interactionLevel.mode) { case 'BUILDING': - sidebarContent = + sidebarContent = break case 'ROOM': - sidebarContent = + sidebarContent = break case 'RACK': - sidebarContent = + sidebarContent = break case 'MACHINE': - sidebarContent = + sidebarContent = break default: sidebarContent = 'Missing Content' diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js new file mode 100644 index 00000000..5fcd46be --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js @@ -0,0 +1,8 @@ +import React from 'react' +import NewRoomConstructionContainer from './NewRoomConstructionContainer' + +function BuildingSidebar() { + return +} + +export default BuildingSidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js deleted file mode 100644 index 6c2556d3..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import NewRoomConstructionContainer from './NewRoomConstructionContainer' - -const BuildingSidebarComponent = () => { - return -} - -export default BuildingSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js index 656b2515..9fc85d0c 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js @@ -4,7 +4,7 @@ import { Button, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from '@pat import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' -const NewRoomConstructionComponent = ({ onStart, onFinish, onCancel, currentRoomInConstruction }) => { +function NewRoomConstructionComponent({ onStart, onFinish, onCancel, currentRoomInConstruction }) { if (currentRoomInConstruction === '-1') { return ( + ) +} + +AddPrefab.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default AddPrefab diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js deleted file mode 100644 index c8543134..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabComponent.js +++ /dev/null @@ -1,16 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { SaveIcon } from '@patternfly/react-icons' -import { Button } from '@patternfly/react-core' - -const AddPrefabComponent = ({ onClick }) => ( - -) - -AddPrefabComponent.propTypes = { - onClick: PropTypes.func, -} - -export default AddPrefabComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js deleted file mode 100644 index d3d9aaf5..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefabContainer.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch } from 'react-redux' -import { addPrefab } from '../../../../../redux/actions/prefabs' -import AddPrefabComponent from './AddPrefabComponent' - -const AddPrefabContainer = (props) => { - const dispatch = useDispatch() - return dispatch(addPrefab('name'))} /> -} - -export default AddPrefabContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js index 47959f03..f0dc7b6b 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js @@ -20,6 +20,7 @@ * SOFTWARE. */ +import PropTypes from 'prop-types' import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' @@ -27,12 +28,12 @@ import { deleteRack } from '../../../../../redux/actions/topology/rack' import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' import { Button } from '@patternfly/react-core' -const DeleteRackContainer = () => { +function DeleteRackContainer({ tileId }) { const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) const callback = (isConfirmed) => { if (isConfirmed) { - dispatch(deleteRack()) + dispatch(deleteRack(tileId)) } setVisible(false) } @@ -51,4 +52,8 @@ const DeleteRackContainer = () => { ) } +DeleteRackContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js index 1617b3bf..97141711 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js @@ -19,7 +19,7 @@ UnitIcon.propTypes = { type: PropTypes.string, } -const MachineComponent = ({ machine, onClick }) => { +function MachineComponent({ machine, onClick }) { const hasNoUnits = machine.cpus.length + machine.gpus.length + machine.memories.length + machine.storages.length === 0 diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js index 54e6db0a..3ed0ffd0 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js @@ -43,7 +43,7 @@ function MachineListContainer({ tileId, ...props }) { dispatch(addMachine(index))} + onAdd={(index) => dispatch(addMachine(rack._id, index))} onSelect={(index) => dispatch(goFromRackToMachine(index))} /> ) diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js index 11529b55..11db6420 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js @@ -5,11 +5,11 @@ import NameComponent from '../NameComponent' import { editRackName } from '../../../../../redux/actions/topology/rack' const RackNameContainer = ({ tileId }) => { - const rackName = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack].name) + const { name: rackName, _id } = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) const dispatch = useDispatch() const callback = (name) => { if (name) { - dispatch(editRackName(name)) + dispatch(editRackName(_id, name)) } } return diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js new file mode 100644 index 00000000..3c9f152a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js @@ -0,0 +1,58 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { machineListContainer, sidebarContainer } from './RackSidebar.module.scss' +import RackNameContainer from './RackNameContainer' +import AddPrefab from './AddPrefab' +import DeleteRackContainer from './DeleteRackContainer' +import MachineListContainer from './MachineListContainer' +import { + Skeleton, + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' +import { useSelector } from 'react-redux' + +function RackSidebar({ tileId }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + + return ( +
    + + Details + + + Name + + + + + Capacity + + {rack?.capacity ?? } + + + Actions + + + + Slots + +
    + +
    +
    + ) +} + +RackSidebar.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss new file mode 100644 index 00000000..6f258aec --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss @@ -0,0 +1,12 @@ +.sidebarContainer { + display: flex; + height: 100%; + max-height: 100%; + flex-direction: column; +} + +.machineListContainer { + flex: 1; + overflow-y: scroll; + margin-top: 10px; +} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js deleted file mode 100644 index dd5117f7..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.js +++ /dev/null @@ -1,58 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { machineListContainer, sidebarContainer } from './RackSidebarComponent.module.scss' -import RackNameContainer from './RackNameContainer' -import AddPrefabContainer from './AddPrefabContainer' -import DeleteRackContainer from './DeleteRackContainer' -import MachineListContainer from './MachineListContainer' -import { - Skeleton, - TextContent, - TextList, - TextListItem, - TextListItemVariants, - TextListVariants, - Title, -} from '@patternfly/react-core' -import { useSelector } from 'react-redux' - -function RackSidebarComponent({ tileId }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) - - return ( -
    - - Details - - - Name - - - - - Capacity - - {rack?.capacity ?? } - - - Actions - - - - Slots - -
    - -
    -
    - ) -} - -RackSidebarComponent.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default RackSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss deleted file mode 100644 index 6f258aec..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarComponent.module.scss +++ /dev/null @@ -1,12 +0,0 @@ -.sidebarContainer { - display: flex; - height: 100%; - max-height: 100%; - flex-direction: column; -} - -.machineListContainer { - flex: 1; - overflow-y: scroll; - margin-top: 10px; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js deleted file mode 100644 index 2b31413d..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebarContainer.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useSelector } from 'react-redux' -import RackSidebarComponent from './RackSidebarComponent' - -const RackSidebarContainer = (props) => { - const tileId = useSelector((state) => state.interactionLevel.tileId) - return -} - -export default RackSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js index 284c4d53..19a782a6 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js @@ -20,6 +20,7 @@ * SOFTWARE. */ +import PropTypes from 'prop-types' import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' @@ -27,12 +28,12 @@ import { deleteRoom } from '../../../../../redux/actions/topology/room' import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' import { Button } from '@patternfly/react-core' -const DeleteRoomContainer = () => { +function DeleteRoomContainer({ roomId }) { const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) const callback = (isConfirmed) => { if (isConfirmed) { - dispatch(deleteRoom()) + dispatch(deleteRoom(roomId)) } setVisible(false) } @@ -51,4 +52,8 @@ const DeleteRoomContainer = () => { ) } +DeleteRoomContainer.propTypes = { + roomId: PropTypes.string.isRequired, +} + export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js index 6db2bfb6..96c077cb 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js @@ -20,6 +20,7 @@ * SOFTWARE. */ +import PropTypes from 'prop-types' import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { finishRoomEdit, startRoomEdit } from '../../../../../redux/actions/topology/building' @@ -27,12 +28,12 @@ import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon' import { Button } from '@patternfly/react-core' -const EditRoomContainer = () => { +function EditRoomContainer({ roomId }) { const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) const dispatch = useDispatch() - const onEdit = () => dispatch(startRoomEdit()) + const onEdit = () => dispatch(startRoomEdit(roomId)) const onFinish = () => dispatch(finishRoomEdit()) return isEditing ? ( @@ -53,4 +54,8 @@ const EditRoomContainer = () => { ) } +EditRoomContainer.propTypes = { + roomId: PropTypes.string.isRequired, +} + export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js index 8aebe969..13432689 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js @@ -7,7 +7,7 @@ import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon' const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, isEditingRoom }) => { if (inRackConstructionMode) { return ( - ) diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js index 38af447a..b9ab6610 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js @@ -25,7 +25,7 @@ import { useDispatch, useSelector } from 'react-redux' import { startRackConstruction, stopRackConstruction } from '../../../../../redux/actions/topology/room' import RackConstructionComponent from './RackConstructionComponent' -const RackConstructionContainer = (props) => { +function RackConstructionContainer(props) { const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js index d7b006a6..11909189 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js @@ -27,11 +27,11 @@ import NameComponent from '../../../../../components/app/sidebars/topology/NameC import { editRoomName } from '../../../../../redux/actions/topology/room' function RoomName({ roomId }) { - const roomName = useSelector((state) => state.objects.room[roomId].name) + const { name: roomName, _id } = useSelector((state) => state.objects.room[roomId]) const dispatch = useDispatch() const callback = (name) => { if (name) { - dispatch(editRoomName(name)) + dispatch(editRoomName(_id, name)) } } return diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js new file mode 100644 index 00000000..6ad489e0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js @@ -0,0 +1,43 @@ +import PropTypes from 'prop-types' +import React from 'react' +import RoomName from './RoomName' +import RackConstructionContainer from './RackConstructionContainer' +import EditRoomContainer from './EditRoomContainer' +import DeleteRoomContainer from './DeleteRoomContainer' +import { + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' + +const RoomSidebar = ({ roomId }) => { + return ( + + Details + + + Name + + + + + + Construction + + + + + ) +} + +RoomSidebar.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default RoomSidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js deleted file mode 100644 index fac58c51..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarComponent.js +++ /dev/null @@ -1,43 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import RoomName from './RoomName' -import RackConstructionContainer from './RackConstructionContainer' -import EditRoomContainer from './EditRoomContainer' -import DeleteRoomContainer from './DeleteRoomContainer' -import { - TextContent, - TextList, - TextListItem, - TextListItemVariants, - TextListVariants, - Title, -} from '@patternfly/react-core' - -const RoomSidebarComponent = ({ roomId }) => { - return ( - - Details - - - Name - - - - - - Construction - - - - - ) -} - -RoomSidebarComponent.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default RoomSidebarComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js deleted file mode 100644 index 2076b00e..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebarContainer.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useSelector } from 'react-redux' -import RoomSidebarComponent from './RoomSidebarComponent' - -const RoomSidebarContainer = (props) => { - const roomId = useSelector((state) => state.interactionLevel.roomId) - return -} - -export default RoomSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index d79e8e7a..139c2979 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -40,8 +40,6 @@ import { Spinner, Title, } from '@patternfly/react-core' -import Toolbar from '../../../../components/app/map/controls/Toolbar' -import ScaleIndicator from '../../../../components/app/map/controls/ScaleIndicator' import TopologySidebar from '../../../../components/app/sidebars/topology/TopologySidebar' import Collapse from '../../../../components/app/map/controls/Collapse' diff --git a/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js b/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js index c112feed..0ef7795f 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js @@ -3,10 +3,11 @@ export const DELETE_PREFAB = 'DELETE_PREFAB' export const DELETE_PREFAB_SUCCEEDED = 'DELETE_PREFAB_SUCCEEDED' export const OPEN_PREFAB_SUCCEEDED = 'OPEN_PREFAB_SUCCEEDED' -export function addPrefab(name) { +export function addPrefab(name, tileId) { return { type: ADD_PREFAB, name, + tileId, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js index f1a7d569..49425318 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js @@ -55,13 +55,10 @@ export function cancelNewRoomConstructionSucceeded() { } } -export function startRoomEdit() { - return (dispatch, getState) => { - const { interactionLevel } = getState() - dispatch({ - type: START_ROOM_EDIT, - roomId: interactionLevel.roomId, - }) +export function startRoomEdit(roomId) { + return { + type: START_ROOM_EDIT, + roomId: roomId, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js index 17ccce5d..170b7648 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js @@ -2,23 +2,27 @@ export const DELETE_MACHINE = 'DELETE_MACHINE' export const ADD_UNIT = 'ADD_UNIT' export const DELETE_UNIT = 'DELETE_UNIT' -export function deleteMachine() { +export function deleteMachine(rackId, position) { return { type: DELETE_MACHINE, + rackId, + position, } } -export function addUnit(unitType, id) { +export function addUnit(machineId, unitType, id) { return { type: ADD_UNIT, + machineId, unitType, id, } } -export function deleteUnit(unitType, index) { +export function deleteUnit(machineId, unitType, index) { return { type: DELETE_UNIT, + machineId, unitType, index, } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js index b117402e..228e3ae9 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js @@ -2,22 +2,25 @@ export const EDIT_RACK_NAME = 'EDIT_RACK_NAME' export const DELETE_RACK = 'DELETE_RACK' export const ADD_MACHINE = 'ADD_MACHINE' -export function editRackName(name) { +export function editRackName(rackId, name) { return { type: EDIT_RACK_NAME, name, + rackId, } } -export function deleteRack() { +export function deleteRack(tileId) { return { type: DELETE_RACK, + tileId, } } -export function addMachine(position) { +export function addMachine(rackId, position) { return { type: ADD_MACHINE, position, + rackId, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js index 80ef7c5e..e584af89 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js @@ -6,10 +6,11 @@ export const START_RACK_CONSTRUCTION = 'START_RACK_CONSTRUCTION' export const STOP_RACK_CONSTRUCTION = 'STOP_RACK_CONSTRUCTION' export const ADD_RACK_TO_TILE = 'ADD_RACK_TO_TILE' -export function editRoomName(name) { +export function editRoomName(roomId, name) { return { type: EDIT_ROOM_NAME, name, + roomId, } } @@ -41,8 +42,9 @@ export function addRackToTile(positionX, positionY) { } } -export function deleteRoom() { +export function deleteRoom(roomId) { return { type: DELETE_ROOM, + roomId, } } diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js b/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js index 91b03bf6..f717d878 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js @@ -4,14 +4,13 @@ import { addPrefab } from '../../api/prefabs' import { Rack } from '../../util/topology-schema' import { denormalize } from 'normalizr' -export function* onAddPrefab(action) { +export function* onAddPrefab({ name, tileId }) { try { - const interactionLevel = yield select((state) => state.interactionLevel) const objects = yield select((state) => state.objects) - const rack = objects.rack[objects.tile[interactionLevel.tileId].rack] + const rack = objects.rack[objects.tile[tileId].rack] const prefabRack = denormalize(rack, Rack, objects) const auth = yield getContext('auth') - const prefab = yield call(() => addPrefab(auth, { name: action.name, rack: prefabRack })) + const prefab = yield call(() => addPrefab(auth, { name, rack: prefabRack })) yield put(addToStore('prefab', prefab)) } catch (error) { console.error(error) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index 333c1485..f3742b78 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -37,10 +37,8 @@ export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = fa } } -export function* onAddTopology(action) { +export function* onAddTopology({ projectId, duplicateId, name }) { try { - const { projectId, duplicateId, name } = action - let topologyToBeCreated if (duplicateId) { topologyToBeCreated = yield denormalizeTopology(duplicateId) @@ -119,21 +117,19 @@ export function* onDeleteTile(action) { } } -export function* onEditRoomName(action) { +export function* onEditRoomName({ roomId, name }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const roomId = yield select((state) => state.interactionLevel.roomId) - yield put(addPropToStoreObject('room', roomId, { name: action.name })) + yield put(addPropToStoreObject('room', roomId, { name })) yield updateTopologyOnServer(topologyId) } catch (error) { console.error(error) } } -export function* onDeleteRoom() { +export function* onDeleteRoom({ roomId }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const roomId = yield select((state) => state.interactionLevel.roomId) yield put(goDownOneInteractionLevel()) yield put(removeIdFromStoreObjectListProp('topology', topologyId, 'rooms', roomId)) yield updateTopologyOnServer(topologyId) @@ -142,21 +138,19 @@ export function* onDeleteRoom() { } } -export function* onEditRackName(action) { +export function* onEditRackName({ rackId, name }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const rackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rack) - yield put(addPropToStoreObject('rack', rackId, { name: action.name })) + yield put(addPropToStoreObject('rack', rackId, { name })) yield updateTopologyOnServer(topologyId) } catch (error) { console.error(error) } } -export function* onDeleteRack() { +export function* onDeleteRack({ tileId }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const tileId = yield select((state) => state.interactionLevel.tileId) yield put(goDownOneInteractionLevel()) yield put(addPropToStoreObject('tile', tileId, { rack: undefined })) yield updateTopologyOnServer(topologyId) @@ -165,35 +159,34 @@ export function* onDeleteRack() { } } -export function* onAddRackToTile(action) { +export function* onAddRackToTile({ tileId }) { try { const topologyId = yield select((state) => state.currentTopologyId) const rack = { _id: uuid(), name: 'Rack', - tileId: action.tileId, + tileId, capacity: DEFAULT_RACK_SLOT_CAPACITY, powerCapacityW: DEFAULT_RACK_POWER_CAPACITY, machines: [], } yield put(addToStore('rack', rack)) - yield put(addPropToStoreObject('tile', action.tileId, { rack: rack._id })) + yield put(addPropToStoreObject('tile', tileId, { rack: rack._id })) yield updateTopologyOnServer(topologyId) } catch (error) { console.error(error) } } -export function* onAddMachine(action) { +export function* onAddMachine({ rackId, position }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const rackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rack) const rack = yield select((state) => state.objects.rack[rackId]) const machine = { _id: uuid(), rackId, - position: action.position, + position, cpus: [], gpus: [], memories: [], @@ -209,15 +202,13 @@ export function* onAddMachine(action) { } } -export function* onDeleteMachine() { +export function* onDeleteMachine({ rackId, position }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const tileId = yield select((state) => state.interactionLevel.tileId) - const position = yield select((state) => state.interactionLevel.position) - const rack = yield select((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const rack = yield select((state) => state.objects.rack[rackId]) yield put(goDownOneInteractionLevel()) yield put( - addPropToStoreObject('rack', rack._id, { machines: rack.machines.filter((_, idx) => idx !== position - 1) }) + addPropToStoreObject('rack', rackId, { machines: rack.machines.filter((_, idx) => idx !== position - 1) }) ) yield updateTopologyOnServer(topologyId) } catch (error) { @@ -232,23 +223,19 @@ const unitMapping = { storage: 'storages', } -export function* onAddUnit(action) { +export function* onAddUnit({ machineId, unitType, id }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const tileId = yield select((state) => state.interactionLevel.tileId) - const position = yield select((state) => state.interactionLevel.position) - const machine = yield select( - (state) => state.objects.machine[state.objects.rack[state.objects.tile[tileId].rack].machines[position - 1]] - ) + const machine = yield select((state) => state.objects.machine[machineId]) - if (machine[unitMapping[action.unitType]].length >= MAX_NUM_UNITS_PER_MACHINE) { + if (machine[unitMapping[unitType]].length >= MAX_NUM_UNITS_PER_MACHINE) { return } - const units = [...machine[unitMapping[action.unitType]], action.id] + const units = [...machine[unitMapping[unitType]], id] yield put( addPropToStoreObject('machine', machine._id, { - [unitMapping[action.unitType]]: units, + [unitMapping[unitType]]: units, }) ) yield updateTopologyOnServer(topologyId) @@ -257,20 +244,16 @@ export function* onAddUnit(action) { } } -export function* onDeleteUnit(action) { +export function* onDeleteUnit({ machineId, unitType, index }) { try { const topologyId = yield select((state) => state.currentTopologyId) - const tileId = yield select((state) => state.interactionLevel.tileId) - const position = yield select((state) => state.interactionLevel.position) - const machine = yield select( - (state) => state.objects.machine[state.objects.rack[state.objects.tile[tileId].rack].machines[position - 1]] - ) - const unitIds = machine[unitMapping[action.unitType]].slice() - unitIds.splice(action.index, 1) + const machine = yield select((state) => state.objects.machine[machineId]) + const unitIds = machine[unitMapping[unitType]].slice() + unitIds.splice(index, 1) yield put( addPropToStoreObject('machine', machine._id, { - [unitMapping[action.unitType]]: unitIds, + [unitMapping[unitType]]: unitIds, }) ) yield updateTopologyOnServer(topologyId) diff --git a/opendc-web/opendc-web-ui/src/util/sidebar-space.js b/opendc-web/opendc-web-ui/src/util/sidebar-space.js deleted file mode 100644 index 005c40f3..00000000 --- a/opendc-web/opendc-web-ui/src/util/sidebar-space.js +++ /dev/null @@ -1,2 +0,0 @@ -export const isCollapsible = (router) => - router.asPath.indexOf('portfolios') === -1 && router.asPath.indexOf('scenarios') === -1 diff --git a/opendc-web/opendc-web-ui/src/util/state-utils.js b/opendc-web/opendc-web-ui/src/util/state-utils.js deleted file mode 100644 index e5b695c3..00000000 --- a/opendc-web/opendc-web-ui/src/util/state-utils.js +++ /dev/null @@ -1,6 +0,0 @@ -export const getState = (dispatch) => - new Promise((resolve) => { - dispatch((dispatch, getState) => { - resolve(getState()) - }) - }) diff --git a/opendc-web/opendc-web-ui/src/util/tile-calculations.js b/opendc-web/opendc-web-ui/src/util/tile-calculations.js index 764ae6ac..374ca48c 100644 --- a/opendc-web/opendc-web-ui/src/util/tile-calculations.js +++ b/opendc-web/opendc-web-ui/src/util/tile-calculations.js @@ -18,8 +18,8 @@ function getWallSegments(tiles) { } let doInsert = true - for (let tileIndex in tiles) { - if (tiles[tileIndex].positionX === x + dX && tiles[tileIndex].positionY === y + dY) { + for (const tile of tiles) { + if (tile.positionX === x + dX && tile.positionY === y + dY) { doInsert = false break } -- cgit v1.2.3 From 5e5ab63b280eb446db4090733cd3ad2e97d02018 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 15:47:23 +0200 Subject: refactor(ui): Restructure components per page This change updates the source structure of the OpenDC frontend to follow the page structure. --- opendc-web/opendc-web-ui/src/api/topologies.js | 1 + .../opendc-web-ui/src/components/AppNavigation.js | 2 +- opendc-web/opendc-web-ui/src/components/AppPage.js | 3 +- .../src/components/app/map/GrayContainer.js | 34 ----- .../src/components/app/map/MapConstants.js | 25 ---- .../src/components/app/map/MapStage.js | 83 ----------- .../src/components/app/map/MapStage.module.scss | 31 ---- .../src/components/app/map/RackContainer.js | 37 ----- .../components/app/map/RackEnergyFillContainer.js | 34 ----- .../components/app/map/RackSpaceFillContainer.js | 37 ----- .../src/components/app/map/RoomContainer.js | 45 ------ .../src/components/app/map/TileContainer.js | 46 ------ .../src/components/app/map/TopologyContainer.js | 35 ----- .../src/components/app/map/WallContainer.js | 39 ----- .../src/components/app/map/controls/Collapse.js | 42 ------ .../app/map/controls/Collapse.module.scss | 55 ------- .../components/app/map/controls/ScaleIndicator.js | 16 -- .../app/map/controls/ScaleIndicator.module.scss | 10 -- .../src/components/app/map/controls/Toolbar.js | 28 ---- .../app/map/controls/Toolbar.module.scss | 29 ---- .../src/components/app/map/elements/Backdrop.js | 8 - .../src/components/app/map/elements/GrayLayer.js | 22 --- .../src/components/app/map/elements/HoverTile.js | 28 ---- .../components/app/map/elements/ImageComponent.js | 36 ----- .../src/components/app/map/elements/RackFillBar.js | 68 --------- .../src/components/app/map/elements/RoomTile.js | 22 --- .../src/components/app/map/elements/TileObject.js | 25 ---- .../components/app/map/elements/TilePlusIcon.js | 44 ------ .../src/components/app/map/elements/WallSegment.js | 32 ---- .../src/components/app/map/groups/GridGroup.js | 34 ----- .../src/components/app/map/groups/RackGroup.js | 25 ---- .../src/components/app/map/groups/RoomGroup.js | 52 ------- .../src/components/app/map/groups/TileGroup.js | 36 ----- .../src/components/app/map/groups/TopologyGroup.js | 44 ------ .../src/components/app/map/groups/WallGroup.js | 22 --- .../app/map/layers/HoverLayerComponent.js | 55 ------- .../src/components/app/map/layers/MapLayer.js | 41 ------ .../components/app/map/layers/ObjectHoverLayer.js | 53 ------- .../components/app/map/layers/RoomHoverLayer.js | 61 -------- .../components/app/results/PortfolioResultInfo.js | 40 ----- .../src/components/app/results/PortfolioResults.js | 134 ----------------- .../app/sidebars/topology/NameComponent.js | 69 --------- .../app/sidebars/topology/TopologySidebar.js | 83 ----------- .../sidebars/topology/TopologySidebar.module.scss | 37 ----- .../sidebars/topology/building/BuildingSidebar.js | 8 - .../building/NewRoomConstructionComponent.js | 46 ------ .../building/NewRoomConstructionContainer.js | 46 ------ .../app/sidebars/topology/machine/DeleteMachine.js | 56 ------- .../sidebars/topology/machine/MachineSidebar.js | 49 ------- .../sidebars/topology/machine/UnitAddComponent.js | 42 ------ .../sidebars/topology/machine/UnitAddContainer.js | 43 ------ .../sidebars/topology/machine/UnitListComponent.js | 112 -------------- .../sidebars/topology/machine/UnitListContainer.js | 53 ------- .../sidebars/topology/machine/UnitTabsComponent.js | 36 ----- .../app/sidebars/topology/rack/AddPrefab.js | 44 ------ .../sidebars/topology/rack/DeleteRackContainer.js | 59 -------- .../app/sidebars/topology/rack/MachineComponent.js | 46 ------ .../sidebars/topology/rack/MachineListComponent.js | 73 ---------- .../sidebars/topology/rack/MachineListContainer.js | 56 ------- .../sidebars/topology/rack/RackNameContainer.js | 22 --- .../app/sidebars/topology/rack/RackSidebar.js | 58 -------- .../sidebars/topology/rack/RackSidebar.module.scss | 12 -- .../sidebars/topology/room/DeleteRoomContainer.js | 59 -------- .../sidebars/topology/room/EditRoomContainer.js | 61 -------- .../topology/room/RackConstructionComponent.js | 36 ----- .../topology/room/RackConstructionContainer.js | 46 ------ .../app/sidebars/topology/room/RoomName.js | 44 ------ .../app/sidebars/topology/room/RoomSidebar.js | 43 ------ .../src/components/modals/ConfirmationModal.js | 27 ---- .../opendc-web-ui/src/components/modals/Modal.js | 38 ----- .../src/components/modals/TextInputModal.js | 70 --------- .../modals/custom-components/NewPortfolioModal.js | 139 ------------------ .../modals/custom-components/NewScenarioModal.js | 159 -------------------- .../modals/custom-components/NewTopologyModal.js | 81 ----------- .../src/components/portfolios/NewScenario.js | 64 ++++++++ .../src/components/portfolios/NewScenarioModal.js | 159 ++++++++++++++++++++ .../src/components/portfolios/ScenarioState.js | 62 ++++++++ .../src/components/portfolios/ScenarioTable.js | 108 ++++++++++++++ .../portfolios/results/PortfolioResultInfo.js | 40 +++++ .../portfolios/results/PortfolioResults.js | 134 +++++++++++++++++ .../src/components/projects/NewPortfolio.js | 2 +- .../src/components/projects/NewPortfolioModal.js | 161 +++++++++++++++++++++ .../src/components/projects/NewProject.js | 2 +- .../src/components/projects/NewScenario.js | 64 -------- .../src/components/projects/NewTopology.js | 2 +- .../src/components/projects/NewTopologyModal.js | 103 +++++++++++++ .../src/components/projects/ScenarioState.js | 62 -------- .../src/components/projects/ScenarioTable.js | 108 -------------- .../src/components/topologies/map/GrayContainer.js | 34 +++++ .../src/components/topologies/map/MapConstants.js | 25 ++++ .../src/components/topologies/map/MapStage.js | 83 +++++++++++ .../components/topologies/map/MapStage.module.scss | 31 ++++ .../src/components/topologies/map/RackContainer.js | 37 +++++ .../topologies/map/RackEnergyFillContainer.js | 34 +++++ .../topologies/map/RackSpaceFillContainer.js | 37 +++++ .../src/components/topologies/map/RoomContainer.js | 45 ++++++ .../src/components/topologies/map/TileContainer.js | 46 ++++++ .../components/topologies/map/TopologyContainer.js | 35 +++++ .../src/components/topologies/map/WallContainer.js | 37 +++++ .../components/topologies/map/controls/Collapse.js | 42 ++++++ .../topologies/map/controls/Collapse.module.scss | 55 +++++++ .../topologies/map/controls/ScaleIndicator.js | 18 +++ .../map/controls/ScaleIndicator.module.scss | 10 ++ .../components/topologies/map/controls/Toolbar.js | 35 +++++ .../topologies/map/controls/Toolbar.module.scss | 29 ++++ .../components/topologies/map/elements/Backdrop.js | 10 ++ .../topologies/map/elements/GrayLayer.js | 24 +++ .../topologies/map/elements/HoverTile.js | 30 ++++ .../topologies/map/elements/ImageComponent.js | 36 +++++ .../topologies/map/elements/RackFillBar.js | 68 +++++++++ .../components/topologies/map/elements/RoomTile.js | 24 +++ .../topologies/map/elements/TileObject.js | 27 ++++ .../topologies/map/elements/TilePlusIcon.js | 44 ++++++ .../topologies/map/elements/WallSegment.js | 32 ++++ .../components/topologies/map/groups/GridGroup.js | 36 +++++ .../components/topologies/map/groups/RackGroup.js | 25 ++++ .../components/topologies/map/groups/RoomGroup.js | 52 +++++++ .../components/topologies/map/groups/TileGroup.js | 36 +++++ .../topologies/map/groups/TopologyGroup.js | 44 ++++++ .../components/topologies/map/groups/WallGroup.js | 22 +++ .../topologies/map/layers/HoverLayerComponent.js | 55 +++++++ .../components/topologies/map/layers/MapLayer.js | 41 ++++++ .../topologies/map/layers/ObjectHoverLayer.js | 53 +++++++ .../topologies/map/layers/RoomHoverLayer.js | 61 ++++++++ .../components/topologies/sidebar/NameComponent.js | 69 +++++++++ .../topologies/sidebar/TopologySidebar.js | 83 +++++++++++ .../topologies/sidebar/TopologySidebar.module.scss | 37 +++++ .../topologies/sidebar/building/BuildingSidebar.js | 8 + .../building/NewRoomConstructionComponent.js | 46 ++++++ .../building/NewRoomConstructionContainer.js | 46 ++++++ .../topologies/sidebar/machine/DeleteMachine.js | 56 +++++++ .../topologies/sidebar/machine/MachineSidebar.js | 49 +++++++ .../topologies/sidebar/machine/UnitAddComponent.js | 42 ++++++ .../topologies/sidebar/machine/UnitAddContainer.js | 43 ++++++ .../sidebar/machine/UnitListComponent.js | 112 ++++++++++++++ .../sidebar/machine/UnitListContainer.js | 53 +++++++ .../sidebar/machine/UnitTabsComponent.js | 36 +++++ .../topologies/sidebar/rack/AddPrefab.js | 44 ++++++ .../topologies/sidebar/rack/DeleteRackContainer.js | 59 ++++++++ .../topologies/sidebar/rack/MachineComponent.js | 46 ++++++ .../sidebar/rack/MachineListComponent.js | 73 ++++++++++ .../sidebar/rack/MachineListContainer.js | 56 +++++++ .../topologies/sidebar/rack/RackNameContainer.js | 22 +++ .../topologies/sidebar/rack/RackSidebar.js | 58 ++++++++ .../sidebar/rack/RackSidebar.module.scss | 12 ++ .../topologies/sidebar/room/DeleteRoomContainer.js | 59 ++++++++ .../topologies/sidebar/room/EditRoomContainer.js | 61 ++++++++ .../sidebar/room/RackConstructionComponent.js | 35 +++++ .../sidebar/room/RackConstructionContainer.js | 46 ++++++ .../components/topologies/sidebar/room/RoomName.js | 44 ++++++ .../topologies/sidebar/room/RoomSidebar.js | 43 ++++++ .../components/util/modals/ConfirmationModal.js | 27 ++++ .../src/components/util/modals/Modal.js | 38 +++++ .../src/components/util/modals/TextInputModal.js | 70 +++++++++ .../src/pages/projects/[project]/index.js | 1 - .../projects/[project]/portfolios/[portfolio].js | 6 +- .../projects/[project]/topologies/[topology].js | 123 ++++++++++++---- .../opendc-web-ui/src/redux/sagas/topology.js | 4 +- 158 files changed, 3765 insertions(+), 3633 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/MapStage.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/Backdrop.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/GrayLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/ImageComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/RoomTile.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/TileObject.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/elements/WallSegment.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/groups/GridGroup.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/groups/WallGroup.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefab.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js delete mode 100644 opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/Modal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/NewScenario.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/NewScenarioModal.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/ScenarioState.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewPortfolioModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewScenario.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/NewTopologyModal.js delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js delete mode 100644 opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/NameComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/BuildingSidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/DeleteRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/EditRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomSidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/util/modals/ConfirmationModal.js create mode 100644 opendc-web/opendc-web-ui/src/components/util/modals/Modal.js create mode 100644 opendc-web/opendc-web-ui/src/components/util/modals/TextInputModal.js diff --git a/opendc-web/opendc-web-ui/src/api/topologies.js b/opendc-web/opendc-web-ui/src/api/topologies.js index 0b8864e0..bd4e3bc4 100644 --- a/opendc-web/opendc-web-ui/src/api/topologies.js +++ b/opendc-web/opendc-web-ui/src/api/topologies.js @@ -35,6 +35,7 @@ export function addTopology(auth, topology) { } export function updateTopology(auth, topology) { + // eslint-disable-next-line no-unused-vars const { _id, ...data } = topology return request(auth, `topologies/${topology._id}`, 'PUT', { topology: data }) } diff --git a/opendc-web/opendc-web-ui/src/components/AppNavigation.js b/opendc-web/opendc-web-ui/src/components/AppNavigation.js index b3f11f34..178c3ec0 100644 --- a/opendc-web/opendc-web-ui/src/components/AppNavigation.js +++ b/opendc-web/opendc-web-ui/src/components/AppNavigation.js @@ -20,7 +20,7 @@ * SOFTWARE. */ -import { Dropdown, DropdownItem, DropdownToggle, Nav, NavItem, NavList } from '@patternfly/react-core' +import { Nav, NavItem, NavList } from '@patternfly/react-core' import { useRouter } from 'next/router' import NavItemLink from './util/NavItemLink' import { useProject } from '../data/project' diff --git a/opendc-web/opendc-web-ui/src/components/AppPage.js b/opendc-web/opendc-web-ui/src/components/AppPage.js index 7cf9cc15..2e0ea4cc 100644 --- a/opendc-web/opendc-web-ui/src/components/AppPage.js +++ b/opendc-web/opendc-web-ui/src/components/AppPage.js @@ -22,8 +22,7 @@ import PropTypes from 'prop-types' import { AppHeader } from './AppHeader' -import { AppNavigation } from './AppNavigation' -import React, { useState } from 'react' +import React from 'react' import { Page } from '@patternfly/react-core' export function AppPage({ children, breadcrumb, tertiaryNav }) { diff --git a/opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js deleted file mode 100644 index 4791940f..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/GrayContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' -import GrayLayer from '../../../components/app/map/elements/GrayLayer' - -const GrayContainer = () => { - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - return -} - -export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js b/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js deleted file mode 100644 index 4c3b2757..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapConstants.js +++ /dev/null @@ -1,25 +0,0 @@ -export const MAP_SIZE = 50 -export const TILE_SIZE_IN_PIXELS = 100 -export const TILE_SIZE_IN_METERS = 0.5 -export const MAP_SIZE_IN_PIXELS = MAP_SIZE * TILE_SIZE_IN_PIXELS - -export const OBJECT_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 5 -export const TILE_PLUS_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 3 -export const OBJECT_SIZE_IN_PIXELS = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 - -export const GRID_LINE_WIDTH_IN_PIXELS = 2 -export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 -export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 -export const TILE_PLUS_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 10 - -export const RACK_FILL_ICON_WIDTH = OBJECT_SIZE_IN_PIXELS / 3 -export const RACK_FILL_ICON_OPACITY = 0.8 - -export const MAP_MOVE_PIXELS_PER_EVENT = 20 -export const MAP_SCALE_PER_EVENT = 1.1 -export const MAP_MIN_SCALE = 0.5 -export const MAP_MAX_SCALE = 1.5 - -export const MAX_NUM_UNITS_PER_MACHINE = 6 -export const DEFAULT_RACK_SLOT_CAPACITY = 42 -export const DEFAULT_RACK_POWER_CAPACITY = 10000 diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js deleted file mode 100644 index 5d19b3ad..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.js +++ /dev/null @@ -1,83 +0,0 @@ -import React, { useRef, useState } from 'react' -import { HotKeys } from 'react-hotkeys' -import { Stage } from 'react-konva' -import { MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_MOVE_PIXELS_PER_EVENT, MAP_SCALE_PER_EVENT } from './MapConstants' -import { Provider, useStore } from 'react-redux' -import useResizeObserver from 'use-resize-observer' -import { mapContainer } from './MapStage.module.scss' -import MapLayer from './layers/MapLayer' -import RoomHoverLayer from './layers/RoomHoverLayer' -import ObjectHoverLayer from './layers/ObjectHoverLayer' -import ScaleIndicator from './controls/ScaleIndicator' -import Toolbar from './controls/Toolbar' - -function MapStage() { - const store = useStore() - const { ref, width = 100, height = 100 } = useResizeObserver() - const stageRef = useRef(null) - const [[x, y], setPos] = useState([0, 0]) - const [scale, setScale] = useState(1) - - const clampScale = (target) => Math.min(Math.max(target, MAP_MIN_SCALE), MAP_MAX_SCALE) - const moveWithDelta = (deltaX, deltaY) => setPos(([x, y]) => [x + deltaX, y + deltaY]) - - const onZoom = (e) => { - e.evt.preventDefault() - - const stage = stageRef.current.getStage() - const oldScale = scale - - const pointer = stage.getPointerPosition() - const mousePointTo = { - x: (pointer.x - x) / oldScale, - y: (pointer.y - y) / oldScale, - } - - const newScale = clampScale(e.evt.deltaY > 0 ? oldScale * MAP_SCALE_PER_EVENT : oldScale / MAP_SCALE_PER_EVENT) - - setScale(newScale) - setPos([pointer.x - mousePointTo.x * newScale, pointer.y - mousePointTo.y * newScale]) - } - const onZoomButton = (zoomIn) => - setScale((scale) => clampScale(zoomIn ? scale * MAP_SCALE_PER_EVENT : scale / MAP_SCALE_PER_EVENT)) - const onDragEnd = (e) => setPos([e.target.x(), e.target.y()]) - const onExport = () => { - const download = document.createElement('a') - download.href = stageRef.current.getStage().toDataURL() - download.download = 'opendc-canvas-export-' + Date.now() + '.png' - download.click() - } - - const handlers = { - MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), - MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), - MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), - MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), - } - - return ( - - - - - - - - - - - - ) -} - -export default MapStage diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss deleted file mode 100644 index d879b4c8..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/MapStage.module.scss +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -.mapContainer { - background-color: var(--pf-global--Color--light-200); - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js deleted file mode 100644 index 3c75d3a7..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/RackContainer.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useSelector } from 'react-redux' -import RackGroup from '../../../components/app/map/groups/RackGroup' -import { Tile } from '../../../shapes' - -const RackContainer = ({ tile }) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - return -} - -RackContainer.propTypes = { - tile: Tile, -} - -export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js deleted file mode 100644 index dbc26f14..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/RackEnergyFillContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import RackFillBar from '../../../components/app/map/elements/RackFillBar' - -function RackSpaceFillContainer({ tileId, ...props }) { - const fillFraction = useSelector((state) => { - let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[tileId].rack] - const machineIds = rack.machines - machineIds.forEach((machineId) => { - if (machineId !== null) { - const machine = state.objects.machine[machineId] - machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) - machine.memories.forEach( - (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) - ) - machine.storages.forEach( - (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) - ) - } - }) - - return Math.min(1, energyConsumptionTotal / rack.powerCapacityW) - }) - return -} - -RackSpaceFillContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js deleted file mode 100644 index 7ca5c930..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/RackSpaceFillContainer.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import RackFillBar from '../../../components/app/map/elements/RackFillBar' - -function RackSpaceFillContainer({ tileId, ...props }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) - return -} - -RackSpaceFillContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js deleted file mode 100644 index 26fbcd7a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/RoomContainer.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' -import RoomGroup from '../../../components/app/map/groups/RoomGroup' - -const RoomContainer = (props) => { - const state = useSelector((state) => { - return { - interactionLevel: state.interactionLevel, - currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.objects.room[props.roomId], - } - }) - const dispatch = useDispatch() - return dispatch(goFromBuildingToRoom(props.roomId))} /> -} - -RoomContainer.propTypes = { - roomId: PropTypes.string, -} - -export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js deleted file mode 100644 index bfcbf735..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/TileContainer.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import PropTypes from 'prop-types' -import { useDispatch, useSelector } from 'react-redux' -import { goFromRoomToRack } from '../../../redux/actions/interaction-level' -import TileGroup from '../../../components/app/map/groups/TileGroup' - -const TileContainer = (props) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - const tile = useSelector((state) => state.objects.tile[props.tileId]) - - const dispatch = useDispatch() - const onClick = (tile) => { - if (tile.rack) { - dispatch(goFromRoomToRack(tile._id)) - } - } - return -} - -TileContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js deleted file mode 100644 index 78e75d0f..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/TopologyContainer.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useSelector } from 'react-redux' -import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -import { useActiveTopology } from '../../../data/topology' - -const TopologyContainer = () => { - const topology = useActiveTopology() - const interactionLevel = useSelector((state) => state.interactionLevel) - - return -} - -export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js deleted file mode 100644 index 51dffe4b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/WallContainer.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import WallGroup from '../../../components/app/map/groups/WallGroup' - -const WallContainer = (props) => { - const tiles = useSelector((state) => - state.objects.room[props.roomId].tiles.map((tileId) => state.objects.tile[tileId]) - ) - return -} - -WallContainer.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js deleted file mode 100644 index f54b7c84..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import { ChevronLeftIcon } from '@patternfly/react-icons' -import { collapseContainer } from './Collapse.module.scss' -import { Button } from '@patternfly/react-core' - -function Collapse({ onClick }) { - return ( -
    - -
    - ) -} - -Collapse.propTypes = { - onClick: PropTypes.func, -} - -export default Collapse diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss deleted file mode 100644 index 0c1fac94..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/Collapse.module.scss +++ /dev/null @@ -1,55 +0,0 @@ -/*! - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -.collapseContainer { - position: absolute; - right: var(--pf-global--spacer--xs); - top: 0; - bottom: 10%; - margin: auto 0; - height: 50px; - - button:global(.pf-m-tertiary) { - height: 100%; - padding: 2px; - - margin-right: var(--pf-global--spacer--xs); - margin-top: var(--pf-global--spacer--xs); - background-color: var(--pf-global--BackgroundColor--100); - border: none; - border-radius: var(--pf-global--BorderRadius--sm); - box-shadow: var(--pf-global--BoxShadow--sm); - - &:not(:global(.pf-m-disabled)) { - background-color: var(--pf-global--BackgroundColor--100); - } - - &:after { - display: none; - } - - &:hover { - border: none; - box-shadow: var(--pf-global--BoxShadow--md); - } - } -} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js deleted file mode 100644 index 11c2f2d3..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.js +++ /dev/null @@ -1,16 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from '../MapConstants' -import { scaleIndicator } from './ScaleIndicator.module.scss' - -const ScaleIndicator = ({ scale }) => ( -
    - {TILE_SIZE_IN_METERS}m -
    -) - -ScaleIndicator.propTypes = { - scale: PropTypes.number.isRequired, -} - -export default ScaleIndicator diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss deleted file mode 100644 index f19e0ff2..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/ScaleIndicator.module.scss +++ /dev/null @@ -1,10 +0,0 @@ -.scaleIndicator { - position: absolute; - right: 10px; - bottom: 10px; - z-index: 50; - - border: solid 2px #212529; - border-top: none; - border-left: none; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js b/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js deleted file mode 100644 index 4c60bfb2..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.js +++ /dev/null @@ -1,28 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { control, toolBar } from './Toolbar.module.scss' -import { Button } from '@patternfly/react-core' -import { SearchPlusIcon, SearchMinusIcon } from '@patternfly/react-icons' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCamera } from '@fortawesome/free-solid-svg-icons' - -const Toolbar = ({ onZoom, onExport }) => ( -
    - - - -
    -) - -Toolbar.propTypes = { - onZoom: PropTypes.func, - onExport: PropTypes.func, -} - -export default Toolbar diff --git a/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss b/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss deleted file mode 100644 index 0d505acc..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/controls/Toolbar.module.scss +++ /dev/null @@ -1,29 +0,0 @@ -.toolBar { - position: absolute; - bottom: var(--pf-global--spacer--md); - left: var(--pf-global--spacer--xl); -} - -.control { - &:global(.pf-m-tertiary) { - margin-right: var(--pf-global--spacer--xs); - margin-top: var(--pf-global--spacer--xs); - background-color: var(--pf-global--BackgroundColor--100); - border: none; - border-radius: var(--pf-global--BorderRadius--sm); - box-shadow: var(--pf-global--BoxShadow--sm); - - &:not(:global(.pf-m-disabled)) { - background-color: var(--pf-global--BackgroundColor--100); - } - - &:after { - display: none; - } - - &:hover { - border: none; - box-shadow: var(--pf-global--BoxShadow--md); - } - } -} diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/Backdrop.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/Backdrop.js deleted file mode 100644 index 8ccfe584..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/Backdrop.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import { Rect } from 'react-konva' -import { BACKDROP_COLOR } from '../../../../util/colors' -import { MAP_SIZE_IN_PIXELS } from '../MapConstants' - -const Backdrop = () => - -export default Backdrop diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/GrayLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/GrayLayer.js deleted file mode 100644 index 35af4d96..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/GrayLayer.js +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Rect } from 'react-konva' -import { GRAYED_OUT_AREA_COLOR } from '../../../../util/colors' -import { MAP_SIZE_IN_PIXELS } from '../MapConstants' - -const GrayLayer = ({ onClick }) => ( - -) - -GrayLayer.propTypes = { - onClick: PropTypes.func, -} - -export default GrayLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js deleted file mode 100644 index 0369bb79..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/HoverTile.js +++ /dev/null @@ -1,28 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Rect } from 'react-konva' -import { ROOM_HOVER_INVALID_COLOR, ROOM_HOVER_VALID_COLOR } from '../../../../util/colors' -import { TILE_SIZE_IN_PIXELS } from '../MapConstants' - -const HoverTile = ({ x, y, isValid, scale = 1, onClick }) => ( - -) - -HoverTile.propTypes = { - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - isValid: PropTypes.bool.isRequired, - scale: PropTypes.number, - onClick: PropTypes.func.isRequired, -} - -export default HoverTile diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/ImageComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/ImageComponent.js deleted file mode 100644 index 7d304b6b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/ImageComponent.js +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useEffect, useState } from 'react' -import { Image } from 'react-konva' - -const imageCaches = {} - -function ImageComponent({ src, x, y, width, height, opacity }) { - const [image, setImage] = useState(null) - - useEffect(() => { - if (imageCaches[src]) { - setImage(imageCaches[src]) - return - } - - const image = new window.Image() - image.src = src - image.onload = () => { - setImage(image) - imageCaches[src] = image - } - }, [src]) - - return -} - -ImageComponent.propTypes = { - src: PropTypes.string.isRequired, - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - opacity: PropTypes.number.isRequired, -} - -export default ImageComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js deleted file mode 100644 index aa284944..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/RackFillBar.js +++ /dev/null @@ -1,68 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group, Rect } from 'react-konva' -import { - RACK_ENERGY_BAR_BACKGROUND_COLOR, - RACK_ENERGY_BAR_FILL_COLOR, - RACK_SPACE_BAR_BACKGROUND_COLOR, - RACK_SPACE_BAR_FILL_COLOR, -} from '../../../../util/colors' -import { - OBJECT_BORDER_WIDTH_IN_PIXELS, - OBJECT_MARGIN_IN_PIXELS, - RACK_FILL_ICON_OPACITY, - RACK_FILL_ICON_WIDTH, - TILE_SIZE_IN_PIXELS, -} from '../MapConstants' -import ImageComponent from './ImageComponent' - -function RackFillBar({ positionX, positionY, type, fillFraction }) { - const halfOfObjectBorderWidth = OBJECT_BORDER_WIDTH_IN_PIXELS / 2 - const x = - positionX * TILE_SIZE_IN_PIXELS + - OBJECT_MARGIN_IN_PIXELS + - (type === 'space' ? halfOfObjectBorderWidth : 0.5 * (TILE_SIZE_IN_PIXELS - 2 * OBJECT_MARGIN_IN_PIXELS)) - const startY = positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS + halfOfObjectBorderWidth - const width = 0.5 * (TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2) - halfOfObjectBorderWidth - const fullHeight = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 - OBJECT_BORDER_WIDTH_IN_PIXELS - - const fractionHeight = fillFraction * fullHeight - const fractionY = - (positionY + 1) * TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS - halfOfObjectBorderWidth - fractionHeight - - return ( - - - - - - ) -} - -RackFillBar.propTypes = { - positionX: PropTypes.number.isRequired, - positionY: PropTypes.number.isRequired, - type: PropTypes.string.isRequired, - fillFraction: PropTypes.number.isRequired, -} - -export default RackFillBar diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/RoomTile.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/RoomTile.js deleted file mode 100644 index ed718601..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/RoomTile.js +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Rect } from 'react-konva' -import { Tile } from '../../../../shapes' -import { TILE_SIZE_IN_PIXELS } from '../MapConstants' - -const RoomTile = ({ tile, color }) => ( - -) - -RoomTile.propTypes = { - tile: Tile, - color: PropTypes.string, -} - -export default RoomTile diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/TileObject.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/TileObject.js deleted file mode 100644 index 9e87cc82..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/TileObject.js +++ /dev/null @@ -1,25 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Rect } from 'react-konva' -import { OBJECT_BORDER_COLOR } from '../../../../util/colors' -import { OBJECT_BORDER_WIDTH_IN_PIXELS, OBJECT_MARGIN_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' - -const TileObject = ({ positionX, positionY, color }) => ( - -) - -TileObject.propTypes = { - positionX: PropTypes.number.isRequired, - positionY: PropTypes.number.isRequired, - color: PropTypes.string.isRequired, -} - -export default TileObject diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js deleted file mode 100644 index 186c2b3a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/TilePlusIcon.js +++ /dev/null @@ -1,44 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group, Line } from 'react-konva' -import { TILE_PLUS_COLOR } from '../../../../util/colors' -import { TILE_PLUS_MARGIN_IN_PIXELS, TILE_PLUS_WIDTH_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' - -function TilePlusIcon({ x, y, scale = 1 }) { - const linePoints = [ - [ - x + 0.5 * TILE_SIZE_IN_PIXELS * scale, - y + TILE_PLUS_MARGIN_IN_PIXELS * scale, - x + 0.5 * TILE_SIZE_IN_PIXELS * scale, - y + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, - ], - [ - x + TILE_PLUS_MARGIN_IN_PIXELS * scale, - y + 0.5 * TILE_SIZE_IN_PIXELS * scale, - x + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, - y + 0.5 * TILE_SIZE_IN_PIXELS * scale, - ], - ] - return ( - - {linePoints.map((points, index) => ( - - ))} - - ) -} - -TilePlusIcon.propTypes = { - x: PropTypes.number, - y: PropTypes.number, - scale: PropTypes.number, -} - -export default TilePlusIcon diff --git a/opendc-web/opendc-web-ui/src/components/app/map/elements/WallSegment.js b/opendc-web/opendc-web-ui/src/components/app/map/elements/WallSegment.js deleted file mode 100644 index ad6412c3..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/elements/WallSegment.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { Line } from 'react-konva' -import { WallSegment as WallSegmentShape } from '../../../../shapes' -import { WALL_COLOR } from '../../../../util/colors' -import { TILE_SIZE_IN_PIXELS, WALL_WIDTH_IN_PIXELS } from '../MapConstants' - -const WallSegment = ({ wallSegment }) => { - let points - if (wallSegment.isHorizontal) { - points = [ - wallSegment.startPosX * TILE_SIZE_IN_PIXELS, - wallSegment.startPosY * TILE_SIZE_IN_PIXELS, - (wallSegment.startPosX + wallSegment.length) * TILE_SIZE_IN_PIXELS, - wallSegment.startPosY * TILE_SIZE_IN_PIXELS, - ] - } else { - points = [ - wallSegment.startPosX * TILE_SIZE_IN_PIXELS, - wallSegment.startPosY * TILE_SIZE_IN_PIXELS, - wallSegment.startPosX * TILE_SIZE_IN_PIXELS, - (wallSegment.startPosY + wallSegment.length) * TILE_SIZE_IN_PIXELS, - ] - } - - return -} - -WallSegment.propTypes = { - wallSegment: WallSegmentShape, -} - -export default WallSegment diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/GridGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/GridGroup.js deleted file mode 100644 index ebc00244..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/GridGroup.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -import { Group, Line } from 'react-konva' -import { GRID_COLOR } from '../../../../util/colors' -import { GRID_LINE_WIDTH_IN_PIXELS, MAP_SIZE, MAP_SIZE_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' - -const MAP_COORDINATE_ENTRIES = Array.from(new Array(MAP_SIZE), (x, i) => i) -const HORIZONTAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map((index) => [ - 0, - index * TILE_SIZE_IN_PIXELS, - MAP_SIZE_IN_PIXELS, - index * TILE_SIZE_IN_PIXELS, -]) -const VERTICAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map((index) => [ - index * TILE_SIZE_IN_PIXELS, - 0, - index * TILE_SIZE_IN_PIXELS, - MAP_SIZE_IN_PIXELS, -]) - -const GridGroup = () => ( - - {HORIZONTAL_POINT_PAIRS.concat(VERTICAL_POINT_PAIRS).map((points, index) => ( - - ))} - -) - -export default GridGroup diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js deleted file mode 100644 index 9c4abc4a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/RackGroup.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import { Group } from 'react-konva' -import { Tile } from '../../../../shapes' -import { RACK_BACKGROUND_COLOR } from '../../../../util/colors' -import TileObject from '../elements/TileObject' -import RackSpaceFillContainer from '../RackSpaceFillContainer' -import RackEnergyFillContainer from '../RackEnergyFillContainer' - -const RackGroup = ({ tile }) => { - return ( - - - - - - - - ) -} - -RackGroup.propTypes = { - tile: Tile, -} - -export default RackGroup diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js deleted file mode 100644 index a14f3676..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/RoomGroup.js +++ /dev/null @@ -1,52 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group } from 'react-konva' -import { InteractionLevel, Room } from '../../../../shapes' -import GrayContainer from '../GrayContainer' -import TileContainer from '../TileContainer' -import WallContainer from '../WallContainer' - -const RoomGroup = ({ room, interactionLevel, currentRoomInConstruction, onClick }) => { - if (currentRoomInConstruction === room._id) { - return ( - - {room.tiles.map((tileId) => ( - - ))} - - ) - } - - return ( - - {(() => { - if ( - (interactionLevel.mode === 'RACK' || interactionLevel.mode === 'MACHINE') && - interactionLevel.roomId === room._id - ) { - return [ - room.tiles - .filter((tileId) => tileId !== interactionLevel.tileId) - .map((tileId) => ), - , - room.tiles - .filter((tileId) => tileId === interactionLevel.tileId) - .map((tileId) => ), - ] - } else { - return room.tiles.map((tileId) => ) - } - })()} - - - ) -} - -RoomGroup.propTypes = { - room: Room, - interactionLevel: InteractionLevel, - currentRoomInConstruction: PropTypes.string, - onClick: PropTypes.func, -} - -export default RoomGroup diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js deleted file mode 100644 index cd36c7e5..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/TileGroup.js +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group } from 'react-konva' -import { Tile } from '../../../../shapes' -import { ROOM_DEFAULT_COLOR, ROOM_IN_CONSTRUCTION_COLOR } from '../../../../util/colors' -import RoomTile from '../elements/RoomTile' -import RackContainer from '../RackContainer' - -const TileGroup = ({ tile, newTile, onClick }) => { - let tileObject - if (tile.rack) { - tileObject = - } else { - tileObject = null - } - - let color = ROOM_DEFAULT_COLOR - if (newTile) { - color = ROOM_IN_CONSTRUCTION_COLOR - } - - return ( - onClick(tile)}> - - {tileObject} - - ) -} - -TileGroup.propTypes = { - tile: Tile, - newTile: PropTypes.bool, - onClick: PropTypes.func, -} - -export default TileGroup diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js deleted file mode 100644 index d3bcb279..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/TopologyGroup.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react' -import { Group } from 'react-konva' -import { InteractionLevel, Topology } from '../../../../shapes' -import RoomContainer from '../RoomContainer' -import GrayContainer from '../GrayContainer' - -const TopologyGroup = ({ topology, interactionLevel }) => { - if (!topology) { - return - } - - if (interactionLevel.mode === 'BUILDING') { - return ( - - {topology.rooms.map((roomId) => ( - - ))} - - ) - } - - return ( - - {topology.rooms - .filter((roomId) => roomId !== interactionLevel.roomId) - .map((roomId) => ( - - ))} - {interactionLevel.mode === 'ROOM' ? : null} - {topology.rooms - .filter((roomId) => roomId === interactionLevel.roomId) - .map((roomId) => ( - - ))} - - ) -} - -TopologyGroup.propTypes = { - topology: Topology, - interactionLevel: InteractionLevel, -} - -export default TopologyGroup diff --git a/opendc-web/opendc-web-ui/src/components/app/map/groups/WallGroup.js b/opendc-web/opendc-web-ui/src/components/app/map/groups/WallGroup.js deleted file mode 100644 index c73a95a7..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/groups/WallGroup.js +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group } from 'react-konva' -import { Tile } from '../../../../shapes' -import { deriveWallLocations } from '../../../../util/tile-calculations' -import WallSegment from '../elements/WallSegment' - -const WallGroup = ({ tiles }) => { - return ( - - {deriveWallLocations(tiles).map((wallSegment, index) => ( - - ))} - - ) -} - -WallGroup.propTypes = { - tiles: PropTypes.arrayOf(Tile).isRequired, -} - -export default WallGroup diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js deleted file mode 100644 index 2b1060c0..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/HoverLayerComponent.js +++ /dev/null @@ -1,55 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useMemo, useState } from 'react' -import { Layer } from 'react-konva/lib/ReactKonva' -import HoverTile from '../elements/HoverTile' -import { TILE_SIZE_IN_PIXELS } from '../MapConstants' -import { useEffectRef } from '../../../../util/effect-ref' - -function HoverLayerComponent({ isEnabled, isValid, onClick, children }) { - const [[mouseWorldX, mouseWorldY], setPos] = useState([0, 0]) - - const layerRef = useEffectRef((layer) => { - if (!layer) { - return - } - - const stage = layer.getStage() - - // Transform used to convert mouse coordinates to world coordinates - const transform = stage.getAbsoluteTransform().copy() - transform.invert() - - stage.on('mousemove.hover', () => { - const { x, y } = transform.point(stage.getPointerPosition()) - setPos([x, y]) - }) - return () => stage.off('mousemove.hover') - }) - - const gridX = Math.floor(mouseWorldX / TILE_SIZE_IN_PIXELS) - const gridY = Math.floor(mouseWorldY / TILE_SIZE_IN_PIXELS) - const valid = useMemo(() => isEnabled && isValid(gridX, gridY), [isEnabled, isValid, gridX, gridY]) - - if (!isEnabled) { - return - } - - const x = gridX * TILE_SIZE_IN_PIXELS - const y = gridY * TILE_SIZE_IN_PIXELS - - return ( - - (valid ? onClick(gridX, gridY) : undefined)} /> - {children ? React.cloneElement(children, { x, y, scale: 1 }) : undefined} - - ) -} - -HoverLayerComponent.propTypes = { - isEnabled: PropTypes.bool.isRequired, - isValid: PropTypes.func.isRequired, - onClick: PropTypes.func.isRequired, - children: PropTypes.node, -} - -export default HoverLayerComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js deleted file mode 100644 index c902532b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/MapLayer.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { Group, Layer } from 'react-konva' -import Backdrop from '../elements/Backdrop' -import TopologyContainer from '../TopologyContainer' -import GridGroup from '../groups/GridGroup' - -function MapLayer() { - return ( - - - - - - - - ) -} - -export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js deleted file mode 100644 index 47d9c992..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/ObjectHoverLayer.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addRackToTile } from '../../../../redux/actions/topology/room' -import { findTileWithPosition } from '../../../../util/tile-calculations' -import HoverLayerComponent from './HoverLayerComponent' -import TilePlusIcon from '../elements/TilePlusIcon' - -function ObjectHoverLayer() { - const isEnabled = useSelector((state) => state.construction.inRackConstructionMode) - const isValid = useSelector((state) => (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } - - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) - const tile = findTileWithPosition(tiles, x, y) - - return !(tile === null || tile.rack) - }) - - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(addRackToTile(x, y)) - return ( - - - - ) -} - -export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js deleted file mode 100644 index 59f83b2b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/map/layers/RoomHoverLayer.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' -import { - deriveValidNextTilePositions, - findPositionInPositions, - findPositionInRooms, -} from '../../../../util/tile-calculations' -import HoverLayerComponent from './HoverLayerComponent' - -function RoomHoverLayer() { - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) - const isEnabled = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - const isValid = useSelector((state) => (x, y) => { - const newRoom = { ...state.objects.room[state.construction.currentRoomInConstruction] } - const oldRooms = Object.keys(state.objects.room) - .map((id) => ({ ...state.objects.room[id] })) - .filter( - (room) => - state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && - room._id !== state.construction.currentRoomInConstruction - ) - - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) - }) - if (newRoom.tiles.length === 0) { - return findPositionInRooms(oldRooms, x, y) === -1 - } - - const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) - return findPositionInPositions(validNextPositions, x, y) !== -1 - }) - - return -} - -export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js deleted file mode 100644 index 09348e60..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResultInfo.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import { Tooltip } from '@patternfly/react-core' -import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' -import { METRIC_DESCRIPTIONS } from '../../../util/available-metrics' - -function PortfolioResultInfo({ metric }) { - return ( - {METRIC_DESCRIPTIONS[metric]}
    }> - - - ) -} - -PortfolioResultInfo.propTypes = { - metric: PropTypes.string.isRequired, -} - -export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js deleted file mode 100644 index 6a96c70c..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/results/PortfolioResults.js +++ /dev/null @@ -1,134 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' -import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_NAMES_SHORT, METRIC_UNITS } from '../../../util/available-metrics' -import { mean, std } from 'mathjs' -import approx from 'approximate-number' -import { - Bullseye, - Card, - CardActions, - CardBody, - CardHeader, - CardTitle, - EmptyState, - EmptyStateBody, - EmptyStateIcon, - Grid, - GridItem, - Spinner, - Title, -} from '@patternfly/react-core' -import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' -import { usePortfolioScenarios } from '../../../data/project' -import NewScenario from '../../projects/NewScenario' -import PortfolioResultInfo from './PortfolioResultInfo' - -const PortfolioResults = ({ portfolioId }) => { - const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) - - if (status === 'loading') { - return ( - - - - - Loading Results - - - - ) - } else if (status === 'error') { - return ( - - - - - Unable to connect - - - There was an error retrieving data. Check your connection and try again. - - - - ) - } else if (scenarios.length === 0) { - return ( - - - - - No results - - - No results are currently available for this portfolio. Run a scenario to obtain simulation - results. - - - - - ) - } - - const dataPerMetric = {} - - AVAILABLE_METRICS.forEach((metric) => { - dataPerMetric[metric] = scenarios - .filter((scenario) => scenario.results) - .map((scenario) => ({ - name: scenario.name, - value: mean(scenario.results[metric]), - errorX: std(scenario.results[metric]), - })) - }) - - return ( - - {AVAILABLE_METRICS.map((metric) => ( - - - - - - - {METRIC_NAMES[metric]} - - - - - - approx(tick)} - label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} - type="number" - /> - - - - - - - - - - - ))} - - ) -} - -PortfolioResults.propTypes = { - portfolioId: PropTypes.string, -} - -export default PortfolioResults diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js deleted file mode 100644 index ececd07b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/NameComponent.js +++ /dev/null @@ -1,69 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef, useState } from 'react' -import { Button, TextInput } from '@patternfly/react-core' -import { PencilAltIcon, CheckIcon, TimesIcon } from '@patternfly/react-icons' - -function NameComponent({ name, onEdit }) { - const [isEditing, setEditing] = useState(false) - const nameInput = useRef(null) - - const onCancel = () => { - nameInput.current.value = name - setEditing(false) - } - - const onSubmit = (event) => { - if (event) { - event.preventDefault() - } - - const name = nameInput.current.value - if (name) { - onEdit(name) - } - - setEditing(false) - } - - return ( -
    -
    -
    - {name} -
    -
    - -
    -
    -
    -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - ) -} - -NameComponent.propTypes = { - name: PropTypes.string, - onEdit: PropTypes.func, -} - -export default NameComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js deleted file mode 100644 index 564f4030..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.js +++ /dev/null @@ -1,83 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { InteractionLevel } from '../../../../shapes' -import BuildingSidebar from './building/BuildingSidebar' -import { - Button, - DrawerActions, - DrawerCloseButton, - DrawerHead, - DrawerPanelBody, - DrawerPanelContent, - Flex, - Title, -} from '@patternfly/react-core' -import { AngleLeftIcon } from '@patternfly/react-icons' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../redux/actions/interaction-level' -import { backButton } from './TopologySidebar.module.scss' -import RoomSidebar from './room/RoomSidebar' -import RackSidebar from './rack/RackSidebar' -import MachineSidebar from './machine/MachineSidebar' - -const name = { - BUILDING: 'Building', - ROOM: 'Room', - RACK: 'Rack', - MACHINE: 'Machine', -} - -function TopologySidebar({ interactionLevel, onClose }) { - let sidebarContent - - switch (interactionLevel.mode) { - case 'BUILDING': - sidebarContent = - break - case 'ROOM': - sidebarContent = - break - case 'RACK': - sidebarContent = - break - case 'MACHINE': - sidebarContent = - break - default: - sidebarContent = 'Missing Content' - } - - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - - return ( - - - - - - {name[interactionLevel.mode]} - - - - - - - {sidebarContent} - - ) -} - -TopologySidebar.propTypes = { - interactionLevel: InteractionLevel, - onClose: PropTypes.func, -} - -export default TopologySidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss deleted file mode 100644 index 45dc98da..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/TopologySidebar.module.scss +++ /dev/null @@ -1,37 +0,0 @@ -/*! - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -.backButton { - &:global(.pf-c-button) { - align-self: center; - --pf-c-button--after--BorderColor: var(--pf-global--BorderColor--light-100); - color: var(--pf-global--Color--400); - - --pf-c-button--PaddingRight: var(--pf-global--spacer--sm); - --pf-c-button--PaddingLeft: var(--pf-global--spacer--sm); - - &:hover, - &:focus { - --pf-c-button--after--BorderColor: var(--pf-global--BorderColor--100); - } - } -} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js deleted file mode 100644 index 5fcd46be..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/BuildingSidebar.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import NewRoomConstructionContainer from './NewRoomConstructionContainer' - -function BuildingSidebar() { - return -} - -export default BuildingSidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js deleted file mode 100644 index 9fc85d0c..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js +++ /dev/null @@ -1,46 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Button, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from '@patternfly/react-core' -import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' -import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' - -function NewRoomConstructionComponent({ onStart, onFinish, onCancel, currentRoomInConstruction }) { - if (currentRoomInConstruction === '-1') { - return ( - - ) - } - return ( - - - - - - - - - - - - - ) -} - -NewRoomConstructionComponent.propTypes = { - onStart: PropTypes.func, - onFinish: PropTypes.func, - onCancel: PropTypes.func, - currentRoomInConstruction: PropTypes.string, -} - -export default NewRoomConstructionComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js deleted file mode 100644 index 5b031a6b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/building/NewRoomConstructionContainer.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { - cancelNewRoomConstruction, - finishNewRoomConstruction, - startNewRoomConstruction, -} from '../../../../../redux/actions/topology/building' -import NewRoomConstructionComponent from './NewRoomConstructionComponent' - -function NewRoomConstructionButton(props) { - const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) - - const dispatch = useDispatch() - const actions = { - onStart: () => dispatch(startNewRoomConstruction()), - onFinish: () => dispatch(finishNewRoomConstruction()), - onCancel: () => dispatch(cancelNewRoomConstruction()), - } - return ( - - ) -} - -export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js deleted file mode 100644 index 75d458b6..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/DeleteMachine.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { deleteMachine } from '../../../../../redux/actions/topology/machine' -import { Button } from '@patternfly/react-core' -import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' -import ConfirmationModal from '../../../../modals/ConfirmationModal' - -function DeleteMachine() { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rack) - const position = useSelector((state) => state.interactionLevel.position) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteMachine(rackId, position)) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteMachine diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebar.js deleted file mode 100644 index 0c3dea98..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/MachineSidebar.js +++ /dev/null @@ -1,49 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import UnitTabsComponent from './UnitTabsComponent' -import DeleteMachine from './DeleteMachine' -import { - TextContent, - TextList, - TextListItem, - TextListItemVariants, - TextListVariants, - Title, -} from '@patternfly/react-core' -import { useSelector } from 'react-redux' - -function MachineSidebar({ tileId, position }) { - const machine = useSelector(({ objects }) => { - const rack = objects.rack[objects.tile[tileId].rack] - return objects.machine[rack.machines[position - 1]] - }) - const machineId = machine._id - return ( -
    - - Details - - Name - - Machine at position {machine.position} - - - - Actions - - - Units - -
    - -
    -
    - ) -} - -MachineSidebar.propTypes = { - tileId: PropTypes.string.isRequired, - position: PropTypes.number.isRequired, -} - -export default MachineSidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js deleted file mode 100644 index 88591208..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddComponent.js +++ /dev/null @@ -1,42 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import { Button, InputGroup, Select, SelectOption, SelectVariant } from '@patternfly/react-core' -import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' - -function UnitAddComponent({ units, onAdd }) { - const [isOpen, setOpen] = useState(false) - const [selected, setSelected] = useState(null) - - return ( - - - - - ) -} - -UnitAddComponent.propTypes = { - units: PropTypes.array.isRequired, - onAdd: PropTypes.func.isRequired, -} - -export default UnitAddComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js deleted file mode 100644 index cc226d46..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitAddContainer.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addUnit } from '../../../../../redux/actions/topology/machine' -import UnitAddComponent from './UnitAddComponent' - -function UnitAddContainer({ machineId, unitType }) { - const units = useSelector((state) => Object.values(state.objects[unitType])) - const dispatch = useDispatch() - - const onAdd = (id) => dispatch(addUnit(machineId, unitType, id)) - - return -} - -UnitAddContainer.propTypes = { - machineId: PropTypes.string.isRequired, - unitType: PropTypes.string.isRequired, -} - -export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js deleted file mode 100644 index 16ebd708..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListComponent.js +++ /dev/null @@ -1,112 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { ProcessingUnit, StorageUnit } from '../../../../../shapes' -import { - Button, - DataList, - DataListAction, - DataListCell, - DataListItem, - DataListItemCells, - DataListItemRow, - DescriptionList, - DescriptionListDescription, - DescriptionListGroup, - DescriptionListTerm, - EmptyState, - EmptyStateBody, - EmptyStateIcon, - Popover, - Title, -} from '@patternfly/react-core' -import { CubesIcon, InfoIcon, TrashIcon } from '@patternfly/react-icons' - -function UnitInfo({ unit, unitType }) { - if (unitType === 'cpu' || unitType === 'gpu') { - return ( - - - Clock Frequency - {unit.clockRateMhz} MHz - - - Number of Cores - {unit.numberOfCores} - - - Energy Consumption - {unit.energyConsumptionW} W - - - ) - } - - return ( - - - Speed - {unit.speedMbPerS} Mb/s - - - Capacity - {unit.sizeMb} MB - - - Energy Consumption - {unit.energyConsumptionW} W - - - ) -} - -UnitInfo.propTypes = { - unitType: PropTypes.string.isRequired, - unit: PropTypes.oneOfType([ProcessingUnit, StorageUnit]).isRequired, -} - -function UnitListComponent({ unitType, units, onDelete }) { - if (units.length === 0) { - return ( - - - - No units found - - You have not configured any units yet. Add some with the menu above! - - ) - } - - return ( - - {units.map((unit, index) => ( - - - {unit.name}]} /> - - } - > - - - - - - - ))} - - ) -} - -UnitListComponent.propTypes = { - unitType: PropTypes.string.isRequired, - units: PropTypes.arrayOf(PropTypes.oneOfType([ProcessingUnit, StorageUnit])).isRequired, - onDelete: PropTypes.func, -} - -export default UnitListComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js deleted file mode 100644 index f76684a5..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitListContainer.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import UnitListComponent from './UnitListComponent' -import { deleteUnit } from '../../../../../redux/actions/topology/machine' - -const unitMapping = { - cpu: 'cpus', - gpu: 'gpus', - memory: 'memories', - storage: 'storages', -} - -function UnitListContainer({ machineId, unitType }) { - const dispatch = useDispatch() - const units = useSelector((state) => { - const machine = state.objects.machine[machineId] - return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) - }) - - const onDelete = (unit) => dispatch(deleteUnit(machineId, unitType, unit._id)) - - return -} - -UnitListContainer.propTypes = { - machineId: PropTypes.string.isRequired, - unitType: PropTypes.string.isRequired, -} - -export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js deleted file mode 100644 index 6d10d2df..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/machine/UnitTabsComponent.js +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import { Tab, Tabs, TabTitleText } from '@patternfly/react-core' -import UnitAddContainer from './UnitAddContainer' -import UnitListContainer from './UnitListContainer' - -function UnitTabsComponent({ machineId }) { - const [activeTab, setActiveTab] = useState('cpu-units') - - return ( - setActiveTab(tab)}> - CPU}> - - - - GPU}> - - - - Memory}> - - - - Storage}> - - - - - ) -} - -UnitTabsComponent.propTypes = { - machineId: PropTypes.string.isRequired, -} - -export default UnitTabsComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefab.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefab.js deleted file mode 100644 index 3af46861..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/AddPrefab.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch } from 'react-redux' -import { addPrefab } from '../../../../../redux/actions/prefabs' -import { Button } from '@patternfly/react-core' -import { SaveIcon } from '@patternfly/react-icons' - -function AddPrefab({ tileId }) { - const dispatch = useDispatch() - const onClick = () => dispatch(addPrefab('name', tileId)) - return ( - - ) -} - -AddPrefab.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default AddPrefab diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js deleted file mode 100644 index f0dc7b6b..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/DeleteRackContainer.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRack } from '../../../../../redux/actions/topology/rack' -import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' -import { Button } from '@patternfly/react-core' - -function DeleteRackContainer({ tileId }) { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRack(tileId)) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -DeleteRackContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js deleted file mode 100644 index 97141711..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineComponent.js +++ /dev/null @@ -1,46 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Image from 'next/image' -import { Machine } from '../../../../../shapes' -import { Flex, Label } from '@patternfly/react-core' - -const UnitIcon = ({ id, type }) => ( - {'Machine -) - -UnitIcon.propTypes = { - id: PropTypes.string, - type: PropTypes.string, -} - -function MachineComponent({ machine, onClick }) { - const hasNoUnits = - machine.cpus.length + machine.gpus.length + machine.memories.length + machine.storages.length === 0 - - return ( - onClick()}> - {machine.cpus.length > 0 ? : undefined} - {machine.gpus.length > 0 ? : undefined} - {machine.memories.length > 0 ? : undefined} - {machine.storages.length > 0 ? : undefined} - {hasNoUnits ? ( - - ) : undefined} - - ) -} - -MachineComponent.propTypes = { - machine: Machine.isRequired, - onClick: PropTypes.func, -} - -export default MachineComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js deleted file mode 100644 index 27834cf4..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListComponent.js +++ /dev/null @@ -1,73 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import MachineComponent from './MachineComponent' -import { Machine } from '../../../../../shapes' -import { - Badge, - Button, - DataList, - DataListAction, - DataListCell, - DataListItem, - DataListItemCells, - DataListItemRow, -} from '@patternfly/react-core' -import { AngleRightIcon, PlusIcon } from '@patternfly/react-icons' - -function MachineListComponent({ machines = [], onSelect, onAdd }) { - return ( - - {machines.map((machine, index) => - machine ? ( - onSelect(index + 1)}> - - - {machines.length - index}U - , - - onSelect(index + 1)} machine={machine} /> - , - ]} - /> - - - - - - ) : ( - - - - {machines.length - index}U - , - - Empty Slot - , - ]} - /> - - - - - - ) - )} - - ) -} - -MachineListComponent.propTypes = { - machines: PropTypes.arrayOf(Machine), - onSelect: PropTypes.func.isRequired, - onAdd: PropTypes.func.isRequired, -} - -export default MachineListComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js deleted file mode 100644 index 3ed0ffd0..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/MachineListContainer.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React, { useMemo } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import MachineListComponent from './MachineListComponent' -import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' -import { addMachine } from '../../../../../redux/actions/topology/rack' - -function MachineListContainer({ tileId, ...props }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) - const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) - const machinesNull = useMemo(() => { - const res = Array(rack.capacity).fill(null) - for (const machine of machines) { - res[machine.position - 1] = machine - } - return res - }, [rack, machines]) - const dispatch = useDispatch() - - return ( - dispatch(addMachine(rack._id, index))} - onSelect={(index) => dispatch(goFromRackToMachine(index))} - /> - ) -} - -MachineListContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js deleted file mode 100644 index 11db6420..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackNameContainer.js +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import NameComponent from '../NameComponent' -import { editRackName } from '../../../../../redux/actions/topology/rack' - -const RackNameContainer = ({ tileId }) => { - const { name: rackName, _id } = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) - const dispatch = useDispatch() - const callback = (name) => { - if (name) { - dispatch(editRackName(_id, name)) - } - } - return -} - -RackNameContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js deleted file mode 100644 index 3c9f152a..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.js +++ /dev/null @@ -1,58 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { machineListContainer, sidebarContainer } from './RackSidebar.module.scss' -import RackNameContainer from './RackNameContainer' -import AddPrefab from './AddPrefab' -import DeleteRackContainer from './DeleteRackContainer' -import MachineListContainer from './MachineListContainer' -import { - Skeleton, - TextContent, - TextList, - TextListItem, - TextListItemVariants, - TextListVariants, - Title, -} from '@patternfly/react-core' -import { useSelector } from 'react-redux' - -function RackSidebar({ tileId }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) - - return ( -
    - - Details - - - Name - - - - - Capacity - - {rack?.capacity ?? } - - - Actions - - - - Slots - -
    - -
    -
    - ) -} - -RackSidebar.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default RackSidebar diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss deleted file mode 100644 index 6f258aec..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/rack/RackSidebar.module.scss +++ /dev/null @@ -1,12 +0,0 @@ -.sidebarContainer { - display: flex; - height: 100%; - max-height: 100%; - flex-direction: column; -} - -.machineListContainer { - flex: 1; - overflow-y: scroll; - margin-top: 10px; -} diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js deleted file mode 100644 index 19a782a6..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/DeleteRoomContainer.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRoom } from '../../../../../redux/actions/topology/room' -import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' -import { Button } from '@patternfly/react-core' - -function DeleteRoomContainer({ roomId }) { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRoom(roomId)) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -DeleteRoomContainer.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js deleted file mode 100644 index 96c077cb..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/EditRoomContainer.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { finishRoomEdit, startRoomEdit } from '../../../../../redux/actions/topology/building' -import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' -import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon' -import { Button } from '@patternfly/react-core' - -function EditRoomContainer({ roomId }) { - const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) - - const dispatch = useDispatch() - const onEdit = () => dispatch(startRoomEdit(roomId)) - const onFinish = () => dispatch(finishRoomEdit()) - - return isEditing ? ( - - ) : ( - - ) -} - -EditRoomContainer.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js deleted file mode 100644 index 13432689..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionComponent.js +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Button } from '@patternfly/react-core' -import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' -import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon' - -const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, isEditingRoom }) => { - if (inRackConstructionMode) { - return ( - - ) - } - - return ( - - ) -} - -RackConstructionComponent.propTypes = { - onStart: PropTypes.func, - onStop: PropTypes.func, - inRackConstructionMode: PropTypes.bool, - isEditingRoom: PropTypes.bool, -} - -export default RackConstructionComponent diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js deleted file mode 100644 index b9ab6610..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RackConstructionContainer.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { startRackConstruction, stopRackConstruction } from '../../../../../redux/actions/topology/room' -import RackConstructionComponent from './RackConstructionComponent' - -function RackConstructionContainer(props) { - const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) - const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - - const dispatch = useDispatch() - const onStart = () => dispatch(startRackConstruction()) - const onStop = () => dispatch(stopRackConstruction()) - return ( - - ) -} - -export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js deleted file mode 100644 index 11909189..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomName.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' -import { editRoomName } from '../../../../../redux/actions/topology/room' - -function RoomName({ roomId }) { - const { name: roomName, _id } = useSelector((state) => state.objects.room[roomId]) - const dispatch = useDispatch() - const callback = (name) => { - if (name) { - dispatch(editRoomName(_id, name)) - } - } - return -} - -RoomName.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default RoomName diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js deleted file mode 100644 index 6ad489e0..00000000 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/topology/room/RoomSidebar.js +++ /dev/null @@ -1,43 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import RoomName from './RoomName' -import RackConstructionContainer from './RackConstructionContainer' -import EditRoomContainer from './EditRoomContainer' -import DeleteRoomContainer from './DeleteRoomContainer' -import { - TextContent, - TextList, - TextListItem, - TextListItemVariants, - TextListVariants, - Title, -} from '@patternfly/react-core' - -const RoomSidebar = ({ roomId }) => { - return ( - - Details - - - Name - - - - - - Construction - - - - - ) -} - -RoomSidebar.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default RoomSidebar diff --git a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js deleted file mode 100644 index f6e1c98b..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import Modal from './Modal' - -function ConfirmationModal({ title, message, isOpen, callback }) { - return ( - callback(true)} - onCancel={() => callback(false)} - submitButtonType="danger" - submitButtonText="Confirm" - > - {message} - - ) -} - -ConfirmationModal.propTypes = { - title: PropTypes.string.isRequired, - message: PropTypes.string.isRequired, - isOpen: PropTypes.bool.isRequired, - callback: PropTypes.func.isRequired, -} - -export default ConfirmationModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/Modal.js b/opendc-web/opendc-web-ui/src/components/modals/Modal.js deleted file mode 100644 index d4577062..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/Modal.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Button, Modal as PModal, ModalVariant } from '@patternfly/react-core' - -function Modal({ children, title, isOpen, onSubmit, onCancel, submitButtonType, submitButtonText }) { - const actions = [ - , - , - ] - - return ( - - {children} - - ) -} - -Modal.propTypes = { - title: PropTypes.string.isRequired, - isOpen: PropTypes.bool, - onSubmit: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, - submitButtonType: PropTypes.string, - submitButtonText: PropTypes.string, - children: PropTypes.node, -} - -Modal.defaultProps = { - submitButtonType: 'primary', - submitButtonText: 'Save', - isOpen: false, -} - -export default Modal diff --git a/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js b/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js deleted file mode 100644 index 392a729e..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/TextInputModal.js +++ /dev/null @@ -1,70 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef, useState } from 'react' -import Modal from './Modal' -import { Form, FormGroup, TextInput } from '@patternfly/react-core' - -function TextInputModal({ title, label, isOpen, callback, initialValue }) { - const textInput = useRef(null) - const [isSubmitted, setSubmitted] = useState(false) - const [isValid, setValid] = useState(true) - - const resetState = () => { - textInput.current.value = '' - setSubmitted(false) - setValid(false) - } - const onSubmit = (event) => { - const value = textInput.current.value - setSubmitted(true) - - if (event) { - event.preventDefault() - } - - if (!value) { - setValid(false) - return false - } - - callback(value) - resetState() - return true - } - const onCancel = () => { - callback(undefined) - resetState() - } - - return ( - -
    - - - -
    -
    - ) -} - -TextInputModal.propTypes = { - title: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - isOpen: PropTypes.bool.isRequired, - callback: PropTypes.func.isRequired, - initialValue: PropTypes.string, -} - -export default TextInputModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js deleted file mode 100644 index afe07597..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewPortfolioModal.js +++ /dev/null @@ -1,139 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef, useState } from 'react' -import Modal from '../Modal' -import { - Form, - FormGroup, - FormSection, - NumberInput, - Select, - SelectGroup, - SelectOption, - SelectVariant, - TextInput, -} from '@patternfly/react-core' -import { METRIC_GROUPS, METRIC_NAMES } from '../../../util/available-metrics' - -const NewPortfolioModal = ({ isOpen, onSubmit: onSubmitUpstream, onCancel: onUpstreamCancel }) => { - const nameInput = useRef(null) - const [repeats, setRepeats] = useState(1) - const [isSelectOpen, setSelectOpen] = useState(false) - const [selectedMetrics, setSelectedMetrics] = useState([]) - - const [isSubmitted, setSubmitted] = useState(false) - const [errors, setErrors] = useState({}) - - const clearState = () => { - setSubmitted(false) - setErrors({}) - nameInput.current.value = '' - setRepeats(1) - setSelectOpen(false) - setSelectedMetrics([]) - } - - const onSubmit = (event) => { - setSubmitted(true) - - if (event) { - event.preventDefault() - } - - const name = nameInput.current.value - - if (!name) { - setErrors({ name: true }) - return false - } else { - onSubmitUpstream(name, { enabledMetrics: selectedMetrics, repeatsPerScenario: repeats }) - } - - clearState() - return false - } - const onCancel = () => { - onUpstreamCancel() - clearState() - } - - const onSelect = (event, selection) => { - if (selectedMetrics.includes(selection)) { - setSelectedMetrics((metrics) => metrics.filter((item) => item !== selection)) - } else { - setSelectedMetrics((metrics) => [...metrics, selection]) - } - } - - return ( - -
    - - - - - - - - - - - setRepeats(Number(e.target.value))} - onPlus={() => setRepeats((r) => r + 1)} - onMinus={() => setRepeats((r) => r - 1)} - min={1} - /> - - -
    -
    - ) -} - -NewPortfolioModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onSubmit: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, -} - -export default NewPortfolioModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js deleted file mode 100644 index 94d0d424..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewScenarioModal.js +++ /dev/null @@ -1,159 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef, useState } from 'react' -import { Portfolio } from '../../../shapes' -import Modal from '../Modal' -import { - Checkbox, - Form, - FormGroup, - FormSection, - FormSelect, - FormSelectOption, - NumberInput, - TextInput, -} from '@patternfly/react-core' -import { useSchedulers, useTraces } from '../../../data/experiments' -import { useProjectTopologies } from '../../../data/topology' -import { usePortfolio } from '../../../data/project' - -const NewScenarioModal = ({ portfolioId, isOpen, onSubmit: onSubmitUpstream, onCancel: onCancelUpstream }) => { - const { data: portfolio } = usePortfolio(portfolioId) - const { data: topologies = [] } = useProjectTopologies(portfolio?.projectId) - const { data: traces = [] } = useTraces() - const { data: schedulers = [] } = useSchedulers() - - const [isSubmitted, setSubmitted] = useState(false) - const [traceLoad, setTraceLoad] = useState(100) - const [trace, setTrace] = useState(undefined) - const [topology, setTopology] = useState(undefined) - const [scheduler, setScheduler] = useState(undefined) - const [failuresEnabled, setFailuresEnabled] = useState(false) - const [opPhenEnabled, setOpPhenEnabled] = useState(false) - const nameInput = useRef(null) - - const resetState = () => { - setSubmitted(false) - setTraceLoad(100) - setTrace(undefined) - setTopology(undefined) - setScheduler(undefined) - setFailuresEnabled(false) - setOpPhenEnabled(false) - nameInput.current.value = '' - } - - const onSubmit = (event) => { - setSubmitted(true) - - if (event) { - event.preventDefault() - } - - const name = nameInput.current.value - - onSubmitUpstream( - name, - portfolio._id, - { - traceId: trace || traces[0]._id, - loadSamplingFraction: traceLoad / 100, - }, - { - topologyId: topology || topologies[0]._id, - }, - { - failuresEnabled, - performanceInterferenceEnabled: opPhenEnabled, - schedulerName: scheduler || schedulers[0].name, - } - ) - - resetState() - return true - } - const onCancel = () => { - onCancelUpstream() - resetState() - } - - return ( - -
    - - - - - - - {traces.map((trace) => ( - - ))} - - - - setTraceLoad((load) => load - 1)} - onPlus={() => setTraceLoad((load) => load + 1)} - onChange={(e) => setTraceLoad(Number(e.target.value))} - unit="%" - /> - - - - - - {topologies.map((topology) => ( - - ))} - - - - - - {schedulers.map((scheduler) => ( - - ))} - - - - - setFailuresEnabled((e) => !e)} - /> - setOpPhenEnabled((e) => !e)} - /> - -
    -
    - ) -} - -NewScenarioModal.propTypes = { - portfolioId: PropTypes.string, - isOpen: PropTypes.bool.isRequired, - onSubmit: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, -} - -export default NewScenarioModal diff --git a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js b/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js deleted file mode 100644 index 49952aec..00000000 --- a/opendc-web/opendc-web-ui/src/components/modals/custom-components/NewTopologyModal.js +++ /dev/null @@ -1,81 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useRef, useState } from 'react' -import Modal from '../Modal' -import { Form, FormGroup, FormSelect, FormSelectOption, TextInput } from '@patternfly/react-core' -import { useProjectTopologies } from '../../../data/topology' - -const NewTopologyModal = ({ projectId, isOpen, onSubmit: onSubmitUpstream, onCancel: onCancelUpstream }) => { - const nameInput = useRef(null) - const [isSubmitted, setSubmitted] = useState(false) - const [originTopology, setOriginTopology] = useState(-1) - const [errors, setErrors] = useState({}) - - const { data: topologies = [] } = useProjectTopologies(projectId) - - const clearState = () => { - nameInput.current.value = '' - setSubmitted(false) - setOriginTopology(-1) - setErrors({}) - } - - const onSubmit = (event) => { - setSubmitted(true) - - if (event) { - event.preventDefault() - } - - const name = nameInput.current.value - - if (!name) { - setErrors({ name: true }) - return false - } else if (originTopology === -1) { - onSubmitUpstream(name) - } else { - onSubmitUpstream(name, originTopology) - } - - clearState() - return true - } - - const onCancel = () => { - onCancelUpstream() - clearState() - } - - return ( - -
    - - - - - - - {topologies.map((topology) => ( - - ))} - - -
    -
    - ) -} - -NewTopologyModal.propTypes = { - projectId: PropTypes.string, - isOpen: PropTypes.bool.isRequired, - onSubmit: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, -} - -export default NewTopologyModal diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/NewScenario.js b/opendc-web/opendc-web-ui/src/components/portfolios/NewScenario.js new file mode 100644 index 00000000..856282a7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/NewScenario.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { PlusIcon } from '@patternfly/react-icons' +import { Button } from '@patternfly/react-core' +import { useState } from 'react' +import { useMutation } from 'react-query' +import NewScenarioModal from './NewScenarioModal' + +function NewScenario({ portfolioId }) { + const [isVisible, setVisible] = useState(false) + const { mutate: addScenario } = useMutation('addScenario') + + const onSubmit = (name, portfolioId, trace, topology, operational) => { + addScenario({ + portfolioId, + name, + trace, + topology, + operational, + }) + setVisible(false) + } + + return ( + <> + + setVisible(false)} + /> + + ) +} + +NewScenario.propTypes = { + portfolioId: PropTypes.string, +} + +export default NewScenario diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/components/portfolios/NewScenarioModal.js new file mode 100644 index 00000000..7f620c8c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/NewScenarioModal.js @@ -0,0 +1,159 @@ +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import Modal from '../util/modals/Modal' +import { + Checkbox, + Form, + FormGroup, + FormSection, + FormSelect, + FormSelectOption, + NumberInput, + TextInput, +} from '@patternfly/react-core' +import { useSchedulers, useTraces } from '../../data/experiments' +import { useProjectTopologies } from '../../data/topology' +import { usePortfolio } from '../../data/project' + +const NewScenarioModal = ({ portfolioId, isOpen, onSubmit: onSubmitUpstream, onCancel: onCancelUpstream }) => { + const { data: portfolio } = usePortfolio(portfolioId) + const { data: topologies = [] } = useProjectTopologies(portfolio?.projectId) + const { data: traces = [] } = useTraces() + const { data: schedulers = [] } = useSchedulers() + + // eslint-disable-next-line no-unused-vars + const [isSubmitted, setSubmitted] = useState(false) + const [traceLoad, setTraceLoad] = useState(100) + const [trace, setTrace] = useState(undefined) + const [topology, setTopology] = useState(undefined) + const [scheduler, setScheduler] = useState(undefined) + const [failuresEnabled, setFailuresEnabled] = useState(false) + const [opPhenEnabled, setOpPhenEnabled] = useState(false) + const nameInput = useRef(null) + + const resetState = () => { + setSubmitted(false) + setTraceLoad(100) + setTrace(undefined) + setTopology(undefined) + setScheduler(undefined) + setFailuresEnabled(false) + setOpPhenEnabled(false) + nameInput.current.value = '' + } + + const onSubmit = (event) => { + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + + onSubmitUpstream( + name, + portfolio._id, + { + traceId: trace || traces[0]._id, + loadSamplingFraction: traceLoad / 100, + }, + { + topologyId: topology || topologies[0]._id, + }, + { + failuresEnabled, + performanceInterferenceEnabled: opPhenEnabled, + schedulerName: scheduler || schedulers[0].name, + } + ) + + resetState() + return true + } + const onCancel = () => { + onCancelUpstream() + resetState() + } + + return ( + +
    + + + + + + + {traces.map((trace) => ( + + ))} + + + + setTraceLoad((load) => load - 1)} + onPlus={() => setTraceLoad((load) => load + 1)} + onChange={(e) => setTraceLoad(Number(e.target.value))} + unit="%" + /> + + + + + + {topologies.map((topology) => ( + + ))} + + + + + + {schedulers.map((scheduler) => ( + + ))} + + + + + setFailuresEnabled((e) => !e)} + /> + setOpPhenEnabled((e) => !e)} + /> + +
    +
    + ) +} + +NewScenarioModal.propTypes = { + portfolioId: PropTypes.string, + isOpen: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +} + +export default NewScenarioModal diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioState.js b/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioState.js new file mode 100644 index 00000000..66691580 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioState.js @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { ClockIcon, CheckCircleIcon, ErrorCircleOIcon } from '@patternfly/react-icons' + +function ScenarioState({ state }) { + switch (state) { + case 'CLAIMED': + case 'QUEUED': + return ( + + Queued + + ) + case 'RUNNING': + return ( + + Running + + ) + case 'FINISHED': + return ( + + Finished + + ) + case 'FAILED': + return ( + + Failed + + ) + } + + return 'Unknown' +} + +ScenarioState.propTypes = { + state: PropTypes.oneOf(['QUEUED', 'CLAIMED', 'RUNNING', 'FINISHED', 'FAILED']), +} + +export default ScenarioState diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js b/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js new file mode 100644 index 00000000..9966e3ba --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import Link from 'next/link' +import { Table, TableBody, TableHeader } from '@patternfly/react-table' +import React from 'react' +import TableEmptyState from '../util/TableEmptyState' +import ScenarioState from './ScenarioState' +import { usePortfolio, usePortfolioScenarios } from '../../data/project' +import { useProjectTopologies } from '../../data/topology' +import { useMutation } from 'react-query' + +const ScenarioTable = ({ portfolioId }) => { + const { data: portfolio } = usePortfolio(portfolioId) + const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) + const { data: topologies } = useProjectTopologies(portfolio?.projectId, { + select: (topologies) => new Map(topologies.map((topology) => [topology._id, topology])), + }) + + const { mutate: deleteScenario } = useMutation('deleteScenario') + + const columns = ['Name', 'Topology', 'Trace', 'State'] + const rows = + scenarios.length > 0 + ? scenarios.map((scenario) => { + const topology = topologies?.get(scenario.topology.topologyId) + + return [ + scenario.name, + { + title: topology ? ( + + {topology.name} + + ) : ( + 'Unknown Topology' + ), + }, + scenario.trace.traceId, + { title: }, + ] + }) + : [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 4 }, + title: ( + + ), + }, + ], + }, + ] + + const actionResolver = (_, { rowIndex }) => [ + { + title: 'Delete Scenario', + onClick: (_, rowId) => deleteScenario(scenarios[rowId]._id), + isDisabled: rowIndex === 0, + }, + ] + + return ( + 0 ? actionResolver : undefined} + > + + +
    + ) +} + +ScenarioTable.propTypes = { + portfolioId: PropTypes.string, +} + +export default ScenarioTable diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js new file mode 100644 index 00000000..09348e60 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { Tooltip } from '@patternfly/react-core' +import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' +import { METRIC_DESCRIPTIONS } from '../../../util/available-metrics' + +function PortfolioResultInfo({ metric }) { + return ( + {METRIC_DESCRIPTIONS[metric]}
    }> + + + ) +} + +PortfolioResultInfo.propTypes = { + metric: PropTypes.string.isRequired, +} + +export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js new file mode 100644 index 00000000..f1883e68 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js @@ -0,0 +1,134 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' +import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_UNITS } from '../../../util/available-metrics' +import { mean, std } from 'mathjs' +import approx from 'approximate-number' +import { + Bullseye, + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + Grid, + GridItem, + Spinner, + Title, +} from '@patternfly/react-core' +import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' +import { usePortfolioScenarios } from '../../../data/project' +import PortfolioResultInfo from './PortfolioResultInfo' +import NewScenario from '../NewScenario' + +const PortfolioResults = ({ portfolioId }) => { + const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) + + if (status === 'loading') { + return ( + + + + + Loading Results + + + + ) + } else if (status === 'error') { + return ( + + + + + Unable to connect + + + There was an error retrieving data. Check your connection and try again. + + + + ) + } else if (scenarios.length === 0) { + return ( + + + + + No results + + + No results are currently available for this portfolio. Run a scenario to obtain simulation + results. + + + + + ) + } + + const dataPerMetric = {} + + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios + .filter((scenario) => scenario.results) + .map((scenario) => ({ + name: scenario.name, + value: mean(scenario.results[metric]), + errorX: std(scenario.results[metric]), + })) + }) + + return ( + + {AVAILABLE_METRICS.map((metric) => ( + + + + + + + {METRIC_NAMES[metric]} + + + + + + approx(tick)} + label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} + type="number" + /> + + + + + + + + + + + ))} + + ) +} + +PortfolioResults.propTypes = { + portfolioId: PropTypes.string, +} + +export default PortfolioResults diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js b/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js index ae4cb9cd..87ea059d 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js +++ b/opendc-web/opendc-web-ui/src/components/projects/NewPortfolio.js @@ -24,8 +24,8 @@ import PropTypes from 'prop-types' import { PlusIcon } from '@patternfly/react-icons' import { Button } from '@patternfly/react-core' import { useState } from 'react' -import NewPortfolioModal from '../modals/custom-components/NewPortfolioModal' import { useMutation } from 'react-query' +import NewPortfolioModal from './NewPortfolioModal' function NewPortfolio({ projectId }) { const [isVisible, setVisible] = useState(false) diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewPortfolioModal.js b/opendc-web/opendc-web-ui/src/components/projects/NewPortfolioModal.js new file mode 100644 index 00000000..4276d7d4 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewPortfolioModal.js @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import { + Form, + FormGroup, + FormSection, + NumberInput, + Select, + SelectGroup, + SelectOption, + SelectVariant, + TextInput, +} from '@patternfly/react-core' +import Modal from '../util/modals/Modal' +import { METRIC_GROUPS, METRIC_NAMES } from '../../util/available-metrics' + +const NewPortfolioModal = ({ isOpen, onSubmit: onSubmitUpstream, onCancel: onUpstreamCancel }) => { + const nameInput = useRef(null) + const [repeats, setRepeats] = useState(1) + const [isSelectOpen, setSelectOpen] = useState(false) + const [selectedMetrics, setSelectedMetrics] = useState([]) + + const [isSubmitted, setSubmitted] = useState(false) + const [errors, setErrors] = useState({}) + + const clearState = () => { + setSubmitted(false) + setErrors({}) + nameInput.current.value = '' + setRepeats(1) + setSelectOpen(false) + setSelectedMetrics([]) + } + + const onSubmit = (event) => { + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + + if (!name) { + setErrors({ name: true }) + return false + } else { + onSubmitUpstream(name, { enabledMetrics: selectedMetrics, repeatsPerScenario: repeats }) + } + + clearState() + return false + } + const onCancel = () => { + onUpstreamCancel() + clearState() + } + + const onSelect = (event, selection) => { + if (selectedMetrics.includes(selection)) { + setSelectedMetrics((metrics) => metrics.filter((item) => item !== selection)) + } else { + setSelectedMetrics((metrics) => [...metrics, selection]) + } + } + + return ( + +
    + + + + + + + + + + + setRepeats(Number(e.target.value))} + onPlus={() => setRepeats((r) => r + 1)} + onMinus={() => setRepeats((r) => r - 1)} + min={1} + /> + + +
    +
    + ) +} + +NewPortfolioModal.propTypes = { + isOpen: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +} + +export default NewPortfolioModal diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewProject.js b/opendc-web/opendc-web-ui/src/components/projects/NewProject.js index 4f5d79cf..984264dc 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/NewProject.js +++ b/opendc-web/opendc-web-ui/src/components/projects/NewProject.js @@ -1,9 +1,9 @@ import React, { useState } from 'react' -import TextInputModal from '../../components/modals/TextInputModal' import { Button } from '@patternfly/react-core' import { useMutation } from 'react-query' import { PlusIcon } from '@patternfly/react-icons' import { buttonContainer } from './NewProject.module.scss' +import TextInputModal from '../util/modals/TextInputModal' /** * A container for creating a new project. diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewScenario.js b/opendc-web/opendc-web-ui/src/components/projects/NewScenario.js deleted file mode 100644 index 6d4f48c1..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/NewScenario.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import { PlusIcon } from '@patternfly/react-icons' -import { Button } from '@patternfly/react-core' -import { useState } from 'react' -import NewScenarioModal from '../modals/custom-components/NewScenarioModal' -import { useMutation } from 'react-query' - -function NewScenario({ portfolioId }) { - const [isVisible, setVisible] = useState(false) - const { mutate: addScenario } = useMutation('addScenario') - - const onSubmit = (name, portfolioId, trace, topology, operational) => { - addScenario({ - portfolioId, - name, - trace, - topology, - operational, - }) - setVisible(false) - } - - return ( - <> - - setVisible(false)} - /> - - ) -} - -NewScenario.propTypes = { - portfolioId: PropTypes.string, -} - -export default NewScenario diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js b/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js index c6c4171b..bf59e020 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js +++ b/opendc-web/opendc-web-ui/src/components/projects/NewTopology.js @@ -24,9 +24,9 @@ import PropTypes from 'prop-types' import { PlusIcon } from '@patternfly/react-icons' import { Button } from '@patternfly/react-core' import { useState } from 'react' -import NewTopologyModal from '../modals/custom-components/NewTopologyModal' import { useDispatch } from 'react-redux' import { addTopology } from '../../redux/actions/topologies' +import NewTopologyModal from './NewTopologyModal' function NewTopology({ projectId }) { const [isVisible, setVisible] = useState(false) diff --git a/opendc-web/opendc-web-ui/src/components/projects/NewTopologyModal.js b/opendc-web/opendc-web-ui/src/components/projects/NewTopologyModal.js new file mode 100644 index 00000000..a495f73e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/NewTopologyModal.js @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import { Form, FormGroup, FormSelect, FormSelectOption, TextInput } from '@patternfly/react-core' +import { useProjectTopologies } from '../../data/topology' +import Modal from '../util/modals/Modal' + +const NewTopologyModal = ({ projectId, isOpen, onSubmit: onSubmitUpstream, onCancel: onCancelUpstream }) => { + const nameInput = useRef(null) + const [isSubmitted, setSubmitted] = useState(false) + const [originTopology, setOriginTopology] = useState(-1) + const [errors, setErrors] = useState({}) + + const { data: topologies = [] } = useProjectTopologies(projectId) + + const clearState = () => { + nameInput.current.value = '' + setSubmitted(false) + setOriginTopology(-1) + setErrors({}) + } + + const onSubmit = (event) => { + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + + if (!name) { + setErrors({ name: true }) + return false + } else if (originTopology === -1) { + onSubmitUpstream(name) + } else { + onSubmitUpstream(name, originTopology) + } + + clearState() + return true + } + + const onCancel = () => { + onCancelUpstream() + clearState() + } + + return ( + +
    + + + + + + + {topologies.map((topology) => ( + + ))} + + +
    +
    + ) +} + +NewTopologyModal.propTypes = { + projectId: PropTypes.string, + isOpen: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +} + +export default NewTopologyModal diff --git a/opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js b/opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js deleted file mode 100644 index 285345e7..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/ScenarioState.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import { ClockIcon, InfoIcon, CheckCircleIcon, ErrorCircleOIcon } from '@patternfly/react-icons' - -function ScenarioState({ state }) { - switch (state) { - case 'CLAIMED': - case 'QUEUED': - return ( - - Queued - - ) - case 'RUNNING': - return ( - - Running - - ) - case 'FINISHED': - return ( - - Finished - - ) - case 'FAILED': - return ( - - Failed - - ) - } - - return 'Unknown' -} - -ScenarioState.propTypes = { - state: PropTypes.oneOf(['QUEUED', 'CLAIMED', 'RUNNING', 'FINISHED', 'FAILED']), -} - -export default ScenarioState diff --git a/opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js b/opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js deleted file mode 100644 index 9966e3ba..00000000 --- a/opendc-web/opendc-web-ui/src/components/projects/ScenarioTable.js +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import Link from 'next/link' -import { Table, TableBody, TableHeader } from '@patternfly/react-table' -import React from 'react' -import TableEmptyState from '../util/TableEmptyState' -import ScenarioState from './ScenarioState' -import { usePortfolio, usePortfolioScenarios } from '../../data/project' -import { useProjectTopologies } from '../../data/topology' -import { useMutation } from 'react-query' - -const ScenarioTable = ({ portfolioId }) => { - const { data: portfolio } = usePortfolio(portfolioId) - const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) - const { data: topologies } = useProjectTopologies(portfolio?.projectId, { - select: (topologies) => new Map(topologies.map((topology) => [topology._id, topology])), - }) - - const { mutate: deleteScenario } = useMutation('deleteScenario') - - const columns = ['Name', 'Topology', 'Trace', 'State'] - const rows = - scenarios.length > 0 - ? scenarios.map((scenario) => { - const topology = topologies?.get(scenario.topology.topologyId) - - return [ - scenario.name, - { - title: topology ? ( - - {topology.name} - - ) : ( - 'Unknown Topology' - ), - }, - scenario.trace.traceId, - { title: }, - ] - }) - : [ - { - heightAuto: true, - cells: [ - { - props: { colSpan: 4 }, - title: ( - - ), - }, - ], - }, - ] - - const actionResolver = (_, { rowIndex }) => [ - { - title: 'Delete Scenario', - onClick: (_, rowId) => deleteScenario(scenarios[rowId]._id), - isDisabled: rowIndex === 0, - }, - ] - - return ( - 0 ? actionResolver : undefined} - > - - -
    - ) -} - -ScenarioTable.propTypes = { - portfolioId: PropTypes.string, -} - -export default ScenarioTable diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js new file mode 100644 index 00000000..ccf637e5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch } from 'react-redux' +import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' +import GrayLayer from './elements/GrayLayer' + +function GrayContainer() { + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + return +} + +export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js b/opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js new file mode 100644 index 00000000..4c3b2757 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js @@ -0,0 +1,25 @@ +export const MAP_SIZE = 50 +export const TILE_SIZE_IN_PIXELS = 100 +export const TILE_SIZE_IN_METERS = 0.5 +export const MAP_SIZE_IN_PIXELS = MAP_SIZE * TILE_SIZE_IN_PIXELS + +export const OBJECT_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 5 +export const TILE_PLUS_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 3 +export const OBJECT_SIZE_IN_PIXELS = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 + +export const GRID_LINE_WIDTH_IN_PIXELS = 2 +export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 +export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 +export const TILE_PLUS_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 10 + +export const RACK_FILL_ICON_WIDTH = OBJECT_SIZE_IN_PIXELS / 3 +export const RACK_FILL_ICON_OPACITY = 0.8 + +export const MAP_MOVE_PIXELS_PER_EVENT = 20 +export const MAP_SCALE_PER_EVENT = 1.1 +export const MAP_MIN_SCALE = 0.5 +export const MAP_MAX_SCALE = 1.5 + +export const MAX_NUM_UNITS_PER_MACHINE = 6 +export const DEFAULT_RACK_SLOT_CAPACITY = 42 +export const DEFAULT_RACK_POWER_CAPACITY = 10000 diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js new file mode 100644 index 00000000..5d19b3ad --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js @@ -0,0 +1,83 @@ +import React, { useRef, useState } from 'react' +import { HotKeys } from 'react-hotkeys' +import { Stage } from 'react-konva' +import { MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_MOVE_PIXELS_PER_EVENT, MAP_SCALE_PER_EVENT } from './MapConstants' +import { Provider, useStore } from 'react-redux' +import useResizeObserver from 'use-resize-observer' +import { mapContainer } from './MapStage.module.scss' +import MapLayer from './layers/MapLayer' +import RoomHoverLayer from './layers/RoomHoverLayer' +import ObjectHoverLayer from './layers/ObjectHoverLayer' +import ScaleIndicator from './controls/ScaleIndicator' +import Toolbar from './controls/Toolbar' + +function MapStage() { + const store = useStore() + const { ref, width = 100, height = 100 } = useResizeObserver() + const stageRef = useRef(null) + const [[x, y], setPos] = useState([0, 0]) + const [scale, setScale] = useState(1) + + const clampScale = (target) => Math.min(Math.max(target, MAP_MIN_SCALE), MAP_MAX_SCALE) + const moveWithDelta = (deltaX, deltaY) => setPos(([x, y]) => [x + deltaX, y + deltaY]) + + const onZoom = (e) => { + e.evt.preventDefault() + + const stage = stageRef.current.getStage() + const oldScale = scale + + const pointer = stage.getPointerPosition() + const mousePointTo = { + x: (pointer.x - x) / oldScale, + y: (pointer.y - y) / oldScale, + } + + const newScale = clampScale(e.evt.deltaY > 0 ? oldScale * MAP_SCALE_PER_EVENT : oldScale / MAP_SCALE_PER_EVENT) + + setScale(newScale) + setPos([pointer.x - mousePointTo.x * newScale, pointer.y - mousePointTo.y * newScale]) + } + const onZoomButton = (zoomIn) => + setScale((scale) => clampScale(zoomIn ? scale * MAP_SCALE_PER_EVENT : scale / MAP_SCALE_PER_EVENT)) + const onDragEnd = (e) => setPos([e.target.x(), e.target.y()]) + const onExport = () => { + const download = document.createElement('a') + download.href = stageRef.current.getStage().toDataURL() + download.download = 'opendc-canvas-export-' + Date.now() + '.png' + download.click() + } + + const handlers = { + MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), + MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), + MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), + } + + return ( + + + + + + + + + + + + ) +} + +export default MapStage diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss new file mode 100644 index 00000000..d879b4c8 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss @@ -0,0 +1,31 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.mapContainer { + background-color: var(--pf-global--Color--light-200); + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; +} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js new file mode 100644 index 00000000..14449a91 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import { Tile } from '../../../shapes' +import RackGroup from './groups/RackGroup' + +function RackContainer({ tile }) { + const interactionLevel = useSelector((state) => state.interactionLevel) + return +} + +RackContainer.propTypes = { + tile: Tile, +} + +export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js new file mode 100644 index 00000000..c35cbde7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js @@ -0,0 +1,34 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' +import RackFillBar from './elements/RackFillBar' + +function RackSpaceFillContainer({ tileId, ...props }) { + const fillFraction = useSelector((state) => { + let energyConsumptionTotal = 0 + const rack = state.objects.rack[state.objects.tile[tileId].rack] + const machineIds = rack.machines + machineIds.forEach((machineId) => { + if (machineId !== null) { + const machine = state.objects.machine[machineId] + machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) + machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) + machine.memories.forEach( + (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) + ) + machine.storages.forEach( + (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) + ) + } + }) + + return Math.min(1, energyConsumptionTotal / rack.powerCapacityW) + }) + return +} + +RackSpaceFillContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js new file mode 100644 index 00000000..a6766f33 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' +import RackFillBar from './elements/RackFillBar' + +function RackSpaceFillContainer({ tileId, ...props }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + return +} + +RackSpaceFillContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js new file mode 100644 index 00000000..93ba9c93 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' +import RoomGroup from './groups/RoomGroup' + +function RoomContainer({ roomId, ...props }) { + const state = useSelector((state) => { + return { + interactionLevel: state.interactionLevel, + currentRoomInConstruction: state.construction.currentRoomInConstruction, + room: state.objects.room[roomId], + } + }) + const dispatch = useDispatch() + return dispatch(goFromBuildingToRoom(roomId))} /> +} + +RoomContainer.propTypes = { + roomId: PropTypes.string, +} + +export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js new file mode 100644 index 00000000..149e26a1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { useDispatch, useSelector } from 'react-redux' +import { goFromRoomToRack } from '../../../redux/actions/interaction-level' +import TileGroup from './groups/TileGroup' + +function TileContainer({ tileId, ...props }) { + const interactionLevel = useSelector((state) => state.interactionLevel) + const tile = useSelector((state) => state.objects.tile[tileId]) + + const dispatch = useDispatch() + const onClick = (tile) => { + if (tile.rack) { + dispatch(goFromRoomToRack(tile._id)) + } + } + return +} + +TileContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js new file mode 100644 index 00000000..eaebabd5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useSelector } from 'react-redux' +import { useActiveTopology } from '../../../data/topology' +import TopologyGroup from './groups/TopologyGroup' + +function TopologyContainer() { + const topology = useActiveTopology() + const interactionLevel = useSelector((state) => state.interactionLevel) + + return +} + +export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js new file mode 100644 index 00000000..77f553dd --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { useSelector } from 'react-redux' +import WallGroup from './groups/WallGroup' + +function WallContainer({ roomId, ...props }) { + const tiles = useSelector((state) => state.objects.room[roomId].tiles.map((tileId) => state.objects.tile[tileId])) + return +} + +WallContainer.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js new file mode 100644 index 00000000..f54b7c84 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { ChevronLeftIcon } from '@patternfly/react-icons' +import { collapseContainer } from './Collapse.module.scss' +import { Button } from '@patternfly/react-core' + +function Collapse({ onClick }) { + return ( +
    + +
    + ) +} + +Collapse.propTypes = { + onClick: PropTypes.func, +} + +export default Collapse diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.scss new file mode 100644 index 00000000..0c1fac94 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.scss @@ -0,0 +1,55 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.collapseContainer { + position: absolute; + right: var(--pf-global--spacer--xs); + top: 0; + bottom: 10%; + margin: auto 0; + height: 50px; + + button:global(.pf-m-tertiary) { + height: 100%; + padding: 2px; + + margin-right: var(--pf-global--spacer--xs); + margin-top: var(--pf-global--spacer--xs); + background-color: var(--pf-global--BackgroundColor--100); + border: none; + border-radius: var(--pf-global--BorderRadius--sm); + box-shadow: var(--pf-global--BoxShadow--sm); + + &:not(:global(.pf-m-disabled)) { + background-color: var(--pf-global--BackgroundColor--100); + } + + &:after { + display: none; + } + + &:hover { + border: none; + box-shadow: var(--pf-global--BoxShadow--md); + } + } +} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js new file mode 100644 index 00000000..58d2ccc9 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js @@ -0,0 +1,18 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from '../MapConstants' +import { scaleIndicator } from './ScaleIndicator.module.scss' + +function ScaleIndicator({ scale }) { + return ( +
    + {TILE_SIZE_IN_METERS}m +
    + ) +} + +ScaleIndicator.propTypes = { + scale: PropTypes.number.isRequired, +} + +export default ScaleIndicator diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.scss new file mode 100644 index 00000000..f19e0ff2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.scss @@ -0,0 +1,10 @@ +.scaleIndicator { + position: absolute; + right: 10px; + bottom: 10px; + z-index: 50; + + border: solid 2px #212529; + border-top: none; + border-left: none; +} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js new file mode 100644 index 00000000..469fd515 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js @@ -0,0 +1,35 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { control, toolBar } from './Toolbar.module.scss' +import { Button } from '@patternfly/react-core' +import { SearchPlusIcon, SearchMinusIcon } from '@patternfly/react-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faCamera } from '@fortawesome/free-solid-svg-icons' + +function Toolbar({ onZoom, onExport }) { + return ( +
    + + + +
    + ) +} + +Toolbar.propTypes = { + onZoom: PropTypes.func, + onExport: PropTypes.func, +} + +export default Toolbar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.scss new file mode 100644 index 00000000..0d505acc --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.scss @@ -0,0 +1,29 @@ +.toolBar { + position: absolute; + bottom: var(--pf-global--spacer--md); + left: var(--pf-global--spacer--xl); +} + +.control { + &:global(.pf-m-tertiary) { + margin-right: var(--pf-global--spacer--xs); + margin-top: var(--pf-global--spacer--xs); + background-color: var(--pf-global--BackgroundColor--100); + border: none; + border-radius: var(--pf-global--BorderRadius--sm); + box-shadow: var(--pf-global--BoxShadow--sm); + + &:not(:global(.pf-m-disabled)) { + background-color: var(--pf-global--BackgroundColor--100); + } + + &:after { + display: none; + } + + &:hover { + border: none; + box-shadow: var(--pf-global--BoxShadow--md); + } + } +} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js new file mode 100644 index 00000000..93037b51 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js @@ -0,0 +1,10 @@ +import React from 'react' +import { Rect } from 'react-konva' +import { BACKDROP_COLOR } from '../../../../util/colors' +import { MAP_SIZE_IN_PIXELS } from '../MapConstants' + +function Backdrop() { + return +} + +export default Backdrop diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js new file mode 100644 index 00000000..08c687f6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js @@ -0,0 +1,24 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Rect } from 'react-konva' +import { GRAYED_OUT_AREA_COLOR } from '../../../../util/colors' +import { MAP_SIZE_IN_PIXELS } from '../MapConstants' + +function GrayLayer({ onClick }) { + return ( + + ) +} + +GrayLayer.propTypes = { + onClick: PropTypes.func, +} + +export default GrayLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js new file mode 100644 index 00000000..20c2c6d1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js @@ -0,0 +1,30 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Rect } from 'react-konva' +import { ROOM_HOVER_INVALID_COLOR, ROOM_HOVER_VALID_COLOR } from '../../../../util/colors' +import { TILE_SIZE_IN_PIXELS } from '../MapConstants' + +function HoverTile({ x, y, isValid, scale = 1, onClick }) { + return ( + + ) +} + +HoverTile.propTypes = { + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + isValid: PropTypes.bool.isRequired, + scale: PropTypes.number, + onClick: PropTypes.func.isRequired, +} + +export default HoverTile diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js new file mode 100644 index 00000000..7d304b6b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types' +import React, { useEffect, useState } from 'react' +import { Image } from 'react-konva' + +const imageCaches = {} + +function ImageComponent({ src, x, y, width, height, opacity }) { + const [image, setImage] = useState(null) + + useEffect(() => { + if (imageCaches[src]) { + setImage(imageCaches[src]) + return + } + + const image = new window.Image() + image.src = src + image.onload = () => { + setImage(image) + imageCaches[src] = image + } + }, [src]) + + return +} + +ImageComponent.propTypes = { + src: PropTypes.string.isRequired, + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + opacity: PropTypes.number.isRequired, +} + +export default ImageComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js new file mode 100644 index 00000000..aa284944 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js @@ -0,0 +1,68 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Group, Rect } from 'react-konva' +import { + RACK_ENERGY_BAR_BACKGROUND_COLOR, + RACK_ENERGY_BAR_FILL_COLOR, + RACK_SPACE_BAR_BACKGROUND_COLOR, + RACK_SPACE_BAR_FILL_COLOR, +} from '../../../../util/colors' +import { + OBJECT_BORDER_WIDTH_IN_PIXELS, + OBJECT_MARGIN_IN_PIXELS, + RACK_FILL_ICON_OPACITY, + RACK_FILL_ICON_WIDTH, + TILE_SIZE_IN_PIXELS, +} from '../MapConstants' +import ImageComponent from './ImageComponent' + +function RackFillBar({ positionX, positionY, type, fillFraction }) { + const halfOfObjectBorderWidth = OBJECT_BORDER_WIDTH_IN_PIXELS / 2 + const x = + positionX * TILE_SIZE_IN_PIXELS + + OBJECT_MARGIN_IN_PIXELS + + (type === 'space' ? halfOfObjectBorderWidth : 0.5 * (TILE_SIZE_IN_PIXELS - 2 * OBJECT_MARGIN_IN_PIXELS)) + const startY = positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS + halfOfObjectBorderWidth + const width = 0.5 * (TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2) - halfOfObjectBorderWidth + const fullHeight = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 - OBJECT_BORDER_WIDTH_IN_PIXELS + + const fractionHeight = fillFraction * fullHeight + const fractionY = + (positionY + 1) * TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS - halfOfObjectBorderWidth - fractionHeight + + return ( + + + + + + ) +} + +RackFillBar.propTypes = { + positionX: PropTypes.number.isRequired, + positionY: PropTypes.number.isRequired, + type: PropTypes.string.isRequired, + fillFraction: PropTypes.number.isRequired, +} + +export default RackFillBar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js new file mode 100644 index 00000000..e7329dc0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js @@ -0,0 +1,24 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Rect } from 'react-konva' +import { Tile } from '../../../../shapes' +import { TILE_SIZE_IN_PIXELS } from '../MapConstants' + +function RoomTile({ tile, color }) { + return ( + + ) +} + +RoomTile.propTypes = { + tile: Tile, + color: PropTypes.string, +} + +export default RoomTile diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js new file mode 100644 index 00000000..3211f187 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Rect } from 'react-konva' +import { OBJECT_BORDER_COLOR } from '../../../../util/colors' +import { OBJECT_BORDER_WIDTH_IN_PIXELS, OBJECT_MARGIN_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' + +function TileObject({ positionX, positionY, color }) { + return ( + + ) +} + +TileObject.propTypes = { + positionX: PropTypes.number.isRequired, + positionY: PropTypes.number.isRequired, + color: PropTypes.string.isRequired, +} + +export default TileObject diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js new file mode 100644 index 00000000..186c2b3a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js @@ -0,0 +1,44 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Group, Line } from 'react-konva' +import { TILE_PLUS_COLOR } from '../../../../util/colors' +import { TILE_PLUS_MARGIN_IN_PIXELS, TILE_PLUS_WIDTH_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' + +function TilePlusIcon({ x, y, scale = 1 }) { + const linePoints = [ + [ + x + 0.5 * TILE_SIZE_IN_PIXELS * scale, + y + TILE_PLUS_MARGIN_IN_PIXELS * scale, + x + 0.5 * TILE_SIZE_IN_PIXELS * scale, + y + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, + ], + [ + x + TILE_PLUS_MARGIN_IN_PIXELS * scale, + y + 0.5 * TILE_SIZE_IN_PIXELS * scale, + x + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, + y + 0.5 * TILE_SIZE_IN_PIXELS * scale, + ], + ] + return ( + + {linePoints.map((points, index) => ( + + ))} + + ) +} + +TilePlusIcon.propTypes = { + x: PropTypes.number, + y: PropTypes.number, + scale: PropTypes.number, +} + +export default TilePlusIcon diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js new file mode 100644 index 00000000..4f18813e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js @@ -0,0 +1,32 @@ +import React from 'react' +import { Line } from 'react-konva' +import { WallSegment as WallSegmentShape } from '../../../../shapes' +import { WALL_COLOR } from '../../../../util/colors' +import { TILE_SIZE_IN_PIXELS, WALL_WIDTH_IN_PIXELS } from '../MapConstants' + +function WallSegment({ wallSegment }) { + let points + if (wallSegment.isHorizontal) { + points = [ + wallSegment.startPosX * TILE_SIZE_IN_PIXELS, + wallSegment.startPosY * TILE_SIZE_IN_PIXELS, + (wallSegment.startPosX + wallSegment.length) * TILE_SIZE_IN_PIXELS, + wallSegment.startPosY * TILE_SIZE_IN_PIXELS, + ] + } else { + points = [ + wallSegment.startPosX * TILE_SIZE_IN_PIXELS, + wallSegment.startPosY * TILE_SIZE_IN_PIXELS, + wallSegment.startPosX * TILE_SIZE_IN_PIXELS, + (wallSegment.startPosY + wallSegment.length) * TILE_SIZE_IN_PIXELS, + ] + } + + return +} + +WallSegment.propTypes = { + wallSegment: WallSegmentShape, +} + +export default WallSegment diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js new file mode 100644 index 00000000..d66a18de --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js @@ -0,0 +1,36 @@ +import React from 'react' +import { Group, Line } from 'react-konva' +import { GRID_COLOR } from '../../../../util/colors' +import { GRID_LINE_WIDTH_IN_PIXELS, MAP_SIZE, MAP_SIZE_IN_PIXELS, TILE_SIZE_IN_PIXELS } from '../MapConstants' + +const MAP_COORDINATE_ENTRIES = Array.from(new Array(MAP_SIZE), (x, i) => i) +const HORIZONTAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map((index) => [ + 0, + index * TILE_SIZE_IN_PIXELS, + MAP_SIZE_IN_PIXELS, + index * TILE_SIZE_IN_PIXELS, +]) +const VERTICAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map((index) => [ + index * TILE_SIZE_IN_PIXELS, + 0, + index * TILE_SIZE_IN_PIXELS, + MAP_SIZE_IN_PIXELS, +]) + +function GridGroup() { + return ( + + {HORIZONTAL_POINT_PAIRS.concat(VERTICAL_POINT_PAIRS).map((points, index) => ( + + ))} + + ) +} + +export default GridGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js new file mode 100644 index 00000000..46030135 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js @@ -0,0 +1,25 @@ +import React from 'react' +import { Group } from 'react-konva' +import { Tile } from '../../../../shapes' +import { RACK_BACKGROUND_COLOR } from '../../../../util/colors' +import TileObject from '../elements/TileObject' +import RackSpaceFillContainer from '../RackSpaceFillContainer' +import RackEnergyFillContainer from '../RackEnergyFillContainer' + +function RackGroup({ tile }) { + return ( + + + + + + + + ) +} + +RackGroup.propTypes = { + tile: Tile, +} + +export default RackGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js new file mode 100644 index 00000000..a42e7bb7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js @@ -0,0 +1,52 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Group } from 'react-konva' +import { InteractionLevel, Room } from '../../../../shapes' +import GrayContainer from '../GrayContainer' +import TileContainer from '../TileContainer' +import WallContainer from '../WallContainer' + +function RoomGroup({ room, interactionLevel, currentRoomInConstruction, onClick }) { + if (currentRoomInConstruction === room._id) { + return ( + + {room.tiles.map((tileId) => ( + + ))} + + ) + } + + return ( + + {(() => { + if ( + (interactionLevel.mode === 'RACK' || interactionLevel.mode === 'MACHINE') && + interactionLevel.roomId === room._id + ) { + return [ + room.tiles + .filter((tileId) => tileId !== interactionLevel.tileId) + .map((tileId) => ), + , + room.tiles + .filter((tileId) => tileId === interactionLevel.tileId) + .map((tileId) => ), + ] + } else { + return room.tiles.map((tileId) => ) + } + })()} + + + ) +} + +RoomGroup.propTypes = { + room: Room, + interactionLevel: InteractionLevel, + currentRoomInConstruction: PropTypes.string, + onClick: PropTypes.func, +} + +export default RoomGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js new file mode 100644 index 00000000..f2084017 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Group } from 'react-konva' +import { Tile } from '../../../../shapes' +import { ROOM_DEFAULT_COLOR, ROOM_IN_CONSTRUCTION_COLOR } from '../../../../util/colors' +import RoomTile from '../elements/RoomTile' +import RackContainer from '../RackContainer' + +function TileGroup({ tile, newTile, onClick }) { + let tileObject + if (tile.rack) { + tileObject = + } else { + tileObject = null + } + + let color = ROOM_DEFAULT_COLOR + if (newTile) { + color = ROOM_IN_CONSTRUCTION_COLOR + } + + return ( + onClick(tile)}> + + {tileObject} + + ) +} + +TileGroup.propTypes = { + tile: Tile, + newTile: PropTypes.bool, + onClick: PropTypes.func, +} + +export default TileGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js new file mode 100644 index 00000000..011dcf34 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js @@ -0,0 +1,44 @@ +import React from 'react' +import { Group } from 'react-konva' +import { InteractionLevel, Topology } from '../../../../shapes' +import RoomContainer from '../RoomContainer' +import GrayContainer from '../GrayContainer' + +function TopologyGroup({ topology, interactionLevel }) { + if (!topology) { + return + } + + if (interactionLevel.mode === 'BUILDING') { + return ( + + {topology.rooms.map((roomId) => ( + + ))} + + ) + } + + return ( + + {topology.rooms + .filter((roomId) => roomId !== interactionLevel.roomId) + .map((roomId) => ( + + ))} + {interactionLevel.mode === 'ROOM' ? : null} + {topology.rooms + .filter((roomId) => roomId === interactionLevel.roomId) + .map((roomId) => ( + + ))} + + ) +} + +TopologyGroup.propTypes = { + topology: Topology, + interactionLevel: InteractionLevel, +} + +export default TopologyGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js new file mode 100644 index 00000000..6cbd1cd0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Group } from 'react-konva' +import { Tile } from '../../../../shapes' +import { deriveWallLocations } from '../../../../util/tile-calculations' +import WallSegment from '../elements/WallSegment' + +function WallGroup({ tiles }) { + return ( + + {deriveWallLocations(tiles).map((wallSegment, index) => ( + + ))} + + ) +} + +WallGroup.propTypes = { + tiles: PropTypes.arrayOf(Tile).isRequired, +} + +export default WallGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js new file mode 100644 index 00000000..2b1060c0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js @@ -0,0 +1,55 @@ +import PropTypes from 'prop-types' +import React, { useMemo, useState } from 'react' +import { Layer } from 'react-konva/lib/ReactKonva' +import HoverTile from '../elements/HoverTile' +import { TILE_SIZE_IN_PIXELS } from '../MapConstants' +import { useEffectRef } from '../../../../util/effect-ref' + +function HoverLayerComponent({ isEnabled, isValid, onClick, children }) { + const [[mouseWorldX, mouseWorldY], setPos] = useState([0, 0]) + + const layerRef = useEffectRef((layer) => { + if (!layer) { + return + } + + const stage = layer.getStage() + + // Transform used to convert mouse coordinates to world coordinates + const transform = stage.getAbsoluteTransform().copy() + transform.invert() + + stage.on('mousemove.hover', () => { + const { x, y } = transform.point(stage.getPointerPosition()) + setPos([x, y]) + }) + return () => stage.off('mousemove.hover') + }) + + const gridX = Math.floor(mouseWorldX / TILE_SIZE_IN_PIXELS) + const gridY = Math.floor(mouseWorldY / TILE_SIZE_IN_PIXELS) + const valid = useMemo(() => isEnabled && isValid(gridX, gridY), [isEnabled, isValid, gridX, gridY]) + + if (!isEnabled) { + return + } + + const x = gridX * TILE_SIZE_IN_PIXELS + const y = gridY * TILE_SIZE_IN_PIXELS + + return ( + + (valid ? onClick(gridX, gridY) : undefined)} /> + {children ? React.cloneElement(children, { x, y, scale: 1 }) : undefined} + + ) +} + +HoverLayerComponent.propTypes = { + isEnabled: PropTypes.bool.isRequired, + isValid: PropTypes.func.isRequired, + onClick: PropTypes.func.isRequired, + children: PropTypes.node, +} + +export default HoverLayerComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js new file mode 100644 index 00000000..c902532b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { Group, Layer } from 'react-konva' +import Backdrop from '../elements/Backdrop' +import TopologyContainer from '../TopologyContainer' +import GridGroup from '../groups/GridGroup' + +function MapLayer() { + return ( + + + + + + + + ) +} + +export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js new file mode 100644 index 00000000..47d9c992 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { addRackToTile } from '../../../../redux/actions/topology/room' +import { findTileWithPosition } from '../../../../util/tile-calculations' +import HoverLayerComponent from './HoverLayerComponent' +import TilePlusIcon from '../elements/TilePlusIcon' + +function ObjectHoverLayer() { + const isEnabled = useSelector((state) => state.construction.inRackConstructionMode) + const isValid = useSelector((state) => (x, y) => { + if (state.interactionLevel.mode !== 'ROOM') { + return false + } + + const currentRoom = state.objects.room[state.interactionLevel.roomId] + const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) + const tile = findTileWithPosition(tiles, x, y) + + return !(tile === null || tile.rack) + }) + + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(addRackToTile(x, y)) + return ( + + + + ) +} + +export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js new file mode 100644 index 00000000..59f83b2b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' +import { + deriveValidNextTilePositions, + findPositionInPositions, + findPositionInRooms, +} from '../../../../util/tile-calculations' +import HoverLayerComponent from './HoverLayerComponent' + +function RoomHoverLayer() { + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) + const isEnabled = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + const isValid = useSelector((state) => (x, y) => { + const newRoom = { ...state.objects.room[state.construction.currentRoomInConstruction] } + const oldRooms = Object.keys(state.objects.room) + .map((id) => ({ ...state.objects.room[id] })) + .filter( + (room) => + state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && + room._id !== state.construction.currentRoomInConstruction + ) + + ;[...oldRooms, newRoom].forEach((room) => { + room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) + }) + if (newRoom.tiles.length === 0) { + return findPositionInRooms(oldRooms, x, y) === -1 + } + + const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) + return findPositionInPositions(validNextPositions, x, y) !== -1 + }) + + return +} + +export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/NameComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/NameComponent.js new file mode 100644 index 00000000..ececd07b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/NameComponent.js @@ -0,0 +1,69 @@ +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import { Button, TextInput } from '@patternfly/react-core' +import { PencilAltIcon, CheckIcon, TimesIcon } from '@patternfly/react-icons' + +function NameComponent({ name, onEdit }) { + const [isEditing, setEditing] = useState(false) + const nameInput = useRef(null) + + const onCancel = () => { + nameInput.current.value = name + setEditing(false) + } + + const onSubmit = (event) => { + if (event) { + event.preventDefault() + } + + const name = nameInput.current.value + if (name) { + onEdit(name) + } + + setEditing(false) + } + + return ( +
    +
    +
    + {name} +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + ) +} + +NameComponent.propTypes = { + name: PropTypes.string, + onEdit: PropTypes.func, +} + +export default NameComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.js new file mode 100644 index 00000000..5d9340b2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.js @@ -0,0 +1,83 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { InteractionLevel } from '../../../shapes' +import BuildingSidebar from './building/BuildingSidebar' +import { + Button, + DrawerActions, + DrawerCloseButton, + DrawerHead, + DrawerPanelBody, + DrawerPanelContent, + Flex, + Title, +} from '@patternfly/react-core' +import { AngleLeftIcon } from '@patternfly/react-icons' +import { useDispatch } from 'react-redux' +import { backButton } from './TopologySidebar.module.scss' +import RoomSidebar from './room/RoomSidebar' +import RackSidebar from './rack/RackSidebar' +import MachineSidebar from './machine/MachineSidebar' +import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' + +const name = { + BUILDING: 'Building', + ROOM: 'Room', + RACK: 'Rack', + MACHINE: 'Machine', +} + +function TopologySidebar({ interactionLevel, onClose }) { + let sidebarContent + + switch (interactionLevel.mode) { + case 'BUILDING': + sidebarContent = + break + case 'ROOM': + sidebarContent = + break + case 'RACK': + sidebarContent = + break + case 'MACHINE': + sidebarContent = + break + default: + sidebarContent = 'Missing Content' + } + + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + + return ( + + + + + + {name[interactionLevel.mode]} + + + + + + + {sidebarContent} + + ) +} + +TopologySidebar.propTypes = { + interactionLevel: InteractionLevel, + onClose: PropTypes.func, +} + +export default TopologySidebar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.module.scss new file mode 100644 index 00000000..45dc98da --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/TopologySidebar.module.scss @@ -0,0 +1,37 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.backButton { + &:global(.pf-c-button) { + align-self: center; + --pf-c-button--after--BorderColor: var(--pf-global--BorderColor--light-100); + color: var(--pf-global--Color--400); + + --pf-c-button--PaddingRight: var(--pf-global--spacer--sm); + --pf-c-button--PaddingLeft: var(--pf-global--spacer--sm); + + &:hover, + &:focus { + --pf-c-button--after--BorderColor: var(--pf-global--BorderColor--100); + } + } +} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/BuildingSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/BuildingSidebar.js new file mode 100644 index 00000000..5fcd46be --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/BuildingSidebar.js @@ -0,0 +1,8 @@ +import React from 'react' +import NewRoomConstructionContainer from './NewRoomConstructionContainer' + +function BuildingSidebar() { + return +} + +export default BuildingSidebar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionComponent.js new file mode 100644 index 00000000..9fc85d0c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionComponent.js @@ -0,0 +1,46 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Button, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from '@patternfly/react-core' +import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' +import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' + +function NewRoomConstructionComponent({ onStart, onFinish, onCancel, currentRoomInConstruction }) { + if (currentRoomInConstruction === '-1') { + return ( + + ) + } + return ( + + + + + + + + + + + + + ) +} + +NewRoomConstructionComponent.propTypes = { + onStart: PropTypes.func, + onFinish: PropTypes.func, + onCancel: PropTypes.func, + currentRoomInConstruction: PropTypes.string, +} + +export default NewRoomConstructionComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionContainer.js new file mode 100644 index 00000000..c149b224 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/building/NewRoomConstructionContainer.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { + cancelNewRoomConstruction, + finishNewRoomConstruction, + startNewRoomConstruction, +} from '../../../../redux/actions/topology/building' +import NewRoomConstructionComponent from './NewRoomConstructionComponent' + +function NewRoomConstructionButton() { + const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) + const dispatch = useDispatch() + + return ( + dispatch(startNewRoomConstruction())} + onFinish={() => dispatch(finishNewRoomConstruction())} + onCancel={() => dispatch(cancelNewRoomConstruction())} + currentRoomInConstruction={currentRoomInConstruction} + /> + ) +} + +export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js new file mode 100644 index 00000000..00ce4603 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { useState } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { Button } from '@patternfly/react-core' +import { TrashIcon } from '@patternfly/react-icons' +import ConfirmationModal from '../../../util/modals/ConfirmationModal' +import { deleteMachine } from '../../../../redux/actions/topology/machine' + +function DeleteMachine() { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rack) + const position = useSelector((state) => state.interactionLevel.position) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteMachine(rackId, position)) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +export default DeleteMachine diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js new file mode 100644 index 00000000..0c3dea98 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js @@ -0,0 +1,49 @@ +import PropTypes from 'prop-types' +import React from 'react' +import UnitTabsComponent from './UnitTabsComponent' +import DeleteMachine from './DeleteMachine' +import { + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' +import { useSelector } from 'react-redux' + +function MachineSidebar({ tileId, position }) { + const machine = useSelector(({ objects }) => { + const rack = objects.rack[objects.tile[tileId].rack] + return objects.machine[rack.machines[position - 1]] + }) + const machineId = machine._id + return ( +
    + + Details + + Name + + Machine at position {machine.position} + + + + Actions + + + Units + +
    + +
    +
    + ) +} + +MachineSidebar.propTypes = { + tileId: PropTypes.string.isRequired, + position: PropTypes.number.isRequired, +} + +export default MachineSidebar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js new file mode 100644 index 00000000..88591208 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js @@ -0,0 +1,42 @@ +import PropTypes from 'prop-types' +import React, { useState } from 'react' +import { Button, InputGroup, Select, SelectOption, SelectVariant } from '@patternfly/react-core' +import PlusIcon from '@patternfly/react-icons/dist/js/icons/plus-icon' + +function UnitAddComponent({ units, onAdd }) { + const [isOpen, setOpen] = useState(false) + const [selected, setSelected] = useState(null) + + return ( + + + + + ) +} + +UnitAddComponent.propTypes = { + units: PropTypes.array.isRequired, + onAdd: PropTypes.func.isRequired, +} + +export default UnitAddComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js new file mode 100644 index 00000000..fc805b95 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import UnitAddComponent from './UnitAddComponent' +import { addUnit } from '../../../../redux/actions/topology/machine' + +function UnitAddContainer({ machineId, unitType }) { + const units = useSelector((state) => Object.values(state.objects[unitType])) + const dispatch = useDispatch() + + const onAdd = (id) => dispatch(addUnit(machineId, unitType, id)) + + return +} + +UnitAddContainer.propTypes = { + machineId: PropTypes.string.isRequired, + unitType: PropTypes.string.isRequired, +} + +export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js new file mode 100644 index 00000000..daa3e7a7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js @@ -0,0 +1,112 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { + Button, + DataList, + DataListAction, + DataListCell, + DataListItem, + DataListItemCells, + DataListItemRow, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + Popover, + Title, +} from '@patternfly/react-core' +import { CubesIcon, InfoIcon, TrashIcon } from '@patternfly/react-icons' +import { ProcessingUnit, StorageUnit } from '../../../../shapes' + +function UnitInfo({ unit, unitType }) { + if (unitType === 'cpu' || unitType === 'gpu') { + return ( + + + Clock Frequency + {unit.clockRateMhz} MHz + + + Number of Cores + {unit.numberOfCores} + + + Energy Consumption + {unit.energyConsumptionW} W + + + ) + } + + return ( + + + Speed + {unit.speedMbPerS} Mb/s + + + Capacity + {unit.sizeMb} MB + + + Energy Consumption + {unit.energyConsumptionW} W + + + ) +} + +UnitInfo.propTypes = { + unitType: PropTypes.string.isRequired, + unit: PropTypes.oneOfType([ProcessingUnit, StorageUnit]).isRequired, +} + +function UnitListComponent({ unitType, units, onDelete }) { + if (units.length === 0) { + return ( + + + + No units found + + You have not configured any units yet. Add some with the menu above! + + ) + } + + return ( + + {units.map((unit, index) => ( + + + {unit.name}]} /> + + } + > + + + + + + + ))} + + ) +} + +UnitListComponent.propTypes = { + unitType: PropTypes.string.isRequired, + units: PropTypes.arrayOf(PropTypes.oneOfType([ProcessingUnit, StorageUnit])).isRequired, + onDelete: PropTypes.func, +} + +export default UnitListComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js new file mode 100644 index 00000000..901fa45b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import UnitListComponent from './UnitListComponent' +import { deleteUnit } from '../../../../redux/actions/topology/machine' + +const unitMapping = { + cpu: 'cpus', + gpu: 'gpus', + memory: 'memories', + storage: 'storages', +} + +function UnitListContainer({ machineId, unitType }) { + const dispatch = useDispatch() + const units = useSelector((state) => { + const machine = state.objects.machine[machineId] + return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) + }) + + const onDelete = (unit) => dispatch(deleteUnit(machineId, unitType, unit._id)) + + return +} + +UnitListContainer.propTypes = { + machineId: PropTypes.string.isRequired, + unitType: PropTypes.string.isRequired, +} + +export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js new file mode 100644 index 00000000..6d10d2df --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types' +import React, { useState } from 'react' +import { Tab, Tabs, TabTitleText } from '@patternfly/react-core' +import UnitAddContainer from './UnitAddContainer' +import UnitListContainer from './UnitListContainer' + +function UnitTabsComponent({ machineId }) { + const [activeTab, setActiveTab] = useState('cpu-units') + + return ( + setActiveTab(tab)}> + CPU}> + + + + GPU}> + + + + Memory}> + + + + Storage}> + + + + + ) +} + +UnitTabsComponent.propTypes = { + machineId: PropTypes.string.isRequired, +} + +export default UnitTabsComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js new file mode 100644 index 00000000..e944c2e8 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch } from 'react-redux' +import { Button } from '@patternfly/react-core' +import { SaveIcon } from '@patternfly/react-icons' +import { addPrefab } from '../../../../api/prefabs' + +function AddPrefab({ tileId }) { + const dispatch = useDispatch() + const onClick = () => dispatch(addPrefab('name', tileId)) + return ( + + ) +} + +AddPrefab.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default AddPrefab diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js new file mode 100644 index 00000000..80c6349a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' +import { Button } from '@patternfly/react-core' +import ConfirmationModal from '../../../util/modals/ConfirmationModal' +import { deleteRack } from '../../../../redux/actions/topology/rack' + +function DeleteRackContainer({ tileId }) { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRack(tileId)) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +DeleteRackContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js new file mode 100644 index 00000000..921622d6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js @@ -0,0 +1,46 @@ +import PropTypes from 'prop-types' +import React from 'react' +import Image from 'next/image' +import { Flex, Label } from '@patternfly/react-core' +import { Machine } from '../../../../shapes' + +const UnitIcon = ({ id, type }) => ( + {'Machine +) + +UnitIcon.propTypes = { + id: PropTypes.string, + type: PropTypes.string, +} + +function MachineComponent({ machine, onClick }) { + const hasNoUnits = + machine.cpus.length + machine.gpus.length + machine.memories.length + machine.storages.length === 0 + + return ( + onClick()}> + {machine.cpus.length > 0 ? : undefined} + {machine.gpus.length > 0 ? : undefined} + {machine.memories.length > 0 ? : undefined} + {machine.storages.length > 0 ? : undefined} + {hasNoUnits ? ( + + ) : undefined} + + ) +} + +MachineComponent.propTypes = { + machine: Machine.isRequired, + onClick: PropTypes.func, +} + +export default MachineComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js new file mode 100644 index 00000000..de7a2140 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js @@ -0,0 +1,73 @@ +import PropTypes from 'prop-types' +import React from 'react' +import MachineComponent from './MachineComponent' +import { + Badge, + Button, + DataList, + DataListAction, + DataListCell, + DataListItem, + DataListItemCells, + DataListItemRow, +} from '@patternfly/react-core' +import { AngleRightIcon, PlusIcon } from '@patternfly/react-icons' +import { Machine } from '../../../../shapes' + +function MachineListComponent({ machines = [], onSelect, onAdd }) { + return ( + + {machines.map((machine, index) => + machine ? ( + onSelect(index + 1)}> + + + {machines.length - index}U + , + + onSelect(index + 1)} machine={machine} /> + , + ]} + /> + + + + + + ) : ( + + + + {machines.length - index}U + , + + Empty Slot + , + ]} + /> + + + + + + ) + )} + + ) +} + +MachineListComponent.propTypes = { + machines: PropTypes.arrayOf(Machine), + onSelect: PropTypes.func.isRequired, + onAdd: PropTypes.func.isRequired, +} + +export default MachineListComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js new file mode 100644 index 00000000..6fbff949 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React, { useMemo } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import MachineListComponent from './MachineListComponent' +import { goFromRackToMachine } from '../../../../redux/actions/interaction-level' +import { addMachine } from '../../../../redux/actions/topology/rack' + +function MachineListContainer({ tileId, ...props }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) + const machinesNull = useMemo(() => { + const res = Array(rack.capacity).fill(null) + for (const machine of machines) { + res[machine.position - 1] = machine + } + return res + }, [rack, machines]) + const dispatch = useDispatch() + + return ( + dispatch(addMachine(rack._id, index))} + onSelect={(index) => dispatch(goFromRackToMachine(index))} + /> + ) +} + +MachineListContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js new file mode 100644 index 00000000..09d73af7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import NameComponent from '../NameComponent' +import { editRackName } from '../../../../redux/actions/topology/rack' + +const RackNameContainer = ({ tileId }) => { + const { name: rackName, _id } = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRackName(_id, name)) + } + } + return +} + +RackNameContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js new file mode 100644 index 00000000..3c9f152a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js @@ -0,0 +1,58 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { machineListContainer, sidebarContainer } from './RackSidebar.module.scss' +import RackNameContainer from './RackNameContainer' +import AddPrefab from './AddPrefab' +import DeleteRackContainer from './DeleteRackContainer' +import MachineListContainer from './MachineListContainer' +import { + Skeleton, + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' +import { useSelector } from 'react-redux' + +function RackSidebar({ tileId }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + + return ( +
    + + Details + + + Name + + + + + Capacity + + {rack?.capacity ?? } + + + Actions + + + + Slots + +
    + +
    +
    + ) +} + +RackSidebar.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSidebar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss new file mode 100644 index 00000000..6f258aec --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss @@ -0,0 +1,12 @@ +.sidebarContainer { + display: flex; + height: 100%; + max-height: 100%; + flex-direction: column; +} + +.machineListContainer { + flex: 1; + overflow-y: scroll; + margin-top: 10px; +} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/DeleteRoomContainer.js new file mode 100644 index 00000000..29b8f78a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/DeleteRoomContainer.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import ConfirmationModal from '../../../util/modals/ConfirmationModal' +import { deleteRoom } from '../../../../redux/actions/topology/room' +import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' +import { Button } from '@patternfly/react-core' + +function DeleteRoomContainer({ roomId }) { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRoom(roomId)) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +DeleteRoomContainer.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/EditRoomContainer.js new file mode 100644 index 00000000..7a278cd6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/EditRoomContainer.js @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { finishRoomEdit, startRoomEdit } from '../../../../redux/actions/topology/building' +import CheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon' +import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon' +import { Button } from '@patternfly/react-core' + +function EditRoomContainer({ roomId }) { + const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) + + const dispatch = useDispatch() + const onEdit = () => dispatch(startRoomEdit(roomId)) + const onFinish = () => dispatch(finishRoomEdit()) + + return isEditing ? ( + + ) : ( + + ) +} + +EditRoomContainer.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionComponent.js new file mode 100644 index 00000000..a384d5d5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionComponent.js @@ -0,0 +1,35 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { Button } from '@patternfly/react-core' +import { PlusIcon, TimesIcon } from '@patternfly/react-icons' + +const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, isEditingRoom }) => { + if (inRackConstructionMode) { + return ( + + ) + } + + return ( + + ) +} + +RackConstructionComponent.propTypes = { + onStart: PropTypes.func, + onStop: PropTypes.func, + inRackConstructionMode: PropTypes.bool, + isEditingRoom: PropTypes.bool, +} + +export default RackConstructionComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionContainer.js new file mode 100644 index 00000000..e04287a5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RackConstructionContainer.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { startRackConstruction, stopRackConstruction } from '../../../../redux/actions/topology/room' +import RackConstructionComponent from './RackConstructionComponent' + +function RackConstructionContainer(props) { + const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) + const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + + const dispatch = useDispatch() + const onStart = () => dispatch(startRackConstruction()) + const onStop = () => dispatch(stopRackConstruction()) + return ( + + ) +} + +export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js new file mode 100644 index 00000000..e8d8b33c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import NameComponent from '../NameComponent' +import { editRoomName } from '../../../../redux/actions/topology/room' + +function RoomName({ roomId }) { + const { name: roomName, _id } = useSelector((state) => state.objects.room[roomId]) + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRoomName(_id, name)) + } + } + return +} + +RoomName.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default RoomName diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomSidebar.js new file mode 100644 index 00000000..6ad489e0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomSidebar.js @@ -0,0 +1,43 @@ +import PropTypes from 'prop-types' +import React from 'react' +import RoomName from './RoomName' +import RackConstructionContainer from './RackConstructionContainer' +import EditRoomContainer from './EditRoomContainer' +import DeleteRoomContainer from './DeleteRoomContainer' +import { + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' + +const RoomSidebar = ({ roomId }) => { + return ( + + Details + + + Name + + + + + + Construction + + + + + ) +} + +RoomSidebar.propTypes = { + roomId: PropTypes.string.isRequired, +} + +export default RoomSidebar diff --git a/opendc-web/opendc-web-ui/src/components/util/modals/ConfirmationModal.js b/opendc-web/opendc-web-ui/src/components/util/modals/ConfirmationModal.js new file mode 100644 index 00000000..f6e1c98b --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/util/modals/ConfirmationModal.js @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types' +import React from 'react' +import Modal from './Modal' + +function ConfirmationModal({ title, message, isOpen, callback }) { + return ( + callback(true)} + onCancel={() => callback(false)} + submitButtonType="danger" + submitButtonText="Confirm" + > + {message} + + ) +} + +ConfirmationModal.propTypes = { + title: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + isOpen: PropTypes.bool.isRequired, + callback: PropTypes.func.isRequired, +} + +export default ConfirmationModal diff --git a/opendc-web/opendc-web-ui/src/components/util/modals/Modal.js b/opendc-web/opendc-web-ui/src/components/util/modals/Modal.js new file mode 100644 index 00000000..d4577062 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/util/modals/Modal.js @@ -0,0 +1,38 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Button, Modal as PModal, ModalVariant } from '@patternfly/react-core' + +function Modal({ children, title, isOpen, onSubmit, onCancel, submitButtonType, submitButtonText }) { + const actions = [ + , + , + ] + + return ( + + {children} + + ) +} + +Modal.propTypes = { + title: PropTypes.string.isRequired, + isOpen: PropTypes.bool, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, + submitButtonType: PropTypes.string, + submitButtonText: PropTypes.string, + children: PropTypes.node, +} + +Modal.defaultProps = { + submitButtonType: 'primary', + submitButtonText: 'Save', + isOpen: false, +} + +export default Modal diff --git a/opendc-web/opendc-web-ui/src/components/util/modals/TextInputModal.js b/opendc-web/opendc-web-ui/src/components/util/modals/TextInputModal.js new file mode 100644 index 00000000..392a729e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/util/modals/TextInputModal.js @@ -0,0 +1,70 @@ +import PropTypes from 'prop-types' +import React, { useRef, useState } from 'react' +import Modal from './Modal' +import { Form, FormGroup, TextInput } from '@patternfly/react-core' + +function TextInputModal({ title, label, isOpen, callback, initialValue }) { + const textInput = useRef(null) + const [isSubmitted, setSubmitted] = useState(false) + const [isValid, setValid] = useState(true) + + const resetState = () => { + textInput.current.value = '' + setSubmitted(false) + setValid(false) + } + const onSubmit = (event) => { + const value = textInput.current.value + setSubmitted(true) + + if (event) { + event.preventDefault() + } + + if (!value) { + setValid(false) + return false + } + + callback(value) + resetState() + return true + } + const onCancel = () => { + callback(undefined) + resetState() + } + + return ( + +
    + + + +
    +
    + ) +} + +TextInputModal.propTypes = { + title: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + isOpen: PropTypes.bool.isRequired, + callback: PropTypes.func.isRequired, + initialValue: PropTypes.string, +} + +export default TextInputModal diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js index c6ded12b..8b0ed8e0 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js @@ -27,7 +27,6 @@ import Head from 'next/head' import { Breadcrumb, BreadcrumbItem, - Button, Card, CardActions, CardBody, diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js index 55bee445..53cc9c73 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js @@ -53,10 +53,10 @@ import { } from '@patternfly/react-core' import { AppPage } from '../../../../components/AppPage' import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' -import ScenarioTable from '../../../../components/projects/ScenarioTable' -import NewScenario from '../../../../components/projects/NewScenario' import { METRIC_NAMES } from '../../../../util/available-metrics' -import PortfolioResults from '../../../../components/app/results/PortfolioResults' +import NewScenario from '../../../../components/portfolios/NewScenario' +import ScenarioTable from '../../../../components/portfolios/ScenarioTable' +import PortfolioResults from '../../../../components/portfolios/results/PortfolioResults' /** * Page that displays the results in a portfolio. diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index 139c2979..a1d6ac7e 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -23,25 +23,37 @@ import { useRouter } from 'next/router' import { useProject } from '../../../../data/project' import { useDispatch, useSelector } from 'react-redux' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { configure, HotKeys } from 'react-hotkeys' import { KeymapConfiguration } from '../../../../hotkeys' import Head from 'next/head' -import MapStage from '../../../../components/app/map/MapStage' import { openProjectSucceeded } from '../../../../redux/actions/projects' import { AppPage } from '../../../../components/AppPage' import { + Breadcrumb, + BreadcrumbItem, Bullseye, + Divider, Drawer, DrawerContent, DrawerContentBody, EmptyState, EmptyStateIcon, + PageSection, + PageSectionVariants, Spinner, + Tab, + TabContent, + Tabs, + TabTitleText, + Text, + TextContent, Title, } from '@patternfly/react-core' -import TopologySidebar from '../../../../components/app/sidebars/topology/TopologySidebar' -import Collapse from '../../../../components/app/map/controls/Collapse' +import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' +import MapStage from '../../../../components/topologies/map/MapStage' +import Collapse from '../../../../components/topologies/map/controls/Collapse' +import TopologySidebar from '../../../../components/topologies/sidebar/TopologySidebar' /** * Page that displays a datacenter topology. @@ -59,10 +71,29 @@ function Topology() { } }, [projectId, topologyId, dispatch]) + const [activeTab, setActiveTab] = useState('overview') + const overviewRef = useRef(null) + const floorPlanRef = useRef(null) + const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') const interactionLevel = useSelector((state) => state.interactionLevel) const [isExpanded, setExpanded] = useState(true) + + const breadcrumb = ( + + + Projects + + + Project details + + + Topology + + + ) + const panelContent = setExpanded(false)} /> // Make sure that holding down a key will generate repeated events @@ -71,31 +102,71 @@ function Topology() { }) return ( - + {project?.name ?? 'Topologies'} - OpenDC - {topologyIsLoading ? ( - - - - - Loading Topology - - - - ) : ( - - - - - - setExpanded(true)} /> - - - - - )} + + + Topology + + + + + setActiveTab(tabIndex)} + className="pf-m-page-insets" + > + Overview} + tabContentId="overview" + tabContentRef={overviewRef} + /> + Floor Plan} + tabContentId="floor-plan" + tabContentRef={floorPlanRef} + /> + + + + + Test + + + ) } diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index f3742b78..a5a3be32 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -15,7 +15,7 @@ import { DEFAULT_RACK_POWER_CAPACITY, DEFAULT_RACK_SLOT_CAPACITY, MAX_NUM_UNITS_PER_MACHINE, -} from '../../components/app/map/MapConstants' +} from '../../components/topologies/map/MapConstants' import { fetchAndStoreTopology, denormalizeTopology, updateTopologyOnServer } from './objects' import { uuid } from 'uuidv4' import { addTopology } from '../../api/topologies' @@ -45,7 +45,7 @@ export function* onAddTopology({ projectId, duplicateId, name }) { topologyToBeCreated = { ...topologyToBeCreated, name } delete topologyToBeCreated._id } else { - topologyToBeCreated = { name: action.name, rooms: [] } + topologyToBeCreated = { name, rooms: [] } } const auth = yield getContext('auth') -- cgit v1.2.3 From 922c84801acf931a5a29e95a08486f6df46a1fc2 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 16:15:04 +0200 Subject: chore(ui): Extend ESLint configuration This change extends the ESLint configuration with the ESLint recommended settings. --- opendc-web/opendc-web-ui/.eslintrc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/opendc-web/opendc-web-ui/.eslintrc b/opendc-web/opendc-web-ui/.eslintrc index c1640061..1446fa02 100644 --- a/opendc-web/opendc-web-ui/.eslintrc +++ b/opendc-web/opendc-web-ui/.eslintrc @@ -1,3 +1,16 @@ { - "extends": "next" + "extends": ["next", "eslint:recommended"], + "env": { + "browser": true, + "node": true, + "es6": true + }, + "overrides": [ + { + "files": ["src/**/*.test.js"], + "env": { + "jest": true + } + } + ] } -- cgit v1.2.3 From 28d6d13844db28745bc2813e87a367131f862070 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 20:59:11 +0200 Subject: refactor(ui): Move page components in separate files --- .../src/components/portfolios/PortfolioOverview.js | 121 ++++++++++++++++ .../components/portfolios/PortfolioResultInfo.js | 40 ++++++ .../src/components/portfolios/PortfolioResults.js | 156 +++++++++++++++++++++ .../portfolios/results/PortfolioResultInfo.js | 40 ------ .../portfolios/results/PortfolioResults.js | 134 ------------------ .../src/components/projects/ProjectOverview.js | 98 +++++++++++++ .../src/components/topologies/TopologyMap.js | 76 ++++++++++ .../src/components/topologies/TopologyOverview.js | 77 ++++++++++ opendc-web/opendc-web-ui/src/data/topology.js | 7 + opendc-web/opendc-web-ui/src/pages/_app.js | 3 +- .../src/pages/projects/[project]/index.js | 60 +------- .../projects/[project]/portfolios/[portfolio].js | 93 +----------- .../projects/[project]/topologies/[topology].js | 53 +------ .../opendc-web-ui/src/pages/projects/index.js | 3 +- 14 files changed, 589 insertions(+), 372 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js delete mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js delete mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js create mode 100644 opendc-web/opendc-web-ui/src/components/projects/ProjectOverview.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js new file mode 100644 index 00000000..580b0a29 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + Chip, + ChipGroup, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Grid, + GridItem, + Skeleton, +} from '@patternfly/react-core' +import React from 'react' +import { usePortfolio } from '../../data/project' +import { METRIC_NAMES } from '../../util/available-metrics' +import NewScenario from './NewScenario' +import ScenarioTable from './ScenarioTable' + +function PortfolioOverview({ portfolioId }) { + const { data: portfolio } = usePortfolio(portfolioId) + + return ( + + + + Details + + + + Name + + {portfolio?.name ?? } + + + + Scenarios + + {portfolio?.scenarioIds.length ?? } + + + + Metrics + + {portfolio?.targets?.enabledMetrics ? ( + portfolio.targets.enabledMetrics.length > 0 ? ( + + {portfolio.targets.enabledMetrics.map((metric) => ( + + {METRIC_NAMES[metric]} + + ))} + + ) : ( + 'No metrics enabled' + ) + ) : ( + + )} + + + + Repeats per Scenario + + {portfolio?.targets?.repeatsPerScenario ?? ( + + )} + + + + + + + + + + + + + Scenarios + + + + + + + + ) +} + +PortfolioOverview.propTypes = { + portfolioId: PropTypes.string, +} + +export default PortfolioOverview diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js new file mode 100644 index 00000000..dbfa928f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { Tooltip } from '@patternfly/react-core' +import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' +import { METRIC_DESCRIPTIONS } from '../../util/available-metrics' + +function PortfolioResultInfo({ metric }) { + return ( + {METRIC_DESCRIPTIONS[metric]}
    }> + + + ) +} + +PortfolioResultInfo.propTypes = { + metric: PropTypes.string.isRequired, +} + +export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js new file mode 100644 index 00000000..00023d9e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import PropTypes from 'prop-types' +import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' +import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_UNITS } from '../../util/available-metrics' +import { mean, std } from 'mathjs' +import approx from 'approximate-number' +import { + Bullseye, + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + Grid, + GridItem, + Spinner, + Title, +} from '@patternfly/react-core' +import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' +import { usePortfolioScenarios } from '../../data/project' +import PortfolioResultInfo from './PortfolioResultInfo' +import NewScenario from './NewScenario' + +const PortfolioResults = ({ portfolioId }) => { + const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) + + if (status === 'loading') { + return ( + + + + + Loading Results + + + + ) + } else if (status === 'error') { + return ( + + + + + Unable to connect + + + There was an error retrieving data. Check your connection and try again. + + + + ) + } else if (scenarios.length === 0) { + return ( + + + + + No results + + + No results are currently available for this portfolio. Run a scenario to obtain simulation + results. + + + + + ) + } + + const dataPerMetric = {} + + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios + .filter((scenario) => scenario.results) + .map((scenario) => ({ + name: scenario.name, + value: mean(scenario.results[metric]), + errorX: std(scenario.results[metric]), + })) + }) + + return ( + + {AVAILABLE_METRICS.map((metric) => ( + + + + + + + {METRIC_NAMES[metric]} + + + + + + approx(tick)} + label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} + type="number" + /> + + + + + + + + + + + ))} + + ) +} + +PortfolioResults.propTypes = { + portfolioId: PropTypes.string, +} + +export default PortfolioResults diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js deleted file mode 100644 index 09348e60..00000000 --- a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import { Tooltip } from '@patternfly/react-core' -import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' -import { METRIC_DESCRIPTIONS } from '../../../util/available-metrics' - -function PortfolioResultInfo({ metric }) { - return ( - {METRIC_DESCRIPTIONS[metric]}
    }> - - - ) -} - -PortfolioResultInfo.propTypes = { - metric: PropTypes.string.isRequired, -} - -export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js deleted file mode 100644 index f1883e68..00000000 --- a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js +++ /dev/null @@ -1,134 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' -import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_UNITS } from '../../../util/available-metrics' -import { mean, std } from 'mathjs' -import approx from 'approximate-number' -import { - Bullseye, - Card, - CardActions, - CardBody, - CardHeader, - CardTitle, - EmptyState, - EmptyStateBody, - EmptyStateIcon, - Grid, - GridItem, - Spinner, - Title, -} from '@patternfly/react-core' -import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' -import { usePortfolioScenarios } from '../../../data/project' -import PortfolioResultInfo from './PortfolioResultInfo' -import NewScenario from '../NewScenario' - -const PortfolioResults = ({ portfolioId }) => { - const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) - - if (status === 'loading') { - return ( - - - - - Loading Results - - - - ) - } else if (status === 'error') { - return ( - - - - - Unable to connect - - - There was an error retrieving data. Check your connection and try again. - - - - ) - } else if (scenarios.length === 0) { - return ( - - - - - No results - - - No results are currently available for this portfolio. Run a scenario to obtain simulation - results. - - - - - ) - } - - const dataPerMetric = {} - - AVAILABLE_METRICS.forEach((metric) => { - dataPerMetric[metric] = scenarios - .filter((scenario) => scenario.results) - .map((scenario) => ({ - name: scenario.name, - value: mean(scenario.results[metric]), - errorX: std(scenario.results[metric]), - })) - }) - - return ( - - {AVAILABLE_METRICS.map((metric) => ( - - - - - - - {METRIC_NAMES[metric]} - - - - - - approx(tick)} - label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} - type="number" - /> - - - - - - - - - - - ))} - - ) -} - -PortfolioResults.propTypes = { - portfolioId: PropTypes.string, -} - -export default PortfolioResults diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectOverview.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectOverview.js new file mode 100644 index 00000000..65b8f5a0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectOverview.js @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Grid, + GridItem, + Skeleton, +} from '@patternfly/react-core' +import NewTopology from './NewTopology' +import TopologyTable from './TopologyTable' +import NewPortfolio from './NewPortfolio' +import PortfolioTable from './PortfolioTable' +import { useProject } from '../../data/project' + +function ProjectOverview({ projectId }) { + const { data: project } = useProject(projectId) + + return ( + + + + Details + + + + Name + + {project?.name ?? } + + + + + + + + + + + + + Topologies + + + + + + + + + + + + + Portfolios + + + + + + + + ) +} + +ProjectOverview.propTypes = { + projectId: PropTypes.string, +} + +export default ProjectOverview diff --git a/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js b/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js new file mode 100644 index 00000000..c16f554c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { useState } from 'react' +import { + Bullseye, + Drawer, + DrawerContent, + DrawerContentBody, + EmptyState, + EmptyStateIcon, + Spinner, + Title, +} from '@patternfly/react-core' +import { configure, HotKeys } from 'react-hotkeys' +import { KeymapConfiguration } from '../../hotkeys' +import MapStage from './map/MapStage' +import Collapse from './map/controls/Collapse' +import { useSelector } from 'react-redux' +import TopologySidebar from './sidebar/TopologySidebar' + +function TopologyMap() { + const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') + const interactionLevel = useSelector((state) => state.interactionLevel) + + const [isExpanded, setExpanded] = useState(true) + const panelContent = setExpanded(false)} /> + + // Make sure that holding down a key will generate repeated events + configure({ + ignoreRepeatedEventsWhenKeyHeldDown: false, + }) + + return topologyIsLoading ? ( + + + + + Loading Topology + + + + ) : ( + + + + + + setExpanded(true)} /> + + + + + ) +} + +export default TopologyMap diff --git a/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js b/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js new file mode 100644 index 00000000..f773dcd1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { + Card, + CardBody, + CardTitle, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Grid, + GridItem, + Skeleton, +} from '@patternfly/react-core' +import { useTopology } from '../../data/topology' +import { parseAndFormatDateTime } from '../../util/date-time' + +function TopologyOverview({ topologyId }) { + const { data: topology } = useTopology(topologyId) + + return ( + + + + Details + + + + Name + + {topology?.name ?? } + + + + Last edited + + {topology ? ( + parseAndFormatDateTime(topology.datetimeLastEdited) + ) : ( + + )} + + + + + + + + ) +} + +TopologyOverview.propTypes = { + topologyId: PropTypes.string, +} + +export default TopologyOverview diff --git a/opendc-web/opendc-web-ui/src/data/topology.js b/opendc-web/opendc-web-ui/src/data/topology.js index 14bd7562..bd4d1e4d 100644 --- a/opendc-web/opendc-web-ui/src/data/topology.js +++ b/opendc-web/opendc-web-ui/src/data/topology.js @@ -70,6 +70,13 @@ export function useActiveTopology() { return useSelector((state) => state.currentTopologyId !== '-1' && state.objects.topology[state.currentTopologyId]) } +/** + * Return the current active topology. + */ +export function useTopology(topologyId, options = {}) { + return useQuery(['topologies', topologyId], { enabled: !!topologyId, ...options }) +} + /** * Return the topologies of the specified project. */ diff --git a/opendc-web/opendc-web-ui/src/pages/_app.js b/opendc-web/opendc-web-ui/src/pages/_app.js index 028dab10..d5f3b329 100644 --- a/opendc-web/opendc-web-ui/src/pages/_app.js +++ b/opendc-web/opendc-web-ui/src/pages/_app.js @@ -24,7 +24,7 @@ import PropTypes from 'prop-types' import Head from 'next/head' import { Provider } from 'react-redux' import { useStore } from '../redux' -import { AuthProvider, useAuth } from '../auth' +import { AuthProvider, useAuth, useRequireAuth } from '../auth' import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' import { QueryClient, QueryClientProvider } from 'react-query' @@ -48,6 +48,7 @@ import '../style/index.scss' // This setup is necessary to forward the Auth0 context to the Redux context const Inner = ({ Component, pageProps }) => { + useRequireAuth() const auth = useAuth() const queryClient = useMemo(() => { diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js index 8b0ed8e0..5c17303f 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js @@ -21,23 +21,13 @@ */ import { useRouter } from 'next/router' +import ProjectOverview from '../../../components/projects/ProjectOverview' import { useProject } from '../../../data/project' import { AppPage } from '../../../components/AppPage' import Head from 'next/head' import { Breadcrumb, BreadcrumbItem, - Card, - CardActions, - CardBody, - CardHeader, - CardTitle, - DescriptionList, - DescriptionListDescription, - DescriptionListGroup, - DescriptionListTerm, - Grid, - GridItem, PageSection, PageSectionVariants, Skeleton, @@ -45,10 +35,6 @@ import { TextContent, } from '@patternfly/react-core' import BreadcrumbLink from '../../../components/util/BreadcrumbLink' -import PortfolioTable from '../../../components/projects/PortfolioTable' -import TopologyTable from '../../../components/projects/TopologyTable' -import NewTopology from '../../../components/projects/NewTopology' -import NewPortfolio from '../../../components/projects/NewPortfolio' function Project() { const router = useRouter() @@ -80,49 +66,7 @@ function Project() { - - - - Details - - - - Name - - {project?.name ?? } - - - - - - - - - - - - - Topologies - - - - - - - - - - - - - Portfolios - - - - - - - + ) diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js index 53cc9c73..28b03c37 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js @@ -23,27 +23,12 @@ import { useRouter } from 'next/router' import Head from 'next/head' import React, { useRef } from 'react' -import { usePortfolio, useProject } from '../../../../data/project' import { Breadcrumb, BreadcrumbItem, - Card, - CardActions, - CardBody, - CardHeader, - CardTitle, - Chip, - ChipGroup, - DescriptionList, - DescriptionListDescription, - DescriptionListGroup, - DescriptionListTerm, Divider, - Grid, - GridItem, PageSection, PageSectionVariants, - Skeleton, Tab, TabContent, Tabs, @@ -53,10 +38,8 @@ import { } from '@patternfly/react-core' import { AppPage } from '../../../../components/AppPage' import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' -import { METRIC_NAMES } from '../../../../util/available-metrics' -import NewScenario from '../../../../components/portfolios/NewScenario' -import ScenarioTable from '../../../../components/portfolios/ScenarioTable' -import PortfolioResults from '../../../../components/portfolios/results/PortfolioResults' +import PortfolioOverview from '../../../../components/portfolios/PortfolioOverview' +import PortfolioResults from '../../../../components/portfolios/PortfolioResults' /** * Page that displays the results in a portfolio. @@ -65,9 +48,6 @@ function Portfolio() { const router = useRouter() const { project: projectId, portfolio: portfolioId } = router.query - const { data: project } = useProject(projectId) - const { data: portfolio } = usePortfolio(portfolioId) - const overviewRef = useRef(null) const resultsRef = useRef(null) @@ -88,7 +68,7 @@ function Portfolio() { return ( - {project?.name ?? 'Portfolios'} - OpenDC + Portfolio - OpenDC @@ -114,72 +94,7 @@ function Portfolio() { - - - - Details - - - - Name - - {portfolio?.name ?? } - - - - Scenarios - - {portfolio?.scenarioIds.length ?? ( - - )} - - - - Metrics - - {portfolio?.targets?.enabledMetrics ? ( - portfolio.targets.enabledMetrics.length > 0 ? ( - - {portfolio.targets.enabledMetrics.map((metric) => ( - - {METRIC_NAMES[metric]} - - ))} - - ) : ( - 'No metrics enabled' - ) - ) : ( - - )} - - - - Repeats per Scenario - - {portfolio?.targets?.repeatsPerScenario ?? ( - - )} - - - - - - - - - - - - - Scenarios - - - - - - - + - Test + diff --git a/opendc-web/opendc-web-ui/src/pages/projects/index.js b/opendc-web/opendc-web-ui/src/pages/projects/index.js index 9dcc9aea..eb77701e 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/index.js +++ b/opendc-web/opendc-web-ui/src/pages/projects/index.js @@ -23,7 +23,7 @@ import React, { useMemo, useState } from 'react' import Head from 'next/head' import ProjectFilterPanel from '../../components/projects/FilterPanel' -import { useAuth, useRequireAuth } from '../../auth' +import { useAuth } from '../../auth' import { AppPage } from '../../components/AppPage' import { PageSection, PageSectionVariants, Text, TextContent } from '@patternfly/react-core' import { useProjects } from '../../data/project' @@ -49,7 +49,6 @@ const getVisibleProjects = (projects, filter, userId) => { } function Projects() { - useRequireAuth() const { user } = useAuth() const { status, data: projects } = useProjects() const [filter, setFilter] = useState('SHOW_ALL') -- cgit v1.2.3 From 6e3ad713111f35fc58bd2b7f1be5aeeb57eb94a8 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 20 Jul 2021 14:09:39 +0200 Subject: refactor(ui): Perform Saga mutations through React Query This change updates the OpenDC frontend to perform mutations of the topology done in Sagas through the React Query cache, so that non-Saga parts of the application also have their topology queries updated. --- opendc-web/opendc-web-ui/src/data/query.js | 57 ++++++++++++++++++++++ opendc-web/opendc-web-ui/src/data/topology.js | 2 +- opendc-web/opendc-web-ui/src/pages/_app.js | 23 +++------ .../opendc-web-ui/src/redux/sagas/objects.js | 36 -------------- opendc-web/opendc-web-ui/src/redux/sagas/query.js | 41 ++++++++++++++++ .../opendc-web-ui/src/redux/sagas/topology.js | 48 +++++++++++++++--- 6 files changed, 147 insertions(+), 60 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/data/query.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/objects.js create mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/query.js diff --git a/opendc-web/opendc-web-ui/src/data/query.js b/opendc-web/opendc-web-ui/src/data/query.js new file mode 100644 index 00000000..59eaa684 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/data/query.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useMemo } from 'react' +import { QueryClient } from 'react-query' +import { useAuth } from '../auth' +import { configureExperimentClient } from './experiments' +import { configureProjectClient } from './project' +import { configureTopologyClient } from './topology' + +let queryClient + +function createQueryClient(auth) { + const client = new QueryClient() + configureProjectClient(client, auth) + configureExperimentClient(client, auth) + configureTopologyClient(client, auth) + return client +} + +function initializeQueryClient(auth) { + const _queryClient = queryClient ?? createQueryClient(auth) + + // For SSG and SSR always create a new query client + if (typeof window === 'undefined') return _queryClient + // Create the query client once in the client + if (!queryClient) queryClient = _queryClient + + return _queryClient +} + +/** + * Obtain a cached query client. + */ +export function useNewQueryClient() { + const auth = useAuth() + return useMemo(() => initializeQueryClient(auth), []) // eslint-disable-line react-hooks/exhaustive-deps +} diff --git a/opendc-web/opendc-web-ui/src/data/topology.js b/opendc-web/opendc-web-ui/src/data/topology.js index bd4d1e4d..83abb6aa 100644 --- a/opendc-web/opendc-web-ui/src/data/topology.js +++ b/opendc-web/opendc-web-ui/src/data/topology.js @@ -46,7 +46,7 @@ export function configureTopologyClient(queryClient, auth) { }) queryClient.setMutationDefaults('updateTopology', { mutationFn: (data) => updateTopology(auth, data), - onSuccess: async (result) => queryClient.setQueryData(['topologies', result._id], result), + onSuccess: (result) => queryClient.setQueryData(['topologies', result._id], result), }) queryClient.setMutationDefaults('deleteTopology', { mutationFn: (id) => deleteTopology(auth, id), diff --git a/opendc-web/opendc-web-ui/src/pages/_app.js b/opendc-web/opendc-web-ui/src/pages/_app.js index d5f3b329..900ff405 100644 --- a/opendc-web/opendc-web-ui/src/pages/_app.js +++ b/opendc-web/opendc-web-ui/src/pages/_app.js @@ -23,15 +23,12 @@ import PropTypes from 'prop-types' import Head from 'next/head' import { Provider } from 'react-redux' +import { useNewQueryClient } from '../data/query' import { useStore } from '../redux' -import { AuthProvider, useAuth, useRequireAuth } from '../auth' +import { AuthProvider, useRequireAuth } from '../auth' import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' -import { QueryClient, QueryClientProvider } from 'react-query' -import { useMemo } from 'react' -import { configureProjectClient } from '../data/project' -import { configureExperimentClient } from '../data/experiments' -import { configureTopologyClient } from '../data/topology' +import { QueryClientProvider } from 'react-query' import '@patternfly/react-core/dist/styles/base.css' import '@patternfly/react-styles/css/utilities/Alignment/alignment.css' @@ -47,18 +44,12 @@ import '@patternfly/react-styles/css/components/InlineEdit/inline-edit.css' import '../style/index.scss' // This setup is necessary to forward the Auth0 context to the Redux context -const Inner = ({ Component, pageProps }) => { +function Inner({ Component, pageProps }) { + // Force user to be authorized useRequireAuth() - const auth = useAuth() - const queryClient = useMemo(() => { - const client = new QueryClient() - configureProjectClient(client, auth) - configureExperimentClient(client, auth) - configureTopologyClient(client, auth) - return client - }, []) // eslint-disable-line react-hooks/exhaustive-deps - const store = useStore(pageProps.initialReduxState, { auth, queryClient }) + const queryClient = useNewQueryClient() + const store = useStore(pageProps.initialReduxState, { queryClient }) return ( diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/objects.js b/opendc-web/opendc-web-ui/src/redux/sagas/objects.js deleted file mode 100644 index 9b4f8094..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/objects.js +++ /dev/null @@ -1,36 +0,0 @@ -import { call, put, select, getContext } from 'redux-saga/effects' -import { fetchTopology, updateTopology } from '../../api/topologies' -import { Topology } from '../../util/topology-schema' -import { denormalize, normalize } from 'normalizr' -import { storeTopology } from '../actions/topologies' - -/** - * Fetches and normalizes the topology with the specified identifier. - */ -export const fetchAndStoreTopology = function* (id) { - const auth = yield getContext('auth') - - let topology = yield select((state) => state.objects.topology[id]) - if (!topology) { - const newTopology = yield call(fetchTopology, auth, id) - const { entities } = normalize(newTopology, Topology) - yield put(storeTopology(entities)) - } - - return topology -} - -export const updateTopologyOnServer = function* (id) { - const topology = yield denormalizeTopology(id) - const auth = yield getContext('auth') - yield call(updateTopology, auth, topology) -} - -/** - * Denormalizes the topology representation in order to be stored on the server. - */ -export const denormalizeTopology = function* (id) { - const objects = yield select((state) => state.objects) - const topology = objects.topology[id] - return denormalize(topology, Topology, objects) -} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/query.js b/opendc-web/opendc-web-ui/src/redux/sagas/query.js new file mode 100644 index 00000000..787006c7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/sagas/query.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { MutationObserver } from 'react-query' +import { getContext, call } from 'redux-saga/effects' + +/** + * Fetch the query with the specified key. + */ +export function* fetchQuery(key, options) { + const queryClient = yield getContext('queryClient') + return yield call([queryClient, queryClient.fetchQuery], key, options) +} + +/** + * Perform a mutation with the specified key. + */ +export function* mutate(key, object, options) { + const queryClient = yield getContext('queryClient') + const mutationObserver = new MutationObserver(queryClient, { mutationKey: key }) + return yield call([mutationObserver, mutationObserver.mutate], object, options) +} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index a5a3be32..2d61643b 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -1,4 +1,6 @@ -import { call, put, select, getContext } from 'redux-saga/effects' +import { normalize, denormalize } from 'normalizr' +import { put, select } from 'redux-saga/effects' +import { Topology } from '../../util/topology-schema' import { goDownOneInteractionLevel } from '../actions/interaction-level' import { addIdToStoreObjectListProp, @@ -6,6 +8,7 @@ import { addToStore, removeIdFromStoreObjectListProp, } from '../actions/objects' +import { storeTopology } from '../actions/topologies' import { cancelNewRoomConstructionSucceeded, setCurrentTopology, @@ -16,14 +19,15 @@ import { DEFAULT_RACK_SLOT_CAPACITY, MAX_NUM_UNITS_PER_MACHINE, } from '../../components/topologies/map/MapConstants' -import { fetchAndStoreTopology, denormalizeTopology, updateTopologyOnServer } from './objects' import { uuid } from 'uuidv4' -import { addTopology } from '../../api/topologies' +import { fetchQuery, mutate } from './query' +/** + * Fetches all topologies of the project with the specified identifier. + */ export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = false) { try { - const queryClient = yield getContext('queryClient') - const project = yield call(() => queryClient.fetchQuery(['projects', projectId])) + const project = yield fetchQuery(['projects', projectId]) for (const id of project.topologyIds) { yield fetchAndStoreTopology(id) @@ -37,6 +41,37 @@ export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = fa } } +/** + * Fetches and normalizes the topology with the specified identifier. + */ +export function* fetchAndStoreTopology(id) { + let topology = yield select((state) => state.objects.topology[id]) + if (!topology) { + const newTopology = yield fetchQuery(['topologies', id]) + const { entities } = normalize(newTopology, Topology) + yield put(storeTopology(entities)) + } + + return topology +} + +/** + * Synchronize the topology with the specified identifier with the server. + */ +export function* updateTopologyOnServer(id) { + const topology = yield denormalizeTopology(id) + yield mutate('updateTopology', topology) +} + +/** + * Denormalizes the topology representation in order to be stored on the server. + */ +export function* denormalizeTopology(id) { + const objects = yield select((state) => state.objects) + const topology = objects.topology[id] + return denormalize(topology, Topology, objects) +} + export function* onAddTopology({ projectId, duplicateId, name }) { try { let topologyToBeCreated @@ -48,8 +83,7 @@ export function* onAddTopology({ projectId, duplicateId, name }) { topologyToBeCreated = { name, rooms: [] } } - const auth = yield getContext('auth') - const topology = yield call(addTopology, auth, { ...topologyToBeCreated, projectId }) + const topology = yield mutate('addTopology', { ...topologyToBeCreated, projectId }) yield fetchAndStoreTopology(topology._id) yield put(setCurrentTopology(topology._id)) } catch (error) { -- cgit v1.2.3 From ebab0cc12e293a57cbc58d2dd51b3c9d7cd4ee92 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 20 Jul 2021 14:55:39 +0200 Subject: fix(ui): Load correct topology view This change fixes an issue where the only the default topology view would be shown to the user. --- .../projects/[project]/topologies/[topology].js | 8 ++--- .../opendc-web-ui/src/redux/actions/projects.js | 8 ----- .../opendc-web-ui/src/redux/actions/topologies.js | 8 +++++ opendc-web/opendc-web-ui/src/redux/sagas/index.js | 7 ++--- .../opendc-web-ui/src/redux/sagas/projects.js | 9 ------ .../opendc-web-ui/src/redux/sagas/topology.js | 34 ++++++++-------------- 6 files changed, 27 insertions(+), 47 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/redux/actions/projects.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/projects.js diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index f95b18ed..c2753144 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -26,7 +26,6 @@ import { useProject } from '../../../../data/project' import { useDispatch } from 'react-redux' import React, { useEffect, useRef, useState } from 'react' import Head from 'next/head' -import { openProjectSucceeded } from '../../../../redux/actions/projects' import { AppPage } from '../../../../components/AppPage' import { Breadcrumb, @@ -43,6 +42,7 @@ import { } from '@patternfly/react-core' import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' import TopologyMap from '../../../../components/topologies/TopologyMap' +import { openTopology } from '../../../../redux/actions/topologies' /** * Page that displays a datacenter topology. @@ -55,10 +55,10 @@ function Topology() { const dispatch = useDispatch() useEffect(() => { - if (projectId) { - dispatch(openProjectSucceeded(projectId)) + if (topologyId) { + dispatch(openTopology(topologyId)) } - }, [projectId, topologyId, dispatch]) + }, [topologyId, dispatch]) const [activeTab, setActiveTab] = useState('overview') const overviewRef = useRef(null) diff --git a/opendc-web/opendc-web-ui/src/redux/actions/projects.js b/opendc-web/opendc-web-ui/src/redux/actions/projects.js deleted file mode 100644 index 4fe6f6a8..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/projects.js +++ /dev/null @@ -1,8 +0,0 @@ -export const OPEN_PROJECT_SUCCEEDED = 'OPEN_PROJECT_SUCCEEDED' - -export function openProjectSucceeded(id) { - return { - type: OPEN_PROJECT_SUCCEEDED, - id, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topologies.js b/opendc-web/opendc-web-ui/src/redux/actions/topologies.js index 529e8663..4888c4da 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topologies.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topologies.js @@ -1,6 +1,14 @@ +export const OPEN_TOPOLOGY = 'OPEN_TOPOLOGY' export const ADD_TOPOLOGY = 'ADD_TOPOLOGY' export const STORE_TOPOLOGY = 'STORE_TOPOLOGY' +export function openTopology(id) { + return { + type: OPEN_TOPOLOGY, + id, + } +} + export function addTopology(projectId, name, duplicateId) { return { type: ADD_TOPOLOGY, diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/index.js b/opendc-web/opendc-web-ui/src/redux/sagas/index.js index 318f0afb..9ddc564d 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/index.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/index.js @@ -1,5 +1,4 @@ import { takeEvery } from 'redux-saga/effects' -import { OPEN_PROJECT_SUCCEEDED } from '../actions/projects' import { ADD_TILE, CANCEL_NEW_ROOM_CONSTRUCTION, @@ -9,7 +8,6 @@ import { import { ADD_UNIT, DELETE_MACHINE, DELETE_UNIT } from '../actions/topology/machine' import { ADD_MACHINE, DELETE_RACK, EDIT_RACK_NAME } from '../actions/topology/rack' import { ADD_RACK_TO_TILE, DELETE_ROOM, EDIT_ROOM_NAME } from '../actions/topology/room' -import { onOpenProjectSucceeded } from './projects' import { onAddMachine, onAddRackToTile, @@ -25,13 +23,14 @@ import { onEditRackName, onEditRoomName, onStartNewRoomConstruction, + onOpenTopology, } from './topology' -import { ADD_TOPOLOGY } from '../actions/topologies' +import { ADD_TOPOLOGY, OPEN_TOPOLOGY } from '../actions/topologies' import { onAddPrefab } from './prefabs' import { ADD_PREFAB } from '../actions/prefabs' export default function* rootSaga() { - yield takeEvery(OPEN_PROJECT_SUCCEEDED, onOpenProjectSucceeded) + yield takeEvery(OPEN_TOPOLOGY, onOpenTopology) yield takeEvery(ADD_TOPOLOGY, onAddTopology) yield takeEvery(START_NEW_ROOM_CONSTRUCTION, onStartNewRoomConstruction) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/projects.js b/opendc-web/opendc-web-ui/src/redux/sagas/projects.js deleted file mode 100644 index 5809d4d2..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/projects.js +++ /dev/null @@ -1,9 +0,0 @@ -import { fetchAndStoreAllTopologiesOfProject } from './topology' - -export function* onOpenProjectSucceeded(action) { - try { - yield fetchAndStoreAllTopologiesOfProject(action.id, true) - } catch (error) { - console.error(error) - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index 2d61643b..fb6f7f0d 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -22,29 +22,10 @@ import { import { uuid } from 'uuidv4' import { fetchQuery, mutate } from './query' -/** - * Fetches all topologies of the project with the specified identifier. - */ -export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = false) { - try { - const project = yield fetchQuery(['projects', projectId]) - - for (const id of project.topologyIds) { - yield fetchAndStoreTopology(id) - } - - if (setTopology) { - yield put(setCurrentTopology(project.topologyIds[0])) - } - } catch (error) { - console.error(error) - } -} - /** * Fetches and normalizes the topology with the specified identifier. */ -export function* fetchAndStoreTopology(id) { +function* fetchAndStoreTopology(id) { let topology = yield select((state) => state.objects.topology[id]) if (!topology) { const newTopology = yield fetchQuery(['topologies', id]) @@ -58,7 +39,7 @@ export function* fetchAndStoreTopology(id) { /** * Synchronize the topology with the specified identifier with the server. */ -export function* updateTopologyOnServer(id) { +function* updateTopologyOnServer(id) { const topology = yield denormalizeTopology(id) yield mutate('updateTopology', topology) } @@ -66,12 +47,21 @@ export function* updateTopologyOnServer(id) { /** * Denormalizes the topology representation in order to be stored on the server. */ -export function* denormalizeTopology(id) { +function* denormalizeTopology(id) { const objects = yield select((state) => state.objects) const topology = objects.topology[id] return denormalize(topology, Topology, objects) } +export function* onOpenTopology({ id }) { + try { + yield fetchAndStoreTopology(id) + yield put(setCurrentTopology(id)) + } catch (error) { + console.error(error) + } +} + export function* onAddTopology({ projectId, duplicateId, name }) { try { let topologyToBeCreated -- cgit v1.2.3 From 28a4259c43e6180723b15a8c36a9b36871420f8a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 20 Jul 2021 14:59:58 +0200 Subject: feat(ui): Add table view for topology rooms --- .../src/components/topologies/RoomTable.js | 70 ++++++++++++++++++++++ .../src/components/topologies/TopologyOverview.js | 11 +++- .../src/redux/actions/interaction-level.js | 7 +++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js diff --git a/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js b/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js new file mode 100644 index 00000000..8a5c401f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js @@ -0,0 +1,70 @@ +import { Button } from '@patternfly/react-core' +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch } from 'react-redux' +import { useTopology } from '../../data/topology' +import { Table, TableBody, TableHeader } from '@patternfly/react-table' +import { goToRoom } from '../../redux/actions/interaction-level' +import { deleteRoom } from '../../redux/actions/topology/room' +import TableEmptyState from '../util/TableEmptyState' + +function RoomTable({ topologyId }) { + const dispatch = useDispatch() + const { status, data: topology } = useTopology(topologyId) + + const onClick = (room) => dispatch(goToRoom(room._id)) + const onDelete = (room) => dispatch(deleteRoom(room._id)) + + const columns = ['Name', 'Tiles', 'Racks'] + const rows = + topology?.rooms.length > 0 + ? topology.rooms.map((room) => { + const tileCount = room.tiles.length + const rackCount = room.tiles.filter((tile) => tile.rack).length + return [ + { + title: ( + + ), + }, + tileCount === 1 ? '1 tile' : `${tileCount} tiles`, + rackCount === 1 ? '1 rack' : `${rackCount} racks`, + ] + }) + : [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 3 }, + title: , + }, + ], + }, + ] + + const actions = + topology?.rooms.length > 0 + ? [ + { + title: 'Delete room', + onClick: (_, rowId) => onDelete(topology.rooms[rowId]), + }, + ] + : [] + + return ( + + + +
    + ) +} + +RoomTable.propTypes = { + topologyId: PropTypes.string, +} + +export default RoomTable diff --git a/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js b/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js index f773dcd1..761e7f9a 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js @@ -33,12 +33,13 @@ import { GridItem, Skeleton, } from '@patternfly/react-core' +import React from 'react' import { useTopology } from '../../data/topology' import { parseAndFormatDateTime } from '../../util/date-time' +import RoomTable from './RoomTable' function TopologyOverview({ topologyId }) { const { data: topology } = useTopology(topologyId) - return ( @@ -66,6 +67,14 @@ function TopologyOverview({ topologyId }) { + + + Rooms + + + + + ) } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js b/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js index ff6b1fa3..8381eeef 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js @@ -3,6 +3,13 @@ export const GO_FROM_ROOM_TO_RACK = 'GO_FROM_ROOM_TO_RACK' export const GO_FROM_RACK_TO_MACHINE = 'GO_FROM_RACK_TO_MACHINE' export const GO_DOWN_ONE_INTERACTION_LEVEL = 'GO_DOWN_ONE_INTERACTION_LEVEL' +export function goToRoom(roomId) { + return { + type: GO_FROM_BUILDING_TO_ROOM, + roomId, + } +} + export function goFromBuildingToRoom(roomId) { return (dispatch, getState) => { const { interactionLevel } = getState() -- cgit v1.2.3 From 54f424a18cc21a52ea518d40893218a07ab55989 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 21 Jul 2021 15:04:22 +0200 Subject: feat(ui): Extract topology construction out of Sagas This change updates the OpenDC frontend to perform the construction of the topology directly in the reducers instead of performing the mutations in Redux Sagas as side effects. This allows us to nicely map actions to mutations in the reducers. --- opendc-web/opendc-web-ui/package.json | 1 + .../src/components/topologies/TopologyMap.js | 2 +- .../src/components/topologies/map/MapStage.js | 10 +- .../topologies/map/RackEnergyFillContainer.js | 12 +- .../topologies/map/RackSpaceFillContainer.js | 2 +- .../src/components/topologies/map/RoomContainer.js | 2 +- .../src/components/topologies/map/TileContainer.js | 2 +- .../components/topologies/map/TopologyContainer.js | 3 +- .../src/components/topologies/map/WallContainer.js | 4 +- .../topologies/map/layers/ObjectHoverLayer.js | 4 +- .../topologies/map/layers/RoomHoverLayer.js | 10 +- .../topologies/sidebar/machine/DeleteMachine.js | 13 +- .../topologies/sidebar/machine/MachineSidebar.js | 8 +- .../topologies/sidebar/machine/UnitAddContainer.js | 2 +- .../sidebar/machine/UnitListContainer.js | 11 +- .../sidebar/machine/UnitTabsComponent.js | 16 +- .../topologies/sidebar/rack/DeleteRackContainer.js | 5 +- .../sidebar/rack/MachineListContainer.js | 4 +- .../topologies/sidebar/rack/RackNameContainer.js | 2 +- .../topologies/sidebar/rack/RackSidebar.js | 2 +- .../components/topologies/sidebar/room/RoomName.js | 2 +- opendc-web/opendc-web-ui/src/data/topology.js | 8 - .../opendc-web-ui/src/redux/actions/objects.js | 41 --- .../opendc-web-ui/src/redux/actions/prefabs.js | 33 --- .../opendc-web-ui/src/redux/actions/topologies.js | 3 +- .../src/redux/actions/topology/building.js | 56 ++-- .../src/redux/actions/topology/machine.js | 13 +- .../src/redux/actions/topology/rack.js | 16 +- .../src/redux/actions/topology/room.js | 32 +- .../src/redux/reducers/construction-mode.js | 3 - .../src/redux/reducers/current-ids.js | 10 - .../opendc-web-ui/src/redux/reducers/index.js | 6 +- .../src/redux/reducers/interaction-level.js | 23 +- .../opendc-web-ui/src/redux/reducers/objects.js | 56 ---- .../src/redux/reducers/topology/index.js | 44 +++ .../src/redux/reducers/topology/machine.js | 47 +++ .../src/redux/reducers/topology/rack.js | 66 +++++ .../src/redux/reducers/topology/room.js | 65 +++++ .../src/redux/reducers/topology/tile.js | 59 ++++ .../src/redux/reducers/topology/topology.js | 47 +++ opendc-web/opendc-web-ui/src/redux/sagas/index.js | 52 +--- .../opendc-web-ui/src/redux/sagas/prefabs.js | 18 -- opendc-web/opendc-web-ui/src/redux/sagas/query.js | 41 --- .../opendc-web-ui/src/redux/sagas/topology.js | 324 ++++----------------- .../opendc-web-ui/src/util/topology-schema.js | 18 +- opendc-web/opendc-web-ui/yarn.lock | 5 + 46 files changed, 564 insertions(+), 639 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/redux/actions/objects.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/actions/prefabs.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/current-ids.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/objects.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js create mode 100644 opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js delete mode 100644 opendc-web/opendc-web-ui/src/redux/sagas/query.js diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 84db4277..5a32806c 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -30,6 +30,7 @@ "approximate-number": "~2.0.0", "classnames": "~2.2.5", "husky": "~4.2.5", + "immer": "^9.0.5", "konva": "~7.2.5", "lint-staged": "~10.2.2", "mathjs": "~7.6.0", diff --git a/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js b/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js index c16f554c..2f27749f 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/TopologyMap.js @@ -39,7 +39,7 @@ import { useSelector } from 'react-redux' import TopologySidebar from './sidebar/TopologySidebar' function TopologyMap() { - const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') + const topologyIsLoading = useSelector((state) => !state.topology.root) const interactionLevel = useSelector((state) => state.interactionLevel) const [isExpanded, setExpanded] = useState(true) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js index 5d19b3ad..d8735cf1 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js @@ -1,8 +1,8 @@ -import React, { useRef, useState } from 'react' +import React, { useRef, useState, useContext } from 'react' import { HotKeys } from 'react-hotkeys' import { Stage } from 'react-konva' import { MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_MOVE_PIXELS_PER_EVENT, MAP_SCALE_PER_EVENT } from './MapConstants' -import { Provider, useStore } from 'react-redux' +import { ReactReduxContext } from 'react-redux' import useResizeObserver from 'use-resize-observer' import { mapContainer } from './MapStage.module.scss' import MapLayer from './layers/MapLayer' @@ -12,7 +12,7 @@ import ScaleIndicator from './controls/ScaleIndicator' import Toolbar from './controls/Toolbar' function MapStage() { - const store = useStore() + const reduxContext = useContext(ReactReduxContext) const { ref, width = 100, height = 100 } = useResizeObserver() const stageRef = useRef(null) const [[x, y], setPos] = useState([0, 0]) @@ -68,11 +68,11 @@ function MapStage() { x={x} y={y} > - + - + diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js index c35cbde7..be1f3e45 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js @@ -6,18 +6,18 @@ import RackFillBar from './elements/RackFillBar' function RackSpaceFillContainer({ tileId, ...props }) { const fillFraction = useSelector((state) => { let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[tileId].rack] + const rack = state.topology.racks[state.topology.tiles[tileId].rack] const machineIds = rack.machines machineIds.forEach((machineId) => { if (machineId !== null) { - const machine = state.objects.machine[machineId] - machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) + const machine = state.topology.machines[machineId] + machine.cpus.forEach((id) => (energyConsumptionTotal += state.topology.cpus[id].energyConsumptionW)) + machine.gpus.forEach((id) => (energyConsumptionTotal += state.topology.gpus[id].energyConsumptionW)) machine.memories.forEach( - (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) + (id) => (energyConsumptionTotal += state.topology.memories[id].energyConsumptionW) ) machine.storages.forEach( - (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) + (id) => (energyConsumptionTotal += state.topology.storages[id].energyConsumptionW) ) } }) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js index a6766f33..0c15d54b 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js @@ -26,7 +26,7 @@ import { useSelector } from 'react-redux' import RackFillBar from './elements/RackFillBar' function RackSpaceFillContainer({ tileId, ...props }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const rack = useSelector((state) => state.topology.racks[state.topology.tiles[tileId].rack]) return } diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js index 93ba9c93..65189891 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js @@ -31,7 +31,7 @@ function RoomContainer({ roomId, ...props }) { return { interactionLevel: state.interactionLevel, currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.objects.room[roomId], + room: state.topology.rooms[roomId], } }) const dispatch = useDispatch() diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js index 149e26a1..411a5ca7 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js @@ -28,7 +28,7 @@ import TileGroup from './groups/TileGroup' function TileContainer({ tileId, ...props }) { const interactionLevel = useSelector((state) => state.interactionLevel) - const tile = useSelector((state) => state.objects.tile[tileId]) + const tile = useSelector((state) => state.topology.tiles[tileId]) const dispatch = useDispatch() const onClick = (tile) => { diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js index eaebabd5..cc0d46b3 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js @@ -22,11 +22,10 @@ import React from 'react' import { useSelector } from 'react-redux' -import { useActiveTopology } from '../../../data/topology' import TopologyGroup from './groups/TopologyGroup' function TopologyContainer() { - const topology = useActiveTopology() + const topology = useSelector((state) => state.topology.root) const interactionLevel = useSelector((state) => state.interactionLevel) return diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js index 77f553dd..143f70c2 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js @@ -26,7 +26,9 @@ import { useSelector } from 'react-redux' import WallGroup from './groups/WallGroup' function WallContainer({ roomId, ...props }) { - const tiles = useSelector((state) => state.objects.room[roomId].tiles.map((tileId) => state.objects.tile[tileId])) + const tiles = useSelector((state) => { + return state.topology.rooms[roomId].tiles.map((tileId) => state.topology.tiles[tileId]) + }) return } diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js index 47d9c992..1f00de36 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js @@ -34,8 +34,8 @@ function ObjectHoverLayer() { return false } - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) + const currentRoom = state.topology.rooms[state.interactionLevel.roomId] + const tiles = currentRoom.tiles.map((tileId) => state.topology.tiles[tileId]) const tile = findTileWithPosition(tiles, x, y) return !(tile === null || tile.rack) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js index 59f83b2b..5e351691 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js @@ -35,17 +35,17 @@ function RoomHoverLayer() { const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) const isEnabled = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') const isValid = useSelector((state) => (x, y) => { - const newRoom = { ...state.objects.room[state.construction.currentRoomInConstruction] } - const oldRooms = Object.keys(state.objects.room) - .map((id) => ({ ...state.objects.room[id] })) + const newRoom = { ...state.topology.rooms[state.construction.currentRoomInConstruction] } + const oldRooms = Object.keys(state.topology.rooms) + .map((id) => ({ ...state.topology.rooms[id] })) .filter( (room) => - state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && + state.topology.root.rooms.indexOf(room._id) !== -1 && room._id !== state.construction.currentRoomInConstruction ) ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) + room.tiles = room.tiles.map((tileId) => state.topology.tiles[tileId]) }) if (newRoom.tiles.length === 0) { return findPositionInRooms(oldRooms, x, y) === -1 diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js index 00ce4603..a4b9457b 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/DeleteMachine.js @@ -20,21 +20,20 @@ * SOFTWARE. */ +import PropTypes from 'prop-types' import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import { Button } from '@patternfly/react-core' import { TrashIcon } from '@patternfly/react-icons' import ConfirmationModal from '../../../util/modals/ConfirmationModal' import { deleteMachine } from '../../../../redux/actions/topology/machine' -function DeleteMachine() { +function DeleteMachine({ machineId }) { const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) - const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rack) - const position = useSelector((state) => state.interactionLevel.position) const callback = (isConfirmed) => { if (isConfirmed) { - dispatch(deleteMachine(rackId, position)) + dispatch(deleteMachine(machineId)) } setVisible(false) } @@ -53,4 +52,8 @@ function DeleteMachine() { ) } +DeleteMachine.propTypes = { + machineId: PropTypes.string.isRequired, +} + export default DeleteMachine diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js index 0c3dea98..9268f615 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js @@ -13,9 +13,9 @@ import { import { useSelector } from 'react-redux' function MachineSidebar({ tileId, position }) { - const machine = useSelector(({ objects }) => { - const rack = objects.rack[objects.tile[tileId].rack] - return objects.machine[rack.machines[position - 1]] + const machine = useSelector(({ topology }) => { + const rack = topology.racks[topology.tiles[tileId].rack] + return topology.machines[rack.machines[position - 1]] }) const machineId = machine._id return ( @@ -30,7 +30,7 @@ function MachineSidebar({ tileId, position }) { Actions - + Units diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js index fc805b95..6b136120 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js @@ -27,7 +27,7 @@ import UnitAddComponent from './UnitAddComponent' import { addUnit } from '../../../../redux/actions/topology/machine' function UnitAddContainer({ machineId, unitType }) { - const units = useSelector((state) => Object.values(state.objects[unitType])) + const units = useSelector((state) => Object.values(state.topology[unitType])) const dispatch = useDispatch() const onAdd = (id) => dispatch(addUnit(machineId, unitType, id)) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js index 901fa45b..6dcc414f 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js @@ -26,18 +26,11 @@ import { useDispatch, useSelector } from 'react-redux' import UnitListComponent from './UnitListComponent' import { deleteUnit } from '../../../../redux/actions/topology/machine' -const unitMapping = { - cpu: 'cpus', - gpu: 'gpus', - memory: 'memories', - storage: 'storages', -} - function UnitListContainer({ machineId, unitType }) { const dispatch = useDispatch() const units = useSelector((state) => { - const machine = state.objects.machine[machineId] - return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) + const machine = state.topology.machines[machineId] + return machine[unitType].map((id) => state.topology[unitType][id]) }) const onDelete = (unit) => dispatch(deleteUnit(machineId, unitType, unit._id)) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js index 6d10d2df..b800e9d4 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitTabsComponent.js @@ -10,20 +10,20 @@ function UnitTabsComponent({ machineId }) { return ( setActiveTab(tab)}> CPU}> - - + + GPU}> - - + + Memory}> - - + + Storage}> - - + + ) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js index 80c6349a..0583a7a4 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js @@ -22,7 +22,7 @@ import PropTypes from 'prop-types' import React, { useState } from 'react' -import { useDispatch } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' import { Button } from '@patternfly/react-core' import ConfirmationModal from '../../../util/modals/ConfirmationModal' @@ -31,9 +31,10 @@ import { deleteRack } from '../../../../redux/actions/topology/rack' function DeleteRackContainer({ tileId }) { const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) + const rackId = useSelector((state) => state.topology.tiles[tileId].rack) const callback = (isConfirmed) => { if (isConfirmed) { - dispatch(deleteRack(tileId)) + dispatch(deleteRack(tileId, rackId)) } setVisible(false) } diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js index 6fbff949..619bb4e2 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js @@ -28,8 +28,8 @@ import { goFromRackToMachine } from '../../../../redux/actions/interaction-level import { addMachine } from '../../../../redux/actions/topology/rack' function MachineListContainer({ tileId, ...props }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) - const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) + const rack = useSelector((state) => state.topology.racks[state.topology.tiles[tileId].rack]) + const machines = useSelector((state) => rack.machines.map((id) => state.topology.machines[id])) const machinesNull = useMemo(() => { const res = Array(rack.capacity).fill(null) for (const machine of machines) { diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js index 09d73af7..30f38cce 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js @@ -5,7 +5,7 @@ import NameComponent from '../NameComponent' import { editRackName } from '../../../../redux/actions/topology/rack' const RackNameContainer = ({ tileId }) => { - const { name: rackName, _id } = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const { name: rackName, _id } = useSelector((state) => state.topology.racks[state.topology.tiles[tileId].rack]) const dispatch = useDispatch() const callback = (name) => { if (name) { diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js index 3c9f152a..8f6ff135 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js @@ -17,7 +17,7 @@ import { import { useSelector } from 'react-redux' function RackSidebar({ tileId }) { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const rack = useSelector((state) => state.topology.racks[state.topology.tiles[tileId].rack]) return (
    diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js index e8d8b33c..fb52d826 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/room/RoomName.js @@ -27,7 +27,7 @@ import NameComponent from '../NameComponent' import { editRoomName } from '../../../../redux/actions/topology/room' function RoomName({ roomId }) { - const { name: roomName, _id } = useSelector((state) => state.objects.room[roomId]) + const { name: roomName, _id } = useSelector((state) => state.topology.rooms[roomId]) const dispatch = useDispatch() const callback = (name) => { if (name) { diff --git a/opendc-web/opendc-web-ui/src/data/topology.js b/opendc-web/opendc-web-ui/src/data/topology.js index 83abb6aa..e068ed8e 100644 --- a/opendc-web/opendc-web-ui/src/data/topology.js +++ b/opendc-web/opendc-web-ui/src/data/topology.js @@ -20,7 +20,6 @@ * SOFTWARE. */ -import { useSelector } from 'react-redux' import { useQuery } from 'react-query' import { addTopology, deleteTopology, fetchTopologiesOfProject, fetchTopology, updateTopology } from '../api/topologies' @@ -63,13 +62,6 @@ export function configureTopologyClient(queryClient, auth) { }) } -/** - * Return the current active topology. - */ -export function useActiveTopology() { - return useSelector((state) => state.currentTopologyId !== '-1' && state.objects.topology[state.currentTopologyId]) -} - /** * Return the current active topology. */ diff --git a/opendc-web/opendc-web-ui/src/redux/actions/objects.js b/opendc-web/opendc-web-ui/src/redux/actions/objects.js deleted file mode 100644 index 7b648b18..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/objects.js +++ /dev/null @@ -1,41 +0,0 @@ -export const ADD_TO_STORE = 'ADD_TO_STORE' -export const ADD_PROP_TO_STORE_OBJECT = 'ADD_PROP_TO_STORE_OBJECT' -export const ADD_ID_TO_STORE_OBJECT_LIST_PROP = 'ADD_ID_TO_STORE_OBJECT_LIST_PROP' -export const REMOVE_ID_FROM_STORE_OBJECT_LIST_PROP = 'REMOVE_ID_FROM_STORE_OBJECT_LIST_PROP' - -export function addToStore(objectType, object) { - return { - type: ADD_TO_STORE, - objectType, - object, - } -} - -export function addPropToStoreObject(objectType, objectId, propObject) { - return { - type: ADD_PROP_TO_STORE_OBJECT, - objectType, - objectId, - propObject, - } -} - -export function addIdToStoreObjectListProp(objectType, objectId, propName, id) { - return { - type: ADD_ID_TO_STORE_OBJECT_LIST_PROP, - objectType, - objectId, - propName, - id, - } -} - -export function removeIdFromStoreObjectListProp(objectType, objectId, propName, id) { - return { - type: REMOVE_ID_FROM_STORE_OBJECT_LIST_PROP, - objectType, - objectId, - propName, - id, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js b/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js deleted file mode 100644 index 0ef7795f..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/prefabs.js +++ /dev/null @@ -1,33 +0,0 @@ -export const ADD_PREFAB = 'ADD_PREFAB' -export const DELETE_PREFAB = 'DELETE_PREFAB' -export const DELETE_PREFAB_SUCCEEDED = 'DELETE_PREFAB_SUCCEEDED' -export const OPEN_PREFAB_SUCCEEDED = 'OPEN_PREFAB_SUCCEEDED' - -export function addPrefab(name, tileId) { - return { - type: ADD_PREFAB, - name, - tileId, - } -} - -export function deletePrefab(id) { - return { - type: DELETE_PREFAB, - id, - } -} - -export function deletePrefabSucceeded(id) { - return { - type: DELETE_PREFAB_SUCCEEDED, - id, - } -} - -export function openPrefabSucceeded(id) { - return { - type: OPEN_PREFAB_SUCCEEDED, - id, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topologies.js b/opendc-web/opendc-web-ui/src/redux/actions/topologies.js index 4888c4da..fc697cc2 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topologies.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topologies.js @@ -18,9 +18,10 @@ export function addTopology(projectId, name, duplicateId) { } } -export function storeTopology(entities) { +export function storeTopology(topology, entities) { return { type: STORE_TOPOLOGY, + topology, entities, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js index 49425318..939c24a4 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js @@ -1,4 +1,6 @@ -export const SET_CURRENT_TOPOLOGY = 'SET_CURRENT_TOPOLOGY' +import { uuid } from 'uuidv4' +import { addRoom, deleteRoom } from './room' + export const START_NEW_ROOM_CONSTRUCTION = 'START_NEW_ROOM_CONSTRUCTION' export const START_NEW_ROOM_CONSTRUCTION_SUCCEEDED = 'START_NEW_ROOM_CONSTRUCTION_SUCCEEDED' export const FINISH_NEW_ROOM_CONSTRUCTION = 'FINISH_NEW_ROOM_CONSTRUCTION' @@ -9,16 +11,19 @@ export const FINISH_ROOM_EDIT = 'FINISH_ROOM_EDIT' export const ADD_TILE = 'ADD_TILE' export const DELETE_TILE = 'DELETE_TILE' -export function setCurrentTopology(topologyId) { - return { - type: SET_CURRENT_TOPOLOGY, - topologyId, - } -} - export function startNewRoomConstruction() { - return { - type: START_NEW_ROOM_CONSTRUCTION, + return (dispatch, getState) => { + const { topology } = getState() + const topologyId = topology.root._id + const room = { + _id: uuid(), + name: 'Room', + topologyId, + tiles: [], + } + + dispatch(addRoom(topologyId, room)) + dispatch(startNewRoomConstructionSucceeded(room._id)) } } @@ -31,8 +36,8 @@ export function startNewRoomConstructionSucceeded(roomId) { export function finishNewRoomConstruction() { return (dispatch, getState) => { - const { objects, construction } = getState() - if (objects.room[construction.currentRoomInConstruction].tiles.length === 0) { + const { topology, construction } = getState() + if (topology.rooms[construction.currentRoomInConstruction].tiles.length === 0) { dispatch(cancelNewRoomConstruction()) return } @@ -44,8 +49,11 @@ export function finishNewRoomConstruction() { } export function cancelNewRoomConstruction() { - return { - type: CANCEL_NEW_ROOM_CONSTRUCTION, + return (dispatch, getState) => { + const { construction } = getState() + const roomId = construction.currentRoomInConstruction + dispatch(deleteRoom(roomId)) + dispatch(cancelNewRoomConstructionSucceeded()) } } @@ -70,24 +78,30 @@ export function finishRoomEdit() { export function toggleTileAtLocation(positionX, positionY) { return (dispatch, getState) => { - const { objects, construction } = getState() + const { topology, construction } = getState() - const tileIds = objects.room[construction.currentRoomInConstruction].tiles + const roomId = construction.currentRoomInConstruction + const tileIds = topology.rooms[roomId].tiles for (const tileId of tileIds) { - if (objects.tile[tileId].positionX === positionX && objects.tile[tileId].positionY === positionY) { + if (topology.tiles[tileId].positionX === positionX && topology.tiles[tileId].positionY === positionY) { dispatch(deleteTile(tileId)) return } } - dispatch(addTile(positionX, positionY)) + + dispatch(addTile(roomId, positionX, positionY)) } } -export function addTile(positionX, positionY) { +export function addTile(roomId, positionX, positionY) { return { type: ADD_TILE, - positionX, - positionY, + tile: { + _id: uuid(), + roomId, + positionX, + positionY, + }, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js index 170b7648..93320884 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js @@ -2,28 +2,27 @@ export const DELETE_MACHINE = 'DELETE_MACHINE' export const ADD_UNIT = 'ADD_UNIT' export const DELETE_UNIT = 'DELETE_UNIT' -export function deleteMachine(rackId, position) { +export function deleteMachine(machineId) { return { type: DELETE_MACHINE, - rackId, - position, + machineId, } } -export function addUnit(machineId, unitType, id) { +export function addUnit(machineId, unitType, unitId) { return { type: ADD_UNIT, machineId, unitType, - id, + unitId, } } -export function deleteUnit(machineId, unitType, index) { +export function deleteUnit(machineId, unitType, unitId) { return { type: DELETE_UNIT, machineId, unitType, - index, + unitId, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js index 228e3ae9..c319d966 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js @@ -1,3 +1,5 @@ +import { uuid } from 'uuidv4' + export const EDIT_RACK_NAME = 'EDIT_RACK_NAME' export const DELETE_RACK = 'DELETE_RACK' export const ADD_MACHINE = 'ADD_MACHINE' @@ -10,9 +12,10 @@ export function editRackName(rackId, name) { } } -export function deleteRack(tileId) { +export function deleteRack(tileId, rackId) { return { type: DELETE_RACK, + rackId, tileId, } } @@ -20,7 +23,14 @@ export function deleteRack(tileId) { export function addMachine(rackId, position) { return { type: ADD_MACHINE, - position, - rackId, + machine: { + _id: uuid(), + rackId, + position, + cpus: [], + gpus: [], + memories: [], + storages: [], + }, } } diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js index e584af89..bd447db5 100644 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js +++ b/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js @@ -1,11 +1,28 @@ +import { uuid } from 'uuidv4' +import { + DEFAULT_RACK_SLOT_CAPACITY, + DEFAULT_RACK_POWER_CAPACITY, +} from '../../../components/topologies/map/MapConstants' import { findTileWithPosition } from '../../../util/tile-calculations' +export const ADD_ROOM = 'ADD_ROOM' export const EDIT_ROOM_NAME = 'EDIT_ROOM_NAME' export const DELETE_ROOM = 'DELETE_ROOM' export const START_RACK_CONSTRUCTION = 'START_RACK_CONSTRUCTION' export const STOP_RACK_CONSTRUCTION = 'STOP_RACK_CONSTRUCTION' export const ADD_RACK_TO_TILE = 'ADD_RACK_TO_TILE' +export function addRoom(topologyId, room) { + return { + type: ADD_ROOM, + room: { + _id: uuid(), + topologyId, + ...room, + }, + } +} + export function editRoomName(roomId, name) { return { type: EDIT_ROOM_NAME, @@ -28,15 +45,22 @@ export function stopRackConstruction() { export function addRackToTile(positionX, positionY) { return (dispatch, getState) => { - const { objects, interactionLevel } = getState() - const currentRoom = objects.room[interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => objects.tile[tileId]) + const { topology, interactionLevel } = getState() + const currentRoom = topology.rooms[interactionLevel.roomId] + const tiles = currentRoom.tiles.map((tileId) => topology.tiles[tileId]) const tile = findTileWithPosition(tiles, positionX, positionY) if (tile !== null) { dispatch({ type: ADD_RACK_TO_TILE, - tileId: tile._id, + rack: { + _id: uuid(), + name: 'Rack', + tileId: tile._id, + capacity: DEFAULT_RACK_SLOT_CAPACITY, + powerCapacityW: DEFAULT_RACK_POWER_CAPACITY, + machines: [], + }, }) } } diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js b/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js index 5bac7fea..d0aac5ae 100644 --- a/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js +++ b/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js @@ -4,7 +4,6 @@ import { CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED, FINISH_NEW_ROOM_CONSTRUCTION, FINISH_ROOM_EDIT, - SET_CURRENT_TOPOLOGY, START_NEW_ROOM_CONSTRUCTION_SUCCEEDED, START_ROOM_EDIT, } from '../actions/topology/building' @@ -19,7 +18,6 @@ export function currentRoomInConstruction(state = '-1', action) { case CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED: case FINISH_NEW_ROOM_CONSTRUCTION: case FINISH_ROOM_EDIT: - case SET_CURRENT_TOPOLOGY: case DELETE_ROOM: return '-1' default: @@ -32,7 +30,6 @@ export function inRackConstructionMode(state = false, action) { case START_RACK_CONSTRUCTION: return true case STOP_RACK_CONSTRUCTION: - case SET_CURRENT_TOPOLOGY: case GO_DOWN_ONE_INTERACTION_LEVEL: return false default: diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/current-ids.js b/opendc-web/opendc-web-ui/src/redux/reducers/current-ids.js deleted file mode 100644 index c0baf567..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/current-ids.js +++ /dev/null @@ -1,10 +0,0 @@ -import { SET_CURRENT_TOPOLOGY } from '../actions/topology/building' - -export function currentTopologyId(state = '-1', action) { - switch (action.type) { - case SET_CURRENT_TOPOLOGY: - return action.topologyId - default: - return state - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/index.js b/opendc-web/opendc-web-ui/src/redux/reducers/index.js index 2f1359d6..7ffb1211 100644 --- a/opendc-web/opendc-web-ui/src/redux/reducers/index.js +++ b/opendc-web/opendc-web-ui/src/redux/reducers/index.js @@ -1,13 +1,11 @@ import { combineReducers } from 'redux' import { construction } from './construction-mode' -import { currentTopologyId } from './current-ids' import { interactionLevel } from './interaction-level' -import { objects } from './objects' +import topology from './topology' const rootReducer = combineReducers({ - objects, + topology, construction, - currentTopologyId, interactionLevel, }) diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js b/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js index 9f23949f..b30c68b9 100644 --- a/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js +++ b/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js @@ -4,14 +4,12 @@ import { GO_FROM_RACK_TO_MACHINE, GO_FROM_ROOM_TO_RACK, } from '../actions/interaction-level' -import { SET_CURRENT_TOPOLOGY } from '../actions/topology/building' +import { DELETE_MACHINE } from '../actions/topology/machine' +import { DELETE_RACK } from '../actions/topology/rack' +import { DELETE_ROOM } from '../actions/topology/room' export function interactionLevel(state = { mode: 'BUILDING' }, action) { switch (action.type) { - case SET_CURRENT_TOPOLOGY: - return { - mode: 'BUILDING', - } case GO_FROM_BUILDING_TO_ROOM: return { mode: 'ROOM', @@ -49,6 +47,21 @@ export function interactionLevel(state = { mode: 'BUILDING' }, action) { } else { return state } + case DELETE_MACHINE: + return { + mode: 'RACK', + roomId: state.roomId, + tileId: state.tileId, + } + case DELETE_RACK: + return { + mode: 'ROOM', + roomId: state.roomId, + } + case DELETE_ROOM: + return { + mode: 'BUILDING', + } default: return state } diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/objects.js b/opendc-web/opendc-web-ui/src/redux/reducers/objects.js deleted file mode 100644 index 11f6d353..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/objects.js +++ /dev/null @@ -1,56 +0,0 @@ -import { combineReducers } from 'redux' -import { - ADD_ID_TO_STORE_OBJECT_LIST_PROP, - ADD_PROP_TO_STORE_OBJECT, - ADD_TO_STORE, - REMOVE_ID_FROM_STORE_OBJECT_LIST_PROP, -} from '../actions/objects' -import { CPU_UNITS, GPU_UNITS, MEMORY_UNITS, STORAGE_UNITS } from '../../util/unit-specifications' -import { STORE_TOPOLOGY } from '../actions/topologies' - -export const objects = combineReducers({ - cpu: object('cpu', CPU_UNITS), - gpu: object('gpu', GPU_UNITS), - memory: object('memory', MEMORY_UNITS), - storage: object('storage', STORAGE_UNITS), - machine: object('machine'), - rack: object('rack'), - tile: object('tile'), - room: object('room'), - topology: object('topology'), - prefab: object('prefab'), -}) - -function object(type, defaultState = {}) { - return objectWithId(type, (object) => object._id, defaultState) -} - -function objectWithId(type, getId, defaultState = {}) { - return (state = defaultState, action) => { - if (action.type === STORE_TOPOLOGY) { - return { ...state, ...action.entities[type] } - } else if (action.objectType !== type) { - return state - } - - if (action.type === ADD_TO_STORE) { - return { ...state, [getId(action.object)]: action.object } - } else if (action.type === ADD_PROP_TO_STORE_OBJECT) { - return { ...state, [action.objectId]: { ...state[action.objectId], ...action.propObject } } - } else if (action.type === ADD_ID_TO_STORE_OBJECT_LIST_PROP) { - return Object.assign({}, state, { - [action.objectId]: Object.assign({}, state[action.objectId], { - [action.propName]: [...state[action.objectId][action.propName], action.id], - }), - }) - } else if (action.type === REMOVE_ID_FROM_STORE_OBJECT_LIST_PROP) { - return Object.assign({}, state, { - [action.objectId]: Object.assign({}, state[action.objectId], { - [action.propName]: state[action.objectId][action.propName].filter((id) => id !== action.id), - }), - }) - } - - return state - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js new file mode 100644 index 00000000..b1c7d29e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { CPU_UNITS, GPU_UNITS, MEMORY_UNITS, STORAGE_UNITS } from '../../../util/unit-specifications' +import machine from './machine' +import rack from './rack' +import room from './room' +import tile from './tile' +import topology from './topology' + +function objects(state = {}, action) { + return { + cpus: CPU_UNITS, + gpus: GPU_UNITS, + memories: MEMORY_UNITS, + storages: STORAGE_UNITS, + machines: machine(state.machines, action, state), + racks: rack(state.racks, action, state), + tiles: tile(state.tiles, action, state), + rooms: room(state.rooms, action, state), + root: topology(state.root, action, state), + } +} + +export default objects diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js new file mode 100644 index 00000000..41773014 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js @@ -0,0 +1,47 @@ +import produce from 'immer' +import { STORE_TOPOLOGY } from '../../actions/topologies' +import { DELETE_MACHINE, ADD_UNIT, DELETE_UNIT } from '../../actions/topology/machine' +import { ADD_MACHINE, DELETE_RACK } from '../../actions/topology/rack' + +function machine(state = {}, action, { racks }) { + switch (action.type) { + case STORE_TOPOLOGY: + return action.entities.machines || {} + case ADD_MACHINE: + return produce(state, (draft) => { + const { machine } = action + draft[machine._id] = machine + }) + case DELETE_MACHINE: + return produce(state, (draft) => { + const { machineId } = action + delete draft[machineId] + }) + case ADD_UNIT: + return produce(state, (draft) => { + const { machineId, unitType, unitId } = action + draft[machineId][unitType].push(unitId) + }) + case DELETE_UNIT: + return produce(state, (draft) => { + const { machineId, unitType, unitId } = action + const units = draft[machineId][unitType] + const index = units.indexOf(unitId) + units.splice(index, 1) + }) + case DELETE_RACK: + return produce(state, (draft) => { + const { rackId } = action + const rack = racks[rackId] + + for (const id of rack.machines) { + const machine = draft[id] + machine.rackId = undefined + } + }) + default: + return state + } +} + +export default machine diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js new file mode 100644 index 00000000..9cc37124 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import produce from 'immer' +import { STORE_TOPOLOGY } from '../../actions/topologies' +import { DELETE_MACHINE } from '../../actions/topology/machine' +import { DELETE_RACK, EDIT_RACK_NAME, ADD_MACHINE } from '../../actions/topology/rack' +import { ADD_RACK_TO_TILE } from '../../actions/topology/room' + +function rack(state = {}, action, { machines }) { + switch (action.type) { + case STORE_TOPOLOGY: + return action.entities.racks || {} + case ADD_RACK_TO_TILE: + return produce(state, (draft) => { + const { rack } = action + draft[rack._id] = rack + }) + case EDIT_RACK_NAME: + return produce(state, (draft) => { + const { rackId, name } = action + draft[rackId].name = name + }) + case DELETE_RACK: + return produce(state, (draft) => { + const { rackId } = action + delete draft[rackId] + }) + case ADD_MACHINE: + return produce(state, (draft) => { + const { machine } = action + draft[machine.rackId].machines.push(machine._id) + }) + case DELETE_MACHINE: + return produce(state, (draft) => { + const { machineId } = action + const machine = machines[machineId] + const rack = draft[machine.rackId] + const index = rack.machines.indexOf(machineId) + rack.machines.splice(index, 1) + }) + default: + return state + } +} + +export default rack diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js new file mode 100644 index 00000000..b61c9d82 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import produce from 'immer' +import { STORE_TOPOLOGY } from '../../actions/topologies' +import { ADD_TILE, DELETE_TILE } from '../../actions/topology/building' +import { DELETE_ROOM, EDIT_ROOM_NAME, ADD_ROOM } from '../../actions/topology/room' + +function room(state = {}, action, { tiles }) { + switch (action.type) { + case STORE_TOPOLOGY: + return action.entities.rooms || {} + case ADD_ROOM: + return produce(state, (draft) => { + const { room } = action + draft[room._id] = room + }) + case DELETE_ROOM: + return produce(state, (draft) => { + const { roomId } = action + delete draft[roomId] + }) + case EDIT_ROOM_NAME: + return produce(state, (draft) => { + const { roomId, name } = action + draft[roomId].name = name + }) + case ADD_TILE: + return produce(state, (draft) => { + const { tile } = action + draft[tile.roomId].tiles.push(tile._id) + }) + case DELETE_TILE: + return produce(state, (draft) => { + const { tileId } = action + const tile = tiles[tileId] + const room = draft[tile.roomId] + const index = room.tiles.indexOf(tileId) + room.tiles.splice(index, 1) + }) + default: + return state + } +} + +export default room diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js new file mode 100644 index 00000000..e0c5dd33 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import produce from 'immer' +import { STORE_TOPOLOGY } from '../../actions/topologies' +import { ADD_TILE, DELETE_TILE } from '../../actions/topology/building' +import { DELETE_RACK } from '../../actions/topology/rack' +import { ADD_RACK_TO_TILE } from '../../actions/topology/room' + +function tile(state = {}, action, { racks }) { + switch (action.type) { + case STORE_TOPOLOGY: + return action.entities.tiles || {} + case ADD_TILE: + return produce(state, (draft) => { + const { tile } = action + draft[tile._id] = tile + }) + case DELETE_TILE: + return produce(state, (draft) => { + const { tileId } = action + delete draft[tileId] + }) + case ADD_RACK_TO_TILE: + return produce(state, (draft) => { + const { rack } = action + draft[rack.tileId].rack = rack._id + }) + case DELETE_RACK: + return produce(state, (draft) => { + const { rackId } = action + const rack = racks[rackId] + draft[rack.tileId].rack = undefined + }) + default: + return state + } +} + +export default tile diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js new file mode 100644 index 00000000..da0e6988 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import produce from 'immer' +import { STORE_TOPOLOGY } from '../../actions/topologies' +import { ADD_ROOM, DELETE_ROOM } from '../../actions/topology/room' + +function topology(state = undefined, action) { + switch (action.type) { + case STORE_TOPOLOGY: + return action.topology + case ADD_ROOM: + return produce(state, (draft) => { + const { room } = action + draft.rooms.push(room._id) + }) + case DELETE_ROOM: + return produce(state, (draft) => { + const { roomId } = action + const index = draft.rooms.indexOf(roomId) + draft.rooms.splice(index, 1) + }) + default: + return state + } +} + +export default topology diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/index.js b/opendc-web/opendc-web-ui/src/redux/sagas/index.js index 9ddc564d..0fabdb6d 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/index.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/index.js @@ -1,51 +1,7 @@ -import { takeEvery } from 'redux-saga/effects' -import { - ADD_TILE, - CANCEL_NEW_ROOM_CONSTRUCTION, - DELETE_TILE, - START_NEW_ROOM_CONSTRUCTION, -} from '../actions/topology/building' -import { ADD_UNIT, DELETE_MACHINE, DELETE_UNIT } from '../actions/topology/machine' -import { ADD_MACHINE, DELETE_RACK, EDIT_RACK_NAME } from '../actions/topology/rack' -import { ADD_RACK_TO_TILE, DELETE_ROOM, EDIT_ROOM_NAME } from '../actions/topology/room' -import { - onAddMachine, - onAddRackToTile, - onAddTile, - onAddTopology, - onAddUnit, - onCancelNewRoomConstruction, - onDeleteMachine, - onDeleteRack, - onDeleteRoom, - onDeleteTile, - onDeleteUnit, - onEditRackName, - onEditRoomName, - onStartNewRoomConstruction, - onOpenTopology, -} from './topology' -import { ADD_TOPOLOGY, OPEN_TOPOLOGY } from '../actions/topologies' -import { onAddPrefab } from './prefabs' -import { ADD_PREFAB } from '../actions/prefabs' +import { fork } from 'redux-saga/effects' +import { watchServer, updateServer } from './topology' export default function* rootSaga() { - yield takeEvery(OPEN_TOPOLOGY, onOpenTopology) - - yield takeEvery(ADD_TOPOLOGY, onAddTopology) - yield takeEvery(START_NEW_ROOM_CONSTRUCTION, onStartNewRoomConstruction) - yield takeEvery(CANCEL_NEW_ROOM_CONSTRUCTION, onCancelNewRoomConstruction) - yield takeEvery(ADD_TILE, onAddTile) - yield takeEvery(DELETE_TILE, onDeleteTile) - yield takeEvery(EDIT_ROOM_NAME, onEditRoomName) - yield takeEvery(DELETE_ROOM, onDeleteRoom) - yield takeEvery(EDIT_RACK_NAME, onEditRackName) - yield takeEvery(DELETE_RACK, onDeleteRack) - yield takeEvery(ADD_RACK_TO_TILE, onAddRackToTile) - yield takeEvery(ADD_MACHINE, onAddMachine) - yield takeEvery(DELETE_MACHINE, onDeleteMachine) - yield takeEvery(ADD_UNIT, onAddUnit) - yield takeEvery(DELETE_UNIT, onDeleteUnit) - - yield takeEvery(ADD_PREFAB, onAddPrefab) + yield fork(watchServer) + yield fork(updateServer) } diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js b/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js deleted file mode 100644 index f717d878..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js +++ /dev/null @@ -1,18 +0,0 @@ -import { call, put, select, getContext } from 'redux-saga/effects' -import { addToStore } from '../actions/objects' -import { addPrefab } from '../../api/prefabs' -import { Rack } from '../../util/topology-schema' -import { denormalize } from 'normalizr' - -export function* onAddPrefab({ name, tileId }) { - try { - const objects = yield select((state) => state.objects) - const rack = objects.rack[objects.tile[tileId].rack] - const prefabRack = denormalize(rack, Rack, objects) - const auth = yield getContext('auth') - const prefab = yield call(() => addPrefab(auth, { name, rack: prefabRack })) - yield put(addToStore('prefab', prefab)) - } catch (error) { - console.error(error) - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/query.js b/opendc-web/opendc-web-ui/src/redux/sagas/query.js deleted file mode 100644 index 787006c7..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/query.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import { MutationObserver } from 'react-query' -import { getContext, call } from 'redux-saga/effects' - -/** - * Fetch the query with the specified key. - */ -export function* fetchQuery(key, options) { - const queryClient = yield getContext('queryClient') - return yield call([queryClient, queryClient.fetchQuery], key, options) -} - -/** - * Perform a mutation with the specified key. - */ -export function* mutate(key, object, options) { - const queryClient = yield getContext('queryClient') - const mutationObserver = new MutationObserver(queryClient, { mutationKey: key }) - return yield call([mutationObserver, mutationObserver.mutate], object, options) -} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index fb6f7f0d..f40cff28 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -1,287 +1,75 @@ +import { QueryObserver, MutationObserver } from 'react-query' import { normalize, denormalize } from 'normalizr' -import { put, select } from 'redux-saga/effects' +import { select, put, take, race, getContext, call } from 'redux-saga/effects' +import { eventChannel } from 'redux-saga' import { Topology } from '../../util/topology-schema' -import { goDownOneInteractionLevel } from '../actions/interaction-level' -import { - addIdToStoreObjectListProp, - addPropToStoreObject, - addToStore, - removeIdFromStoreObjectListProp, -} from '../actions/objects' -import { storeTopology } from '../actions/topologies' -import { - cancelNewRoomConstructionSucceeded, - setCurrentTopology, - startNewRoomConstructionSucceeded, -} from '../actions/topology/building' -import { - DEFAULT_RACK_POWER_CAPACITY, - DEFAULT_RACK_SLOT_CAPACITY, - MAX_NUM_UNITS_PER_MACHINE, -} from '../../components/topologies/map/MapConstants' -import { uuid } from 'uuidv4' -import { fetchQuery, mutate } from './query' +import { storeTopology, OPEN_TOPOLOGY } from '../actions/topologies' /** - * Fetches and normalizes the topology with the specified identifier. + * Update the topology on the server. */ -function* fetchAndStoreTopology(id) { - let topology = yield select((state) => state.objects.topology[id]) - if (!topology) { - const newTopology = yield fetchQuery(['topologies', id]) - const { entities } = normalize(newTopology, Topology) - yield put(storeTopology(entities)) - } - - return topology -} - -/** - * Synchronize the topology with the specified identifier with the server. - */ -function* updateTopologyOnServer(id) { - const topology = yield denormalizeTopology(id) - yield mutate('updateTopology', topology) -} - -/** - * Denormalizes the topology representation in order to be stored on the server. - */ -function* denormalizeTopology(id) { - const objects = yield select((state) => state.objects) - const topology = objects.topology[id] - return denormalize(topology, Topology, objects) -} - -export function* onOpenTopology({ id }) { - try { - yield fetchAndStoreTopology(id) - yield put(setCurrentTopology(id)) - } catch (error) { - console.error(error) - } -} - -export function* onAddTopology({ projectId, duplicateId, name }) { - try { - let topologyToBeCreated - if (duplicateId) { - topologyToBeCreated = yield denormalizeTopology(duplicateId) - topologyToBeCreated = { ...topologyToBeCreated, name } - delete topologyToBeCreated._id - } else { - topologyToBeCreated = { name, rooms: [] } - } - - const topology = yield mutate('addTopology', { ...topologyToBeCreated, projectId }) - yield fetchAndStoreTopology(topology._id) - yield put(setCurrentTopology(topology._id)) - } catch (error) { - console.error(error) - } -} - -export function* onStartNewRoomConstruction() { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const room = { - _id: uuid(), - name: 'Room', - topologyId, - tiles: [], - } - yield put(addToStore('room', room)) - yield put(addIdToStoreObjectListProp('topology', topologyId, 'rooms', room._id)) - yield updateTopologyOnServer(topologyId) - yield put(startNewRoomConstructionSucceeded(room._id)) - } catch (error) { - console.error(error) - } -} - -export function* onCancelNewRoomConstruction() { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const roomId = yield select((state) => state.construction.currentRoomInConstruction) - yield put(removeIdFromStoreObjectListProp('topology', topologyId, 'rooms', roomId)) - // TODO remove room from store, too - yield updateTopologyOnServer(topologyId) - yield put(cancelNewRoomConstructionSucceeded()) - } catch (error) { - console.error(error) - } -} +export function* updateServer() { + const queryClient = yield getContext('queryClient') + const mutationObserver = new MutationObserver(queryClient, { mutationKey: 'updateTopology' }) + + while (true) { + yield take( + (action) => + action.type.startsWith('EDIT') || action.type.startsWith('ADD') || action.type.startsWith('DELETE') + ) + const topology = yield select((state) => state.topology) -export function* onAddTile(action) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const roomId = yield select((state) => state.construction.currentRoomInConstruction) - const tile = { - _id: uuid(), - roomId, - positionX: action.positionX, - positionY: action.positionY, + if (!topology.root) { + continue } - yield put(addToStore('tile', tile)) - yield put(addIdToStoreObjectListProp('room', roomId, 'tiles', tile._id)) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} - -export function* onDeleteTile(action) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const roomId = yield select((state) => state.construction.currentRoomInConstruction) - yield put(removeIdFromStoreObjectListProp('room', roomId, 'tiles', action.tileId)) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} -export function* onEditRoomName({ roomId, name }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - yield put(addPropToStoreObject('room', roomId, { name })) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) + const denormalizedTopology = denormalize(topology.root, Topology, topology) + yield call([mutationObserver, mutationObserver.mutate], denormalizedTopology) } } -export function* onDeleteRoom({ roomId }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - yield put(goDownOneInteractionLevel()) - yield put(removeIdFromStoreObjectListProp('topology', topologyId, 'rooms', roomId)) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} - -export function* onEditRackName({ rackId, name }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - yield put(addPropToStoreObject('rack', rackId, { name })) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} - -export function* onDeleteRack({ tileId }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - yield put(goDownOneInteractionLevel()) - yield put(addPropToStoreObject('tile', tileId, { rack: undefined })) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} - -export function* onAddRackToTile({ tileId }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const rack = { - _id: uuid(), - name: 'Rack', - tileId, - capacity: DEFAULT_RACK_SLOT_CAPACITY, - powerCapacityW: DEFAULT_RACK_POWER_CAPACITY, - machines: [], - } - yield put(addToStore('rack', rack)) - yield put(addPropToStoreObject('tile', tileId, { rack: rack._id })) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} - -export function* onAddMachine({ rackId, position }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const rack = yield select((state) => state.objects.rack[rackId]) - - const machine = { - _id: uuid(), - rackId, - position, - cpus: [], - gpus: [], - memories: [], - storages: [], +/** + * Watch the topology on the server for changes. + */ +export function* watchServer() { + let { id } = yield take(OPEN_TOPOLOGY) + while (true) { + const channel = yield queryObserver(id) + + while (true) { + const [action, response] = yield race([take(OPEN_TOPOLOGY), take(channel)]) + + if (action) { + id = action.id + break + } + + const { isFetched, data } = response + // Only update the topology on the client-side when a new topology was fetched + if (isFetched) { + const { result: topologyId, entities } = normalize(data, Topology) + yield put(storeTopology(entities.topologies[topologyId], entities)) + } } - yield put(addToStore('machine', machine)) - - const machineIds = [...rack.machines, machine._id] - yield put(addPropToStoreObject('rack', rackId, { machines: machineIds })) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} - -export function* onDeleteMachine({ rackId, position }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const rack = yield select((state) => state.objects.rack[rackId]) - yield put(goDownOneInteractionLevel()) - yield put( - addPropToStoreObject('rack', rackId, { machines: rack.machines.filter((_, idx) => idx !== position - 1) }) - ) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) } } -const unitMapping = { - cpu: 'cpus', - gpu: 'gpus', - memory: 'memories', - storage: 'storages', -} - -export function* onAddUnit({ machineId, unitType, id }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const machine = yield select((state) => state.objects.machine[machineId]) - - if (machine[unitMapping[unitType]].length >= MAX_NUM_UNITS_PER_MACHINE) { - return - } +/** + * Observe changes for the topology with the specified identifier. + */ +function* queryObserver(id) { + const queryClient = yield getContext('queryClient') + const observer = new QueryObserver(queryClient, { queryKey: ['topologies', id] }) - const units = [...machine[unitMapping[unitType]], id] - yield put( - addPropToStoreObject('machine', machine._id, { - [unitMapping[unitType]]: units, - }) - ) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } -} + return eventChannel((emitter) => { + const unsubscribe = observer.subscribe((result) => { + emitter(result) + }) -export function* onDeleteUnit({ machineId, unitType, index }) { - try { - const topologyId = yield select((state) => state.currentTopologyId) - const machine = yield select((state) => state.objects.machine[machineId]) - const unitIds = machine[unitMapping[unitType]].slice() - unitIds.splice(index, 1) + // Update result to make sure we did not miss any query updates + // between creating the observer and subscribing to it. + observer.updateResult() - yield put( - addPropToStoreObject('machine', machine._id, { - [unitMapping[unitType]]: unitIds, - }) - ) - yield updateTopologyOnServer(topologyId) - } catch (error) { - console.error(error) - } + return unsubscribe + }) } diff --git a/opendc-web/opendc-web-ui/src/util/topology-schema.js b/opendc-web/opendc-web-ui/src/util/topology-schema.js index 9acd688b..7779ccfe 100644 --- a/opendc-web/opendc-web-ui/src/util/topology-schema.js +++ b/opendc-web/opendc-web-ui/src/util/topology-schema.js @@ -22,13 +22,13 @@ import { schema } from 'normalizr' -const Cpu = new schema.Entity('cpu', {}, { idAttribute: '_id' }) -const Gpu = new schema.Entity('gpu', {}, { idAttribute: '_id' }) -const Memory = new schema.Entity('memory', {}, { idAttribute: '_id' }) -const Storage = new schema.Entity('storage', {}, { idAttribute: '_id' }) +const Cpu = new schema.Entity('cpus', {}, { idAttribute: '_id' }) +const Gpu = new schema.Entity('gpus', {}, { idAttribute: '_id' }) +const Memory = new schema.Entity('memories', {}, { idAttribute: '_id' }) +const Storage = new schema.Entity('storages', {}, { idAttribute: '_id' }) export const Machine = new schema.Entity( - 'machine', + 'machines', { cpus: [Cpu], gpus: [Gpu], @@ -38,10 +38,10 @@ export const Machine = new schema.Entity( { idAttribute: '_id' } ) -export const Rack = new schema.Entity('rack', { machines: [Machine] }, { idAttribute: '_id' }) +export const Rack = new schema.Entity('racks', { machines: [Machine] }, { idAttribute: '_id' }) -export const Tile = new schema.Entity('tile', { rack: Rack }, { idAttribute: '_id' }) +export const Tile = new schema.Entity('tiles', { rack: Rack }, { idAttribute: '_id' }) -export const Room = new schema.Entity('room', { tiles: [Tile] }, { idAttribute: '_id' }) +export const Room = new schema.Entity('rooms', { tiles: [Tile] }, { idAttribute: '_id' }) -export const Topology = new schema.Entity('topology', { rooms: [Room] }, { idAttribute: '_id' }) +export const Topology = new schema.Entity('topologies', { rooms: [Room] }, { idAttribute: '_id' }) diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 78122b5d..062766dd 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -2120,6 +2120,11 @@ image-size@1.0.0: dependencies: queue "6.0.2" +immer@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.5.tgz#a7154f34fe7064f15f00554cc94c66cc0bf453ec" + integrity sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ== + import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" -- cgit v1.2.3 From 7f083b47c2e2333819823fd7835332a0f486b626 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 21 Jul 2021 17:31:45 +0200 Subject: feat(ui): Toggle to Floor Plan on room select --- .../src/components/topologies/RoomTable.js | 7 +++--- .../src/components/topologies/TopologyOverview.js | 5 ++-- .../projects/[project]/topologies/[topology].js | 29 +++++++++++----------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js b/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js index 8a5c401f..9bf369e9 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/RoomTable.js @@ -4,15 +4,13 @@ import React from 'react' import { useDispatch } from 'react-redux' import { useTopology } from '../../data/topology' import { Table, TableBody, TableHeader } from '@patternfly/react-table' -import { goToRoom } from '../../redux/actions/interaction-level' import { deleteRoom } from '../../redux/actions/topology/room' import TableEmptyState from '../util/TableEmptyState' -function RoomTable({ topologyId }) { +function RoomTable({ topologyId, onSelect }) { const dispatch = useDispatch() const { status, data: topology } = useTopology(topologyId) - const onClick = (room) => dispatch(goToRoom(room._id)) const onDelete = (room) => dispatch(deleteRoom(room._id)) const columns = ['Name', 'Tiles', 'Racks'] @@ -24,7 +22,7 @@ function RoomTable({ topologyId }) { return [ { title: ( - ), @@ -65,6 +63,7 @@ function RoomTable({ topologyId }) { RoomTable.propTypes = { topologyId: PropTypes.string, + onSelect: PropTypes.func, } export default RoomTable diff --git a/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js b/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js index 761e7f9a..213a4868 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/TopologyOverview.js @@ -38,7 +38,7 @@ import { useTopology } from '../../data/topology' import { parseAndFormatDateTime } from '../../util/date-time' import RoomTable from './RoomTable' -function TopologyOverview({ topologyId }) { +function TopologyOverview({ topologyId, onSelect }) { const { data: topology } = useTopology(topologyId) return ( @@ -71,7 +71,7 @@ function TopologyOverview({ topologyId }) { Rooms - + onSelect('room', room)} /> @@ -81,6 +81,7 @@ function TopologyOverview({ topologyId }) { TopologyOverview.propTypes = { topologyId: PropTypes.string, + onSelect: PropTypes.func, } export default TopologyOverview diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index c2753144..ae26ae83 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -24,7 +24,7 @@ import { useRouter } from 'next/router' import TopologyOverview from '../../../../components/topologies/TopologyOverview' import { useProject } from '../../../../data/project' import { useDispatch } from 'react-redux' -import React, { useEffect, useRef, useState } from 'react' +import React, { useEffect, useState } from 'react' import Head from 'next/head' import { AppPage } from '../../../../components/AppPage' import { @@ -42,6 +42,7 @@ import { } from '@patternfly/react-core' import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' import TopologyMap from '../../../../components/topologies/TopologyMap' +import { goToRoom } from '../../../../redux/actions/interaction-level' import { openTopology } from '../../../../redux/actions/topologies' /** @@ -61,8 +62,6 @@ function Topology() { }, [topologyId, dispatch]) const [activeTab, setActiveTab] = useState('overview') - const overviewRef = useRef(null) - const floorPlanRef = useRef(null) const breadcrumb = ( @@ -95,31 +94,31 @@ function Topology() { onSelect={(_, tabIndex) => setActiveTab(tabIndex)} className="pf-m-page-insets" > - Overview} - tabContentId="overview" - tabContentRef={overviewRef} - /> + Overview} tabContentId="overview" /> Floor Plan} tabContentId="floor-plan" - tabContentRef={floorPlanRef} /> - - + -- cgit v1.2.3 From 20d21aabe00970e420053cf33cdcf10e1da3a3e2 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 29 Jul 2021 17:38:17 +0200 Subject: build: Update Kotlin dependencies This change updates the Kotlin dependencies used by OpenDC to their latest version. --- buildSrc/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8971e5e4..6ada3535 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -31,10 +31,10 @@ repositories { } dependencies { - implementation(kotlin("gradle-plugin", version = "1.5.20")) + implementation(kotlin("gradle-plugin", version = "1.5.21")) implementation("org.jlleitschuh.gradle:ktlint-gradle:10.1.0") - implementation("org.jetbrains.kotlin:kotlin-allopen:1.5.20") + implementation("org.jetbrains.kotlin:kotlin-allopen:1.5.21") implementation("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.3.1") - implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.4.32") + implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.5.0") implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:7.0.0") } -- cgit v1.2.3 From c4812123572c62483ee0183917fe2ff988e2968d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Aug 2021 10:59:08 +0200 Subject: build(ui): Bump Next.js to 11.1.0 Bumps [next](https://github.com/vercel/next.js) from 11.0.1 to 11.1.0. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v11.0.1...v11.1.0) --- updated-dependencies: - dependency-name: next dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- opendc-web/opendc-web-ui/package.json | 2 +- opendc-web/opendc-web-ui/yarn.lock | 169 ++++++++++++++++++---------------- 2 files changed, 91 insertions(+), 80 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 5a32806c..3f8d31fa 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -34,7 +34,7 @@ "konva": "~7.2.5", "lint-staged": "~10.2.2", "mathjs": "~7.6.0", - "next": "^11.0.1", + "next": "^11.1.0", "next-transpile-modules": "^8.0.0", "normalizr": "^3.6.1", "prettier": "~2.0.5", diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 062766dd..0573e612 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -36,11 +36,21 @@ dependencies: "@babel/highlight" "^7.12.13" +"@babel/helper-plugin-utils@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + "@babel/helper-validator-identifier@^7.14.0": version "7.14.0" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz" integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== +"@babel/helper-validator-identifier@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" + integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== + "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": version "7.14.0" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz" @@ -50,6 +60,13 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/plugin-syntax-jsx@7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201" + integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/runtime@7.12.5": version "7.12.5" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz" @@ -57,27 +74,19 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.9.2": - version "7.14.0" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz" - integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.9.2": version "7.14.6" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz" integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== dependencies: regenerator-runtime "^0.13.4" -"@babel/types@7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz" - integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== +"@babel/types@7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" + integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== dependencies: - esutils "^2.0.2" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" "@eslint/eslintrc@^0.4.1": @@ -148,25 +157,30 @@ resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz" integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== -"@next/env@11.0.1": - version "11.0.1" - resolved "https://registry.npmjs.org/@next/env/-/env-11.0.1.tgz" - integrity sha512-yZfKh2U6R9tEYyNUrs2V3SBvCMufkJ07xMH5uWy8wqcl5gAXoEw6A/1LDqwX3j7pUutF9d1ZxpdGDA3Uag+aQQ== +"@napi-rs/triples@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c" + integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA== + +"@next/env@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.0.tgz#cae83d8e0a65aa9f2af3368f8269ffd9d911746a" + integrity sha512-zPJkMFRenSf7BLlVee8987G0qQXAhxy7k+Lb/5hLAGkPVHAHm+oFFeL+2ipbI2KTEFlazdmGY0M+AlLQn7pWaw== "@next/eslint-plugin-next@10.2.3": version "10.2.3" resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-10.2.3.tgz" integrity sha512-XkYm3cMxY2RZgbGyZLDN3vR9StFyiQVdwdS/EL6NxOerzt0To03/coY22p4jcFLtLYlQxAivJRicMTDNhRzPog== -"@next/polyfill-module@11.0.1": - version "11.0.1" - resolved "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-11.0.1.tgz" - integrity sha512-Cjs7rrKCg4CF4Jhri8PCKlBXhszTfOQNl9AjzdNy4K5jXFyxyoSzuX2rK4IuoyE+yGp5A3XJCBEmOQ4xbUp9Mg== +"@next/polyfill-module@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.0.tgz#ee6b9117a1f9bb137479dfa51d5a9e38e066a62f" + integrity sha512-64EgW8SzJRQls2yJ5DkuljRxgE24o2kYtX/ghTkPUJYsfidHMWzQGwg26IgRbb/uHqTd1G0W5UkKag+Nt8TWaQ== -"@next/react-dev-overlay@11.0.1": - version "11.0.1" - resolved "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-11.0.1.tgz" - integrity sha512-lvUjMVpLsgzADs9Q8wtC5LNqvfdN+M0BDMSrqr04EDWAyyX0vURHC9hkvLbyEYWyh+WW32pwjKBXdkMnJhoqMg== +"@next/react-dev-overlay@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.0.tgz#8d4e8020a4cbdacbca431a0bf40c4d28187083af" + integrity sha512-h+ry0sTk1W3mJw+TwEf91aqLbBJ5oqAsxfx+QryqEItNtfW6zLSSjxkyTYTqX8DkgSssQQutQfATkzBVgOR+qQ== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -180,10 +194,17 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@11.0.1": - version "11.0.1" - resolved "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-11.0.1.tgz" - integrity sha512-K347DM6Z7gBSE+TfUaTTceWvbj0B6iNAsFZXbFZOlfg3uyz2sbKpzPYYFocCc27yjLaS8OfR8DEdS2mZXi8Saw== +"@next/react-refresh-utils@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.0.tgz#60c3c7b127a5dab8b0a2889a7dcf8a90d2c4e592" + integrity sha512-g5DtFTpLTGa36iy9DuZawtJeitI11gysFGKPQQqy+mNbSFazguArcJ10gAYFlbqpIi4boUamWNI5mAoSPx3kog== + +"@node-rs/helper@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@node-rs/helper/-/helper-1.2.1.tgz#e079b05f21ff4329d82c4e1f71c0290e4ecdc70c" + integrity sha512-R5wEmm8nbuQU0YGGmYVjEc0OHtYsuXdpRG+Ut/3wZ9XAvQWyThN08bTh2cBJgoZxHQUPtvRfeQuxcAgLuiBISg== + dependencies: + "@napi-rs/triples" "^1.0.3" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -691,11 +712,6 @@ available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -babel-plugin-syntax-jsx@6.18.0: - version "6.18.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -889,12 +905,7 @@ callsites@^3.0.0: resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caniuse-lite@^1.0.30001202: - version "1.0.30001228" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz" - integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== - -caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: +caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: version "1.0.30001232" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz" integrity sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg== @@ -1162,19 +1173,19 @@ css.escape@1.5.1: resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= -cssnano-preset-simple@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/cssnano-preset-simple/-/cssnano-preset-simple-2.0.0.tgz" - integrity sha512-HkufSLkaBJbKBFx/7aj5HmCK9Ni/JedRQm0mT2qBzMG/dEuJOLnMt2lK6K1rwOOyV4j9aSY+knbW9WoS7BYpzg== +cssnano-preset-simple@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-3.0.0.tgz#e95d0012699ca2c741306e9a3b8eeb495a348dbe" + integrity sha512-vxQPeoMRqUT3c/9f0vWeVa2nKQIHFpogtoBvFdW4GQ3IvEJ6uauCP6p3Y5zQDLFcI7/+40FTgX12o7XUL0Ko+w== dependencies: caniuse-lite "^1.0.30001202" -cssnano-simple@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/cssnano-simple/-/cssnano-simple-2.0.0.tgz" - integrity sha512-0G3TXaFxlh/szPEG/o3VcmCwl0N3E60XNb9YZZijew5eIs6fLjJuOPxQd9yEBaX2p/YfJtt49i4vYi38iH6/6w== +cssnano-simple@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-3.0.0.tgz#a4b8ccdef4c7084af97e19bc5b93b4ecf211e90f" + integrity sha512-oU3ueli5Dtwgh0DyeohcIEE00QVfbPR3HzyXdAl89SfnQG3y0/qcpfLVW+jPIh3/rgMZGwuW96rejZGaYE9eUg== dependencies: - cssnano-preset-simple "^2.0.0" + cssnano-preset-simple "^3.0.0" csstype@^3.0.2: version "3.0.8" @@ -2523,7 +2534,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@>=4.17.21, lodash@^4.17.13, lodash@^4.17.19: +lodash@>=4.17.21, lodash@^4.17.19: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -2678,10 +2689,10 @@ nano-time@1.0.0: dependencies: big-integer "^1.6.16" -nanoid@^3.1.22: - version "3.1.22" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz" - integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== +nanoid@^3.1.23: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== native-url@0.3.4: version "0.3.4" @@ -2703,17 +2714,18 @@ next-transpile-modules@^8.0.0: enhanced-resolve "^5.7.0" escalade "^3.1.1" -next@^11.0.1: - version "11.0.1" - resolved "https://registry.npmjs.org/next/-/next-11.0.1.tgz" - integrity sha512-yR7be7asNbvpVNpi6xxEg28wZ7Gqmj1nOt0sABH9qORmF3+pms2KZ7Cng33oK5nqPIzEEFJD0pp2PCe3/ueMIg== +next@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/next/-/next-11.1.0.tgz#767d4c4fa0b9b0c768cdbd6c9f03dd86b5d701c0" + integrity sha512-GHBk/c7Wyr6YbFRFZF37I0X7HKzkHHI8pur/loyXo5AIE8wdkbGPGO0ds3vNAO6f8AxZAKGCRYtAzoGlVLoifA== dependencies: "@babel/runtime" "7.12.5" "@hapi/accept" "5.0.2" - "@next/env" "11.0.1" - "@next/polyfill-module" "11.0.1" - "@next/react-dev-overlay" "11.0.1" - "@next/react-refresh-utils" "11.0.1" + "@next/env" "11.1.0" + "@next/polyfill-module" "11.1.0" + "@next/react-dev-overlay" "11.1.0" + "@next/react-refresh-utils" "11.1.0" + "@node-rs/helper" "1.2.1" assert "2.0.0" ast-types "0.13.2" browserify-zlib "0.2.0" @@ -2724,7 +2736,7 @@ next@^11.0.1: chokidar "3.5.1" constants-browserify "1.0.0" crypto-browserify "3.12.0" - cssnano-simple "2.0.0" + cssnano-simple "3.0.0" domain-browser "4.19.0" encoding "0.1.13" etag "1.8.1" @@ -2741,9 +2753,8 @@ next@^11.0.1: p-limit "3.1.0" path-browserify "1.0.1" pnp-webpack-plugin "1.6.4" - postcss "8.2.13" + postcss "8.2.15" process "0.11.10" - prop-types "15.7.2" querystring-es3 "0.2.1" raw-body "2.4.1" react-is "17.0.2" @@ -2751,7 +2762,7 @@ next@^11.0.1: stream-browserify "3.0.0" stream-http "3.1.1" string_decoder "1.3.0" - styled-jsx "3.3.2" + styled-jsx "4.0.0" timers-browserify "2.0.12" tty-browserify "0.0.1" use-subscription "1.5.1" @@ -3150,13 +3161,13 @@ postcss-value-parser@^3.3.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss@8.2.13: - version "8.2.13" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.13.tgz" - integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ== +postcss@8.2.15: + version "8.2.15" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" + integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q== dependencies: colorette "^1.2.2" - nanoid "^3.1.22" + nanoid "^3.1.23" source-map "^0.6.1" prelude-ls@^1.2.1: @@ -3197,7 +3208,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@15.7.2, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: +prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: version "15.7.2" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -3968,13 +3979,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -styled-jsx@3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-3.3.2.tgz" - integrity sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g== +styled-jsx@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.0.tgz#f7b90e7889d0a4f4635f8d1ae9ac32f3acaedc57" + integrity sha512-2USeoWMoJ/Lx5s2y1PxuvLy/cz2Yrr8cTySV3ILHU1Vmaw1bnV7suKdblLPjnyhMD+qzN7B1SWyh4UZTARn/WA== dependencies: - "@babel/types" "7.8.3" - babel-plugin-syntax-jsx "6.18.0" + "@babel/plugin-syntax-jsx" "7.14.5" + "@babel/types" "7.15.0" convert-source-map "1.7.0" loader-utils "1.2.3" source-map "0.7.3" -- cgit v1.2.3 From ce2d730159ae24c7cebb22ec42d094fe5fdc888f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 13 Aug 2021 17:14:53 +0200 Subject: build: Update Kotlin dependencies This change updates the Kotlin dependencies used by OpenDC to their latest version. --- gradle/libs.versions.toml | 20 ++++++++++---------- .../opendc/compute/service/ComputeServiceTest.kt | 22 +++++++++++----------- .../experiments/capelin/ExperimentHelpers.kt | 2 +- .../capelin/monitor/ExperimentMetricExporter.kt | 9 ++++++--- .../experiments/serverless/ServerlessExperiment.kt | 2 +- .../resources/impl/SimResourceInterpreterImpl.kt | 2 +- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8553787d..a9b1bf53 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,19 @@ [versions] junit-jupiter = "5.7.2" junit-platform = "1.7.2" -slf4j = "1.7.30" +slf4j = "1.7.32" log4j = "2.14.1" -opentelemetry-main = "1.2.0" -opentelemetry-metrics = "1.2.0-alpha" +opentelemetry-main = "1.4.1" +opentelemetry-metrics = "1.4.1-alpha" hadoop = "3.3.0" -ktor = "1.6.1" -jackson = "2.12.3" +ktor = "1.6.2" +jackson = "2.12.4" [libraries] -kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.5.0" } +kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.5.1" } # Logging -kotlin-logging = { module = "io.github.microutils:kotlin-logging", version = "2.0.8" } +kotlin-logging = { module = "io.github.microutils:kotlin-logging", version = "2.0.10" } slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } log4j-slf4j = { module = "org.apache.logging.log4j:log4j-slf4j-impl", version.ref = "log4j" } sentry-log4j2 = { module = "io.sentry:sentry-log4j2", version = "4.3.0" } @@ -30,7 +30,7 @@ junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", vers junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-jupiter" } junit-platform-commons = { module = "org.junit.platform:junit-platform-commons", version.ref = "junit-platform" } junit-platform-engine = { module = "org.junit.platform:junit-platform-engine", version.ref = "junit-platform" } -mockk = { module = "io.mockk:mockk", version = "1.11.0" } +mockk = { module = "io.mockk:mockk", version = "1.12.0" } # CLI clikt = { module = "com.github.ajalt.clikt:clikt", version = "3.2.0" } @@ -40,14 +40,14 @@ progressbar = { module = "me.tongfei:progressbar", version = "0.9.0" } jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } parquet = { module = "org.apache.parquet:parquet-avro", version = "1.12.0" } -yaml = { module = "org.yaml:snakeyaml", version = "1.28" } +yaml = { module = "org.yaml:snakeyaml", version = "1.29" } config = { module = "com.typesafe:config", version = "1.4.1" } # Benchmark kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime-jvm", version = "0.3.1" } # Other -classgraph = { module = "io.github.classgraph:classgraph", version = "4.8.108" } +classgraph = { module = "io.github.classgraph:classgraph", version = "4.8.113" } hadoop-common = { module = "org.apache.hadoop:hadoop-common", version.ref = "hadoop" } hadoop-mapreduce-client-core = { module = "org.apache.hadoop:hadoop-mapreduce-client-core", version.ref = "hadoop" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt index a6258845..7817c473 100644 --- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt @@ -167,7 +167,7 @@ internal class ComputeServiceTest { val server = client.newServer("test", image, flavor, start = false) server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.ERROR, server.state) } @@ -180,7 +180,7 @@ internal class ComputeServiceTest { val server = client.newServer("test", image, flavor, start = false) server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.ERROR, server.state) } @@ -193,7 +193,7 @@ internal class ComputeServiceTest { val server = client.newServer("test", image, flavor, start = false) server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.ERROR, server.state) } @@ -207,7 +207,7 @@ internal class ComputeServiceTest { server.start() server.stop() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.TERMINATED, server.state) } @@ -228,7 +228,7 @@ internal class ComputeServiceTest { val server = client.newServer("test", image, flavor, start = false) server.start() - delay(10 * 60 * 1000) + delay(10L * 60 * 1000) server.refresh() assertEquals(ServerState.PROVISIONING, server.state) @@ -254,12 +254,12 @@ internal class ComputeServiceTest { val server = client.newServer("test", image, flavor, start = false) server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) every { host.state } returns HostState.UP listeners.forEach { it.onStateChanged(host, HostState.UP) } - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.PROVISIONING, server.state) @@ -284,13 +284,13 @@ internal class ComputeServiceTest { val image = client.newImage("test") val server = client.newServer("test", image, flavor, start = false) - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) every { host.state } returns HostState.DOWN listeners.forEach { it.onStateChanged(host, HostState.DOWN) } server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.PROVISIONING, server.state) @@ -344,7 +344,7 @@ internal class ComputeServiceTest { // Start server server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) coVerify { host.spawn(capture(slot), true) } listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.RUNNING) } @@ -383,7 +383,7 @@ internal class ComputeServiceTest { val server = client.newServer("test", image, flavor, start = false) server.start() - delay(5 * 60 * 1000) + delay(5L * 60 * 1000) server.refresh() assertEquals(ServerState.PROVISIONING, server.state) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 9548253d..42d240dc 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -186,7 +186,7 @@ suspend fun withMonitor( this, listOf(metricProducer), ExperimentMetricExporter(monitor, clock, scheduler.hosts.associateBy { it.uid.toString() }), - exportInterval = 5 * 60 * 1000 /* Every 5 min (which is the granularity of the workload trace) */ + exportInterval = 5L * 60 * 1000 /* Every 5 min (which is the granularity of the workload trace) */ ) try { diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index 54ab3b5b..f520a28c 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -22,6 +22,7 @@ package org.opendc.experiments.capelin.monitor +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.sdk.common.CompletableResultCode import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter @@ -36,6 +37,8 @@ public class ExperimentMetricExporter( private val clock: Clock, private val hosts: Map ) : MetricExporter { + private val hostKey = AttributeKey.stringKey("host") + override fun export(metrics: Collection): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } reportHostMetrics(metricsByName) @@ -99,7 +102,7 @@ public class ExperimentMetricExporter( private fun mapDoubleSummary(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { val points = data?.doubleSummaryData?.points ?: emptyList() for (point in points) { - val uid = point.labels["host"] + val uid = point.attributes[hostKey] val hostMetric = hostMetrics[uid] if (hostMetric != null) { @@ -113,7 +116,7 @@ public class ExperimentMetricExporter( private fun mapDoubleGauge(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { val points = data?.doubleGaugeData?.points ?: emptyList() for (point in points) { - val uid = point.labels["host"] + val uid = point.attributes[hostKey] val hostMetric = hostMetrics[uid] if (hostMetric != null) { @@ -125,7 +128,7 @@ public class ExperimentMetricExporter( private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Long) -> Unit) { val points = data?.longSumData?.points ?: emptyList() for (point in points) { - val uid = point.labels["host"] + val uid = point.attributes[hostKey] val hostMetric = hostMetrics[uid] if (hostMetric != null) { diff --git a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt index 231b491e..650416f5 100644 --- a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt +++ b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt @@ -85,7 +85,7 @@ public class ServerlessExperiment : Experiment("Serverless") { val delayInjector = StochasticDelayInjector(coldStartModel, Random()) val deployer = SimFunctionDeployer(clock, this, createMachineModel(), delayInjector) { FunctionTraceWorkload(traceById.getValue(it.name)) } val service = - FaaSService(coroutineContext, clock, meterProvider.get("opendc-serverless"), deployer, routingPolicy, FunctionTerminationPolicyFixed(coroutineContext, clock, timeout = 10 * 60 * 1000)) + FaaSService(coroutineContext, clock, meterProvider.get("opendc-serverless"), deployer, routingPolicy, FunctionTerminationPolicyFixed(coroutineContext, clock, timeout = 10L * 60 * 1000)) val client = service.newClient() coroutineScope { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt index 6dd02ae5..c3dcebd0 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt @@ -318,7 +318,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, */ private data class Invocation( @JvmField val timestamp: Long, - @JvmField private val disposableHandle: DisposableHandle + private val disposableHandle: DisposableHandle ) { /** * Cancel the interpreter invocation. -- cgit v1.2.3 From f84dc9f8b8b4eaa7621f9ee4fc83ef38a85c431b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 17 Aug 2021 11:30:29 +0200 Subject: feat(ui): Add context selectors This change adds context selectors for the OpenDC frontend where the user can select different projects, portfolios or topologies from the context selection bar. --- opendc-web/opendc-web-ui/src/components/AppPage.js | 12 ++-- .../components/context/ContextSelectionSection.js | 34 ++++++++++ .../context/ContextSelectionSection.module.scss | 28 ++++++++ .../src/components/context/ContextSelector.js | 75 ++++++++++++++++++++++ .../components/context/ContextSelector.module.scss | 45 +++++++++++++ .../src/components/context/PortfolioSelector.js | 47 ++++++++++++++ .../src/components/context/ProjectSelector.js | 48 ++++++++++++++ .../src/components/context/TopologySelector.js | 52 +++++++++++++++ .../src/pages/projects/[project]/index.js | 10 ++- .../projects/[project]/portfolios/[portfolio].js | 12 +++- .../projects/[project]/topologies/[topology].js | 12 +++- 11 files changed, 368 insertions(+), 7 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.js create mode 100644 opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/context/ContextSelector.js create mode 100644 opendc-web/opendc-web-ui/src/components/context/ContextSelector.module.scss create mode 100644 opendc-web/opendc-web-ui/src/components/context/PortfolioSelector.js create mode 100644 opendc-web/opendc-web-ui/src/components/context/ProjectSelector.js create mode 100644 opendc-web/opendc-web-ui/src/components/context/TopologySelector.js diff --git a/opendc-web/opendc-web-ui/src/components/AppPage.js b/opendc-web/opendc-web-ui/src/components/AppPage.js index 2e0ea4cc..25afaf9a 100644 --- a/opendc-web/opendc-web-ui/src/components/AppPage.js +++ b/opendc-web/opendc-web-ui/src/components/AppPage.js @@ -23,11 +23,15 @@ import PropTypes from 'prop-types' import { AppHeader } from './AppHeader' import React from 'react' -import { Page } from '@patternfly/react-core' +import { Page, PageGroup, PageBreadcrumb } from '@patternfly/react-core' -export function AppPage({ children, breadcrumb, tertiaryNav }) { +export function AppPage({ children, breadcrumb, contextSelectors }) { return ( - }> + }> + + {contextSelectors} + {breadcrumb && {breadcrumb}} + {children} ) @@ -35,6 +39,6 @@ export function AppPage({ children, breadcrumb, tertiaryNav }) { AppPage.propTypes = { breadcrumb: PropTypes.node, - tertiaryNav: PropTypes.node, + contextSelectors: PropTypes.node, children: PropTypes.node, } diff --git a/opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.js b/opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.js new file mode 100644 index 00000000..5d3a6441 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { contextSelectionSection } from './ContextSelectionSection.module.scss' + +function ContextSelectionSection({ children }) { + return
    {children}
    +} + +ContextSelectionSection.propTypes = { + children: PropTypes.node, +} + +export default ContextSelectionSection diff --git a/opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.module.scss b/opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.module.scss new file mode 100644 index 00000000..0e902af0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/ContextSelectionSection.module.scss @@ -0,0 +1,28 @@ +/*! + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.contextSelectionSection { + padding-left: var(--pf-c-page__main-breadcrumb--PaddingLeft); + flex-shrink: 0; + border-bottom: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--100); + background-color: var(--pf-c-page__main-breadcrumb--BackgroundColor); +} diff --git a/opendc-web/opendc-web-ui/src/components/context/ContextSelector.js b/opendc-web/opendc-web-ui/src/components/context/ContextSelector.js new file mode 100644 index 00000000..3712cfa0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/ContextSelector.js @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { ContextSelector as PFContextSelector, ContextSelectorItem } from '@patternfly/react-core' +import { useMemo, useState, useReducer } from 'react' +import { contextSelector } from './ContextSelector.module.scss' + +function ContextSelector({ activeItem, items, onSelect, label }) { + const [isOpen, toggle] = useReducer((isOpen) => !isOpen, false) + const [searchValue, setSearchValue] = useState('') + + const filteredItems = useMemo( + () => items.filter(({ name }) => name.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1) || items, + [items, searchValue] + ) + + return ( + setSearchValue(value)} + searchInputValue={searchValue} + isOpen={isOpen} + onToggle={toggle} + onSelect={(event) => { + const targetId = event.target.value + const target = items.find((item) => item._id === targetId) + + toggle() + onSelect(target) + }} + > + {filteredItems.map((item) => ( + + {item.name} + + ))} + + ) +} + +const Item = PropTypes.shape({ + _id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, +}) + +ContextSelector.propTypes = { + activeItem: Item, + items: PropTypes.arrayOf(Item).isRequired, + onSelect: PropTypes.func.isRequired, + label: PropTypes.string, +} + +export default ContextSelector diff --git a/opendc-web/opendc-web-ui/src/components/context/ContextSelector.module.scss b/opendc-web/opendc-web-ui/src/components/context/ContextSelector.module.scss new file mode 100644 index 00000000..fefba41f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/ContextSelector.module.scss @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +.contextSelector { + width: auto; + margin-right: 20px; + + --pf-c-context-selector__toggle--PaddingTop: var(--pf-global--spacer--sm); + --pf-c-context-selector__toggle--PaddingRight: 0; + --pf-c-context-selector__toggle--PaddingBottom: var(--pf-global--spacer--sm); + --pf-c-context-selector__toggle--PaddingLeft: 0; + --pf-c-context-selector__toggle--BorderWidth: 0; + --pf-c-context-selector__toggle-text--FontSize: var(--pf-global--FontSize--sm); + + & :global(.pf-c-context-selector__toggle) { + &:active, + &:focus-within, + &:global(.pf-m-active) { + --pf-c-context-selector__toggle--after--BorderBottomWidth: 0; + } + } + + &:global(.pf-m-expanded) > :global(.pf-c-context-selector__toggle) { + --pf-c-context-selector__toggle--after--BorderBottomWidth: 0; + } +} diff --git a/opendc-web/opendc-web-ui/src/components/context/PortfolioSelector.js b/opendc-web/opendc-web-ui/src/components/context/PortfolioSelector.js new file mode 100644 index 00000000..694681ac --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/PortfolioSelector.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useRouter } from 'next/router' +import { useMemo } from 'react' +import { useProjectPortfolios } from '../../data/project' +import ContextSelector from './ContextSelector' + +function PortfolioSelector() { + const router = useRouter() + const { project, portfolio: activePortfolioId } = router.query + const { data: portfolios = [] } = useProjectPortfolios(project) + const activePortfolio = useMemo(() => portfolios.find((portfolio) => portfolio._id === activePortfolioId), [ + activePortfolioId, + portfolios, + ]) + + return ( + router.push(`/projects/${portfolio.projectId}/portfolios/${portfolio._id}`)} + /> + ) +} + +export default PortfolioSelector diff --git a/opendc-web/opendc-web-ui/src/components/context/ProjectSelector.js b/opendc-web/opendc-web-ui/src/components/context/ProjectSelector.js new file mode 100644 index 00000000..753632ab --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/ProjectSelector.js @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { useRouter } from 'next/router' +import { useMemo } from 'react' +import { useProjects } from '../../data/project' +import ContextSelector from './ContextSelector' + +function ProjectSelector({ projectId }) { + const router = useRouter() + const { data: projects = [] } = useProjects() + const activeProject = useMemo(() => projects.find((project) => project._id === projectId), [projectId, projects]) + + return ( + router.push(`/projects/${project._id}`)} + /> + ) +} + +ProjectSelector.propTypes = { + projectId: PropTypes.string, +} + +export default ProjectSelector diff --git a/opendc-web/opendc-web-ui/src/components/context/TopologySelector.js b/opendc-web/opendc-web-ui/src/components/context/TopologySelector.js new file mode 100644 index 00000000..d5e51c6c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/context/TopologySelector.js @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import PropTypes from 'prop-types' +import { useRouter } from 'next/router' +import { useMemo } from 'react' +import { useProjectTopologies } from '../../data/topology' +import ContextSelector from './ContextSelector' + +function TopologySelector({ projectId, topologyId }) { + const router = useRouter() + const { data: topologies = [] } = useProjectTopologies(projectId) + const activeTopology = useMemo(() => topologies.find((topology) => topology._id === topologyId), [ + topologyId, + topologies, + ]) + + return ( + router.push(`/projects/${topology.projectId}/topologies/${topology._id}`)} + /> + ) +} + +TopologySelector.propTypes = { + projectId: PropTypes.string, + topologyId: PropTypes.string, +} + +export default TopologySelector diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js index 5c17303f..c07a2c31 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/index.js @@ -21,7 +21,9 @@ */ import { useRouter } from 'next/router' +import ContextSelectionSection from '../../../components/context/ContextSelectionSection' import ProjectOverview from '../../../components/projects/ProjectOverview' +import ProjectSelector from '../../../components/context/ProjectSelector' import { useProject } from '../../../data/project' import { AppPage } from '../../../components/AppPage' import Head from 'next/head' @@ -53,8 +55,14 @@ function Project() {
    ) + const contextSelectors = ( + + + + ) + return ( - + {project?.name ?? 'Project'} - OpenDC diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js index 28b03c37..d1533d98 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js @@ -37,6 +37,9 @@ import { TextContent, } from '@patternfly/react-core' import { AppPage } from '../../../../components/AppPage' +import ContextSelectionSection from '../../../../components/context/ContextSelectionSection' +import PortfolioSelector from '../../../../components/context/PortfolioSelector' +import ProjectSelector from '../../../../components/context/ProjectSelector' import BreadcrumbLink from '../../../../components/util/BreadcrumbLink' import PortfolioOverview from '../../../../components/portfolios/PortfolioOverview' import PortfolioResults from '../../../../components/portfolios/PortfolioResults' @@ -65,8 +68,15 @@ function Portfolio() { ) + const contextSelectors = ( + + + + + ) + return ( - + Portfolio - OpenDC diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js index ae26ae83..858f9b16 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js @@ -21,6 +21,9 @@ */ import { useRouter } from 'next/router' +import ContextSelectionSection from '../../../../components/context/ContextSelectionSection' +import ProjectSelector from '../../../../components/context/ProjectSelector' +import TopologySelector from '../../../../components/context/TopologySelector' import TopologyOverview from '../../../../components/topologies/TopologyOverview' import { useProject } from '../../../../data/project' import { useDispatch } from 'react-redux' @@ -77,8 +80,15 @@ function Topology() { ) + const contextSelectors = ( + + + + + ) + return ( - + {project?.name ?? 'Topologies'} - OpenDC -- cgit v1.2.3 From 766b41566f4cf8297202147d789e135a76041ed4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 22 Aug 2021 13:21:53 +0200 Subject: perf(simulator): Prevent counter update without work This change implements a performance improvement by preventing updates on the resource counters in case no work was performed in the last cycle. --- .../org/opendc/simulator/resources/SimAbstractResourceProvider.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt index c1b1450e..2ceb1e3c 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt @@ -88,6 +88,10 @@ public abstract class SimAbstractResourceProvider( * Update the counters of the resource provider. */ protected fun updateCounters(ctx: SimResourceContext, work: Double) { + if (work <= 0.0) { + return + } + val counters = _counters val remainingWork = ctx.remainingWork counters.demand += work -- cgit v1.2.3 From c1988fa1b08011f716194f48da10386a236ffd7f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 22 Aug 2021 13:23:17 +0200 Subject: fix(compute): Track failed servers with counters correctly --- .../kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index 8af5f86e..e7807177 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -477,6 +477,8 @@ internal class ComputeServiceImpl( if (newState == ServerState.RUNNING) { _runningServers.add(1) + } else if (newState == ServerState.ERROR) { + _runningServers.add(-1) } else if (newState == ServerState.TERMINATED || newState == ServerState.DELETED) { logger.info { "[${clock.millis()}] Server ${server.uid} ${server.name} ${server.flavor} finished." } -- cgit v1.2.3 From b8f64c1d3df2c990df8941cd036222fab2def9fa Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 22 Aug 2021 13:23:53 +0200 Subject: refactor(compute): Update FilterScheduler to follow OpenStack's Nova This change updates the FilterScheduler implementation to follow more closely the scheduler implementation in OpenStack's Nova. We now normalize the weights, support many of the filters and weights in OpenStack and support overcommitting resources. --- .../compute/service/scheduler/FilterScheduler.kt | 64 +++- .../scheduler/filters/ComputeCapabilitiesFilter.kt | 40 -- .../compute/service/scheduler/filters/RamFilter.kt | 50 +++ .../service/scheduler/filters/VCpuFilter.kt | 47 +++ .../service/scheduler/weights/CoreMemoryWeigher.kt | 37 -- .../service/scheduler/weights/CoreRamWeigher.kt | 41 +++ .../service/scheduler/weights/HostWeigher.kt | 40 +- .../scheduler/weights/InstanceCountWeigher.kt | 2 +- .../service/scheduler/weights/MemoryWeigher.kt | 37 -- .../scheduler/weights/ProvisionedCoresWeigher.kt | 37 -- .../service/scheduler/weights/RamWeigher.kt | 40 ++ .../service/scheduler/weights/RandomWeigher.kt | 36 -- .../service/scheduler/weights/VCpuWeigher.kt | 44 +++ .../opendc/compute/service/ComputeServiceTest.kt | 9 +- .../service/scheduler/FilterSchedulerTest.kt | 407 +++++++++++++++++++++ .../experiments/capelin/ExperimentHelpers.kt | 59 +++ .../org/opendc/experiments/capelin/Portfolio.kt | 53 +-- .../experiments/capelin/CapelinIntegrationTest.kt | 19 +- .../experiments/energy21/EnergyExperiment.kt | 9 +- .../resources/SimAbstractResourceProvider.kt | 2 +- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 44 +-- .../service/WorkflowServiceIntegrationTest.kt | 11 +- 22 files changed, 811 insertions(+), 317 deletions(-) delete mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt create mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt create mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt delete mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt create mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt delete mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt delete mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt create mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt delete mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt create mode 100644 opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt create mode 100644 opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt index 1fe90454..8c2d4715 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt @@ -26,6 +26,8 @@ import org.opendc.compute.api.Server import org.opendc.compute.service.internal.HostView import org.opendc.compute.service.scheduler.filters.HostFilter import org.opendc.compute.service.scheduler.weights.HostWeigher +import java.util.* +import kotlin.math.min /** * A [ComputeScheduler] implementation that uses filtering and weighing passes to select @@ -33,13 +35,27 @@ import org.opendc.compute.service.scheduler.weights.HostWeigher * * This implementation is based on the filter scheduler from OpenStack Nova. * See: https://docs.openstack.org/nova/latest/user/filter-scheduler.html + * + * @param filters The list of filters to apply when searching for an appropriate host. + * @param weighers The list of weighers to apply when searching for an appropriate host. + * @param subsetSize The size of the subset of best hosts from which a target is randomly chosen. + * @param random A [Random] instance for selecting */ -public class FilterScheduler(private val filters: List, private val weighers: List>) : ComputeScheduler { +public class FilterScheduler( + private val filters: List, + private val weighers: List, + private val subsetSize: Int = 1, + private val random: Random = Random(0) +) : ComputeScheduler { /** * The pool of hosts available to the scheduler. */ private val hosts = mutableListOf() + init { + require(subsetSize >= 1) { "Subset size must be one or greater" } + } + override fun addHost(host: HostView) { hosts.add(host) } @@ -49,18 +65,44 @@ public class FilterScheduler(private val filters: List, private val } override fun select(server: Server): HostView? { - return hosts.asSequence() - .filter { host -> - for (filter in filters) { - if (!filter.test(host, server)) - return@filter false + val hosts = hosts + val filteredHosts = hosts.filter { host -> filters.all { filter -> filter.test(host, server) } } + + val subset = if (weighers.isNotEmpty()) { + val results = weighers.map { it.getWeights(filteredHosts, server) } + val weights = DoubleArray(filteredHosts.size) + + for (result in results) { + val min = result.min + val range = (result.max - min) + + // Skip result if all weights are the same + if (range == 0.0) { + continue } - true - } - .sortedByDescending { host -> - weighers.sumOf { (weigher, factor) -> weigher.getWeight(host, server) * factor } + val multiplier = result.multiplier + val factor = multiplier / range + + for ((i, weight) in result.weights.withIndex()) { + weights[i] += factor * (weight - min) + } } - .firstOrNull() + + weights.indices + .asSequence() + .sortedByDescending { weights[it] } + .map { filteredHosts[it] } + .take(subsetSize) + .toList() + } else { + filteredHosts + } + + return when (val maxSize = min(subsetSize, subset.size)) { + 0 -> null + 1 -> subset[0] + else -> subset[random.nextInt(maxSize)] + } } } diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt deleted file mode 100644 index 072440c5..00000000 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.service.scheduler.filters - -import org.opendc.compute.api.Server -import org.opendc.compute.service.internal.HostView - -/** - * A [HostFilter] that checks whether the capabilities provided by the host satisfies the requirements of the server - * flavor. - */ -public class ComputeCapabilitiesFilter : HostFilter { - override fun test(host: HostView, server: Server): Boolean { - val fitsMemory = host.availableMemory >= server.flavor.memorySize - val fitsCpu = host.host.model.cpuCount >= server.flavor.cpuCount - return fitsMemory && fitsCpu - } - - override fun toString(): String = "ComputeCapabilitiesFilter" -} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt new file mode 100644 index 00000000..a470a453 --- /dev/null +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.service.scheduler.filters + +import org.opendc.compute.api.Server +import org.opendc.compute.service.internal.HostView + +/** + * A [HostFilter] that filters hosts based on the memory requirements of a [Server] and the RAM available on the host. + * + * @param allocationRatio Virtual RAM to physical RAM allocation ratio. + */ +public class RamFilter(private val allocationRatio: Double) : HostFilter { + override fun test(host: HostView, server: Server): Boolean { + val requested = server.flavor.memorySize + val available = host.availableMemory + val total = host.host.model.memorySize + + // Do not allow an instance to overcommit against itself, only against + // other instances. + if (requested > total) { + return false + } + + val limit = total * allocationRatio + val used = total - available + val usable = limit - used + return usable >= requested + } +} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt new file mode 100644 index 00000000..abdd79f1 --- /dev/null +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.service.scheduler.filters + +import org.opendc.compute.api.Server +import org.opendc.compute.service.internal.HostView + +/** + * A [HostFilter] that filters hosts based on the vCPU requirements of a [Server] and the available vCPUs on the host. + * + * @param allocationRatio Virtual CPU to physical CPU allocation ratio. + */ +public class VCpuFilter(private val allocationRatio: Double) : HostFilter { + override fun test(host: HostView, server: Server): Boolean { + val requested = server.flavor.cpuCount + val total = host.host.model.cpuCount + val limit = total * allocationRatio + + // Do not allow an instance to overcommit against itself, only against other instances + if (requested > total) { + return false + } + + val free = limit - host.provisionedCores + return free >= requested + } +} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt deleted file mode 100644 index 12e6510e..00000000 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.service.scheduler.weights - -import org.opendc.compute.api.Server -import org.opendc.compute.service.internal.HostView - -/** - * A [HostWeigher] that weighs the hosts based on the available memory per core on the host. - */ -public class CoreMemoryWeigher : HostWeigher { - override fun getWeight(host: HostView, server: Server): Double { - return host.availableMemory.toDouble() / host.host.model.cpuCount - } - - override fun toString(): String = "CoreMemoryWeigher" -} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt new file mode 100644 index 00000000..d668fdaf --- /dev/null +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.service.scheduler.weights + +import org.opendc.compute.api.Server +import org.opendc.compute.service.internal.HostView + +/** + * A [HostWeigher] that weighs the hosts based on the available memory per core on the host. + * + * @param multiplier Weight multiplier ratio. A positive value will result in the scheduler preferring hosts with more + * available core memory, and a negative number will result in the scheduler preferring hosts with less available core + * memory. + */ +public class CoreRamWeigher(override val multiplier: Double = 1.0) : HostWeigher { + override fun getWeight(host: HostView, server: Server): Double { + return host.availableMemory.toDouble() / host.host.model.cpuCount + } + + override fun toString(): String = "CoreRamWeigher" +} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt index d48ee9e0..aca8c4e6 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt @@ -29,9 +29,47 @@ import org.opendc.compute.service.scheduler.FilterScheduler /** * An interface used by the [FilterScheduler] to weigh the pool of host for a scheduling request. */ -public fun interface HostWeigher { +public interface HostWeigher { + /** + * The multiplier for the weigher. + */ + public val multiplier: Double + /** * Obtain the weight of the specified [host] when scheduling the specified [server]. */ public fun getWeight(host: HostView, server: Server): Double + + /** + * Obtain the weights for [hosts] when scheduling the specified [server]. + */ + public fun getWeights(hosts: List, server: Server): Result { + val weights = DoubleArray(hosts.size) + var min = Double.MAX_VALUE + var max = Double.MIN_VALUE + + for ((i, host) in hosts.withIndex()) { + val weight = getWeight(host, server) + weights[i] = weight + min = kotlin.math.min(min, weight) + max = kotlin.math.max(max, weight) + } + + return Result(weights, min, max, multiplier) + } + + /** + * A result returned by the weigher. + * + * @param weights The weights returned by the weigher. + * @param min The minimum weight returned. + * @param max The maximum weight returned. + * @param multiplier The weight multiplier to use. + */ + public class Result( + public val weights: DoubleArray, + public val min: Double, + public val max: Double, + public val multiplier: Double, + ) } diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt index 2ef733e5..732cbe03 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt @@ -28,7 +28,7 @@ import org.opendc.compute.service.internal.HostView /** * A [HostWeigher] that weighs the hosts based on the number of instances on the host. */ -public class InstanceCountWeigher : HostWeigher { +public class InstanceCountWeigher(override val multiplier: Double = 1.0) : HostWeigher { override fun getWeight(host: HostView, server: Server): Double { return host.instanceCount.toDouble() } diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt deleted file mode 100644 index 115d8e4d..00000000 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.service.scheduler.weights - -import org.opendc.compute.api.Server -import org.opendc.compute.service.internal.HostView - -/** - * A [HostWeigher] that weighs the hosts based on the available memory on the host. - */ -public class MemoryWeigher : HostWeigher { - override fun getWeight(host: HostView, server: Server): Double { - return host.availableMemory.toDouble() - } - - override fun toString(): String = "MemoryWeigher" -} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt deleted file mode 100644 index df5bcd6e..00000000 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.service.scheduler.weights - -import org.opendc.compute.api.Server -import org.opendc.compute.service.internal.HostView - -/** - * A [HostWeigher] that weighs the hosts based on the number of provisioned cores on the host. - */ -public class ProvisionedCoresWeigher : HostWeigher { - override fun getWeight(host: HostView, server: Server): Double { - return host.provisionedCores.toDouble() - } - - override fun toString(): String = "ProvisionedCoresWeigher" -} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt new file mode 100644 index 00000000..d18d31f4 --- /dev/null +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.service.scheduler.weights + +import org.opendc.compute.api.Server +import org.opendc.compute.service.internal.HostView + +/** + * A [HostWeigher] that weighs the hosts based on the available RAM (memory) on the host. + * + * @param multiplier Weight multiplier ratio. A positive value will result in the scheduler preferring hosts with more + * available memory, and a negative number will result in the scheduler preferring hosts with less memory. + */ +public class RamWeigher(override val multiplier: Double = 1.0) : HostWeigher { + override fun getWeight(host: HostView, server: Server): Double { + return host.availableMemory.toDouble() + } + + override fun toString(): String = "RamWeigher" +} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt deleted file mode 100644 index 1615df3a..00000000 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.service.scheduler.weights - -import org.opendc.compute.api.Server -import org.opendc.compute.service.internal.HostView -import java.util.* - -/** - * A [HostWeigher] that assigns random weights to each host every selection. - */ -public class RandomWeigher(private val random: Random) : HostWeigher { - override fun getWeight(host: HostView, server: Server): Double = random.nextDouble() - - override fun toString(): String = "RandomWeigher" -} diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt new file mode 100644 index 00000000..4a22269b --- /dev/null +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.service.scheduler.weights + +import org.opendc.compute.api.Server +import org.opendc.compute.service.internal.HostView + +/** + * A [HostWeigher] that weighs the hosts based on the remaining number of vCPUs available. + * + * @param allocationRatio Virtual CPU to physical CPU allocation ratio. + */ +public class VCpuWeigher(private val allocationRatio: Double, override val multiplier: Double = 1.0) : HostWeigher { + + init { + require(allocationRatio > 0.0) { "Allocation ratio must be greater than zero" } + } + + override fun getWeight(host: HostView, server: Server): Double { + return host.host.model.cpuCount * allocationRatio - host.provisionedCores + } + + override fun toString(): String = "VCpuWeigher" +} diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt index 7817c473..c6c01ea2 100644 --- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt @@ -37,9 +37,10 @@ import org.opendc.compute.service.driver.HostListener import org.opendc.compute.service.driver.HostModel import org.opendc.compute.service.driver.HostState import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.weights.MemoryWeigher +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.RamWeigher import org.opendc.simulator.core.SimulationCoroutineScope import org.opendc.simulator.core.runBlockingSimulation import java.util.* @@ -57,8 +58,8 @@ internal class ComputeServiceTest { scope = SimulationCoroutineScope() val clock = scope.clock val computeScheduler = FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(MemoryWeigher() to -1.0) + filters = listOf(ComputeFilter(), VCpuFilter(allocationRatio = 1.0), RamFilter(allocationRatio = 1.0)), + weighers = listOf(RamWeigher()) ) val meter = MeterProvider.noop().get("opendc-compute") service = ComputeService(scope.coroutineContext, clock, meter, computeScheduler) diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt new file mode 100644 index 00000000..cafd4498 --- /dev/null +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.service.scheduler + +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.junit.jupiter.api.assertThrows +import org.opendc.compute.api.Server +import org.opendc.compute.service.driver.HostModel +import org.opendc.compute.service.driver.HostState +import org.opendc.compute.service.internal.HostView +import org.opendc.compute.service.scheduler.filters.ComputeFilter +import org.opendc.compute.service.scheduler.filters.InstanceCountFilter +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher +import org.opendc.compute.service.scheduler.weights.RamWeigher +import org.opendc.compute.service.scheduler.weights.VCpuWeigher +import java.util.* + +/** + * Test suite for the [FilterScheduler]. + */ +internal class FilterSchedulerTest { + @Test + fun testInvalidSubsetSize() { + assertThrows { + FilterScheduler( + filters = emptyList(), + weighers = emptyList(), + subsetSize = 0 + ) + } + + assertThrows { + FilterScheduler( + filters = emptyList(), + weighers = emptyList(), + subsetSize = -2 + ) + } + } + + @Test + fun testNoHosts() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = emptyList(), + ) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertNull(scheduler.select(server)) + } + + @Test + fun testNoFiltersAndSchedulers() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = emptyList(), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.DOWN + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + // Make sure we get the first host both times + assertAll( + { assertEquals(hostA, scheduler.select(server)) }, + { assertEquals(hostA, scheduler.select(server)) } + ) + } + + @Test + fun testNoFiltersAndSchedulersRandom() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = emptyList(), + subsetSize = Int.MAX_VALUE, + random = Random(1) + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.DOWN + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + // Make sure we get the first host both times + assertAll( + { assertEquals(hostB, scheduler.select(server)) }, + { assertEquals(hostA, scheduler.select(server)) } + ) + } + + @Test + fun testHostIsDown() { + val scheduler = FilterScheduler( + filters = listOf(ComputeFilter()), + weighers = emptyList(), + ) + + val host = mockk() + every { host.host.state } returns HostState.DOWN + + scheduler.addHost(host) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertNull(scheduler.select(server)) + } + + @Test + fun testHostIsUp() { + val scheduler = FilterScheduler( + filters = listOf(ComputeFilter()), + weighers = emptyList(), + ) + + val host = mockk() + every { host.host.state } returns HostState.UP + + scheduler.addHost(host) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(host, scheduler.select(server)) + } + + @Test + fun testRamFilter() { + val scheduler = FilterScheduler( + filters = listOf(RamFilter(1.0)), + weighers = emptyList(), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(4, 2048) + every { hostA.availableMemory } returns 512 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.availableMemory } returns 2048 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostB, scheduler.select(server)) + } + + @Test + fun testRamFilterOvercommit() { + val scheduler = FilterScheduler( + filters = listOf(RamFilter(1.5)), + weighers = emptyList(), + ) + + val host = mockk() + every { host.host.state } returns HostState.UP + every { host.host.model } returns HostModel(4, 2048) + every { host.availableMemory } returns 2048 + + scheduler.addHost(host) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 2300 + + assertNull(scheduler.select(server)) + } + + @Test + fun testVCpuFilter() { + val scheduler = FilterScheduler( + filters = listOf(VCpuFilter(1.0)), + weighers = emptyList(), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(4, 2048) + every { hostA.provisionedCores } returns 3 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.provisionedCores } returns 0 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostB, scheduler.select(server)) + } + + @Test + fun testVCpuFilterOvercommit() { + val scheduler = FilterScheduler( + filters = listOf(VCpuFilter(16.0)), + weighers = emptyList(), + ) + + val host = mockk() + every { host.host.state } returns HostState.UP + every { host.host.model } returns HostModel(4, 2048) + every { host.provisionedCores } returns 0 + + scheduler.addHost(host) + + val server = mockk() + every { server.flavor.cpuCount } returns 8 + every { server.flavor.memorySize } returns 1024 + + assertNull(scheduler.select(server)) + } + + @Test + fun testInstanceCountFilter() { + val scheduler = FilterScheduler( + filters = listOf(InstanceCountFilter(limit = 2)), + weighers = emptyList(), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(4, 2048) + every { hostA.instanceCount } returns 2 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.instanceCount } returns 0 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostB, scheduler.select(server)) + } + + @Test + fun testRamWeigher() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = listOf(RamWeigher(1.5)), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(4, 2048) + every { hostA.availableMemory } returns 1024 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.availableMemory } returns 512 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostA, scheduler.select(server)) + } + + @Test + fun testCoreRamWeigher() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = listOf(CoreRamWeigher(1.5)), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(12, 2048) + every { hostA.availableMemory } returns 1024 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.availableMemory } returns 512 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostB, scheduler.select(server)) + } + + @Test + fun testVCpuWeigher() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = listOf(VCpuWeigher(16.0)), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(4, 2048) + every { hostA.provisionedCores } returns 2 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.provisionedCores } returns 0 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostB, scheduler.select(server)) + } + + @Test + fun testInstanceCountWeigher() { + val scheduler = FilterScheduler( + filters = emptyList(), + weighers = listOf(InstanceCountWeigher(multiplier = -1.0)), + ) + + val hostA = mockk() + every { hostA.host.state } returns HostState.UP + every { hostA.host.model } returns HostModel(4, 2048) + every { hostA.instanceCount } returns 2 + + val hostB = mockk() + every { hostB.host.state } returns HostState.UP + every { hostB.host.model } returns HostModel(4, 2048) + every { hostB.instanceCount } returns 0 + + scheduler.addHost(hostA) + scheduler.addHost(hostB) + + val server = mockk() + every { server.flavor.cpuCount } returns 2 + every { server.flavor.memorySize } returns 1024 + + assertEquals(hostB, scheduler.select(server)) + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 42d240dc..2c443678 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -38,6 +38,15 @@ import org.opendc.compute.service.driver.Host import org.opendc.compute.service.driver.HostListener import org.opendc.compute.service.driver.HostState import org.opendc.compute.service.scheduler.ComputeScheduler +import org.opendc.compute.service.scheduler.FilterScheduler +import org.opendc.compute.service.scheduler.ReplayScheduler +import org.opendc.compute.service.scheduler.filters.ComputeFilter +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher +import org.opendc.compute.service.scheduler.weights.RamWeigher +import org.opendc.compute.service.scheduler.weights.VCpuWeigher import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.monitor.ExperimentMetricExporter import org.opendc.experiments.capelin.monitor.ExperimentMonitor @@ -301,3 +310,53 @@ fun createMeterProvider(clock: Clock): MeterProvider { .registerView(powerSelector, powerView) .build() } + +/** + * Create a [ComputeScheduler] for the experiment. + */ +fun createComputeScheduler(allocationPolicy: String, seeder: Random, vmPlacements: Map = emptyMap()): ComputeScheduler { + val cpuAllocationRatio = 16.0 + val ramAllocationRatio = 1.5 + return when (allocationPolicy) { + "mem" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(RamWeigher(multiplier = 1.0)) + ) + "mem-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(RamWeigher(multiplier = -1.0)) + ) + "core-mem" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) + "core-mem-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(CoreRamWeigher(multiplier = -1.0)) + ) + "active-servers" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(InstanceCountWeigher(multiplier = -1.0)) + ) + "active-servers-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(InstanceCountWeigher(multiplier = 1.0)) + ) + "provisioned-cores" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)) + ) + "provisioned-cores-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)) + ) + "random" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = emptyList(), + subsetSize = Int.MAX_VALUE, + random = java.util.Random(seeder.nextLong()) + ) + "replay" -> ReplayScheduler(vmPlacements) + else -> throw IllegalArgumentException("Unknown policy $allocationPolicy") + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index cbb5bfd9..ee832af8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -28,10 +28,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.Channel import mu.KotlinLogging -import org.opendc.compute.service.scheduler.* -import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter -import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.weights.* import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.OperationalPhenomena @@ -49,6 +45,7 @@ import java.io.File import java.io.FileInputStream import java.util.* import java.util.concurrent.ConcurrentHashMap +import kotlin.random.asKotlinRandom /** * A portfolio represents a collection of scenarios are tested for the work. @@ -105,7 +102,7 @@ abstract class Portfolio(name: String) : Experiment(name) { val environment = ClusterEnvironmentReader(File(config.getString("env-path"), "${topology.name}.txt")) val chan = Channel(Channel.CONFLATED) - val allocationPolicy = createComputeScheduler(seeder) + val allocationPolicy = createComputeScheduler(allocationPolicy, seeder.asKotlinRandom(), vmPlacements) val meterProvider = createMeterProvider(clock) val workload = workload @@ -167,50 +164,4 @@ abstract class Portfolio(name: String) : Experiment(name) { val monitorResults = collectMetrics(meterProvider as MetricProducer) logger.debug { "Finish SUBMIT=${monitorResults.submittedVms} FAIL=${monitorResults.unscheduledVms} QUEUE=${monitorResults.queuedVms} RUNNING=${monitorResults.runningVms}" } } - - /** - * Create the [ComputeScheduler] instance to use for the trial. - */ - private fun createComputeScheduler(seeder: Random): ComputeScheduler { - return when (allocationPolicy) { - "mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(MemoryWeigher() to -1.0) - ) - "mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(MemoryWeigher() to -1.0) - ) - "core-mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(CoreMemoryWeigher() to -1.0) - ) - "core-mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(CoreMemoryWeigher() to -1.0) - ) - "active-servers" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to -1.0) - ) - "active-servers-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(InstanceCountWeigher() to 1.0) - ) - "provisioned-cores" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to -1.0) - ) - "provisioned-cores-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to 1.0) - ) - "random" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(RandomWeigher(Random(seeder.nextLong())) to 1.0) - ) - "replay" -> ReplayScheduler(vmPlacements) - else -> throw IllegalArgumentException("Unknown policy $allocationPolicy") - } - } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 08e04ddf..75428011 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -31,9 +31,10 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll import org.opendc.compute.service.driver.Host import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.weights.CoreMemoryWeigher +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.CoreRamWeigher import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.monitor.ExperimentMonitor @@ -68,8 +69,8 @@ class CapelinIntegrationTest { val seed = 0 val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(CoreMemoryWeigher() to -1.0) + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) ) val traceReader = createTestTraceReader() val environmentReader = createTestEnvironmentReader() @@ -113,9 +114,9 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(207380244590, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(207112418950, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(267825640, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(207380204679, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(207371815929, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(8388750, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } @@ -125,8 +126,8 @@ class CapelinIntegrationTest { val seed = 1 val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(CoreMemoryWeigher() to -1.0) + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) ) val traceReader = createTestTraceReader(0.5, seed) val environmentReader = createTestEnvironmentReader("single") diff --git a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt index 8fc4f6b8..e64e20a2 100644 --- a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt +++ b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt @@ -32,9 +32,9 @@ import mu.KotlinLogging import org.opendc.compute.service.ComputeService import org.opendc.compute.service.scheduler.ComputeScheduler import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.weights.RandomWeigher +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.* import org.opendc.experiments.capelin.monitor.ParquetExperimentMonitor @@ -81,8 +81,9 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { override fun doRun(repeat: Int): Unit = runBlockingSimulation { val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(RandomWeigher(Random(0)) to 1.0) + filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), + weighers = listOf(), + subsetSize = Int.MAX_VALUE ) val meterProvider: MeterProvider = createMeterProvider(clock) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt index 2ceb1e3c..860c50ee 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt @@ -89,7 +89,7 @@ public abstract class SimAbstractResourceProvider( */ protected fun updateCounters(ctx: SimResourceContext, work: Double) { if (work <= 0.0) { - return + return } val counters = _counters diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 5b5ef802..c5f5cd03 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -32,9 +32,6 @@ import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import mu.KotlinLogging -import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter -import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.weights.* import org.opendc.experiments.capelin.* import org.opendc.experiments.capelin.model.Workload @@ -199,46 +196,7 @@ class RunnerCli : CliktCommand(name = "runner") { val metricProducer = meterProvider as MetricProducer val operational = scenario.operationalPhenomena - val allocationPolicy = - when (val policyName = operational.schedulerName) { - "mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(MemoryWeigher() to -1.0) - ) - "mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(MemoryWeigher() to 1.0) - ) - "core-mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(CoreMemoryWeigher() to -1.0) - ) - "core-mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(CoreMemoryWeigher() to 1.0) - ) - "active-servers" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to -1.0) - ) - "active-servers-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(InstanceCountWeigher() to 1.0) - ) - "provisioned-cores" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to -1.0) - ) - "provisioned-cores-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to 1.0) - ) - "random" -> FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(RandomWeigher(java.util.Random(seeder.nextLong())) to 1.0) - ) - else -> throw IllegalArgumentException("Unknown policy $policyName") - } + val allocationPolicy = createComputeScheduler(operational.schedulerName, seeder) val trace = ParquetTraceReader( listOf(traceReader), diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt index 38c774a9..d82959e7 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt @@ -34,9 +34,10 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll import org.opendc.compute.service.ComputeService import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.weights.ProvisionedCoresWeigher +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.VCpuWeigher import org.opendc.compute.simulator.SimHost import org.opendc.format.environment.sc18.Sc18EnvironmentReader import org.opendc.format.trace.gwf.GwfTraceReader @@ -55,7 +56,7 @@ import kotlin.math.max /** * Integration test suite for the [WorkflowServiceImpl]. */ -@DisplayName("WorkflowServiceImpl") +@DisplayName("WorkflowService") internal class WorkflowServiceIntegrationTest { /** * A large integration test where we check whether all tasks in some trace are executed correctly. @@ -85,8 +86,8 @@ internal class WorkflowServiceIntegrationTest { val meter = MeterProvider.noop().get("opendc-compute") val computeScheduler = FilterScheduler( - filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), - weighers = listOf(ProvisionedCoresWeigher() to -1.0) + filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), + weighers = listOf(VCpuWeigher(1.0, multiplier = 1.0)) ) val compute = ComputeService(coroutineContext, clock, meter, computeScheduler, schedulingQuantum = 1000) -- cgit v1.2.3 From 31a1f298c71cd3203fdcd57bd39ba8813009dd5b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 17 Aug 2021 19:25:11 +0200 Subject: refactor(simulator): Execute traces based on timestamps This change refactors the trace workload in the OpenDC simulator to track execute a fragment based on the fragment's timestamp. This makes sure that the trace is replayed identically to the original execution. --- .../org/opendc/compute/simulator/SimHostTest.kt | 24 ++-- .../experiments/capelin/ExperimentHelpers.kt | 2 +- .../capelin/trace/RawParquetTraceReader.kt | 2 + .../capelin/trace/StreamingParquetTraceReader.kt | 4 +- .../experiments/capelin/CapelinIntegrationTest.kt | 12 +- .../serverless/trace/FunctionTraceWorkload.kt | 2 +- .../format/trace/bitbrains/BitbrainsTraceReader.kt | 7 +- .../org/opendc/format/trace/swf/SwfTraceReader.kt | 5 +- .../simulator/compute/SimMachineBenchmarks.kt | 16 +-- .../opendc/simulator/compute/SimAbstractMachine.kt | 1 - .../simulator/compute/workload/SimTraceWorkload.kt | 76 +++++++----- .../org/opendc/simulator/compute/SimMachineTest.kt | 1 - .../simulator/compute/kernel/SimHypervisorTest.kt | 40 +++---- .../compute/kernel/SimSpaceSharedHypervisorTest.kt | 8 +- .../compute/workload/SimTraceWorkloadTest.kt | 133 +++++++++++++++++++++ 15 files changed, 243 insertions(+), 90 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 5a6fb03d..45fdb268 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -99,11 +99,12 @@ internal class SimHostTest { mapOf( "workload" to SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(duration * 1000, 2 * 3500.0, 2), - SimTraceWorkload.Fragment(duration * 1000, 0.0, 2), - SimTraceWorkload.Fragment(duration * 1000, 2 * 183.0, 2) + SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 2 * 3500.0, 2), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 2), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 2 * 183.0, 2) ), + offset = 1 ) ) ) @@ -114,11 +115,12 @@ internal class SimHostTest { mapOf( "workload" to SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(duration * 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(duration * 1000, 0.0, 2), - SimTraceWorkload.Fragment(duration * 1000, 2 * 73.0, 2) - ) + SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(duration * 1000L, duration * 1000, 2 * 3100.0, 2), + SimTraceWorkload.Fragment(duration * 2000L, duration * 1000, 0.0, 2), + SimTraceWorkload.Fragment(duration * 3000L, duration * 1000, 2 * 73.0, 2) + ), + offset = 1 ) ) ) @@ -150,7 +152,7 @@ internal class SimHostTest { override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() }, - exportInterval = duration * 1000 + exportInterval = duration * 1000L ) coroutineScope { @@ -171,7 +173,7 @@ internal class SimHostTest { } // Ensure last cycle is collected - delay(1000 * duration) + delay(1000L * duration) virtDriver.close() reader.close() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 2c443678..fa9fa2fc 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -258,7 +258,7 @@ suspend fun processTrace( delay(max(0, (entry.start - offset) - clock.millis())) launch { chan.send(Unit) - val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace) + val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, offset = -offset + 300001) val server = client.newServer( entry.name, image, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt index 94193780..16ad6816 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt @@ -50,11 +50,13 @@ class RawParquetTraceReader(private val path: File) { val record = reader.read() ?: break val id = record["id"].toString() + val time = record["time"] as Long val duration = record["duration"] as Long val cores = record["cores"] as Int val cpuUsage = record["cpuUsage"] as Double val fragment = SimTraceWorkload.Fragment( + time, duration, cpuUsage, cores diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt index a3b45f47..35f4c5b8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt @@ -81,7 +81,7 @@ class StreamingParquetTraceReader(traceFile: File, selectedVms: List = e /** * A poisonous fragment. */ - private val poison = Pair("\u0000", SimTraceWorkload.Fragment(0, 0.0, 0)) + private val poison = Pair("\u0000", SimTraceWorkload.Fragment(0L, 0, 0.0, 0)) /** * The thread to read the records in. @@ -103,11 +103,13 @@ class StreamingParquetTraceReader(traceFile: File, selectedVms: List = e } val id = record["id"].toString() + val time = record["time"] as Long val duration = record["duration"] as Long val cores = record["cores"] as Int val cpuUsage = record["cpuUsage"] as Double val fragment = SimTraceWorkload.Fragment( + time, duration, cpuUsage, cores diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 75428011..00ab9190 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -114,9 +114,9 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(207380204679, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(207371815929, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(8388750, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(155252275350, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(155086837649, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(165488283, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } @@ -151,9 +151,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(96344616902, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(96324879442, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(19737460, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(29454904468, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(29355293349, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(99627123, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } diff --git a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt index 9a93092e..a119a219 100644 --- a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt +++ b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt @@ -29,6 +29,6 @@ import org.opendc.simulator.compute.workload.SimWorkload /** * A [SimFaaSWorkload] for a [FunctionTrace]. */ -public class FunctionTraceWorkload(trace: FunctionTrace) : SimFaaSWorkload, SimWorkload by SimTraceWorkload(trace.samples.asSequence().map { SimTraceWorkload.Fragment(it.duration, it.cpuUsage, 1) }) { +public class FunctionTraceWorkload(trace: FunctionTrace) : SimFaaSWorkload, SimWorkload by SimTraceWorkload(trace.samples.asSequence().map { SimTraceWorkload.Fragment(it.timestamp, it.duration, it.cpuUsage, 1) }) { override suspend fun invoke() {} } diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt index aaf8a240..cd8021fe 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt @@ -85,17 +85,19 @@ public class BitbrainsTraceReader(traceDirectory: File) : TraceReader 0) { flopsHistory.add( SimTraceWorkload.Fragment( + submitTime + slicedWaitTime + runTime, sliceDuration, runtimePartialSliceRemainder / sliceDuration.toDouble(), cores diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index 8f60bf05..30797089 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -70,14 +70,14 @@ class SimMachineBenchmarks { @Setup fun setUp() { trace = sequenceOf( - SimTraceWorkload.Fragment(1000, 28.0, 1), - SimTraceWorkload.Fragment(1000, 3500.0, 1), - SimTraceWorkload.Fragment(1000, 0.0, 1), - SimTraceWorkload.Fragment(1000, 183.0, 1), - SimTraceWorkload.Fragment(1000, 400.0, 1), - SimTraceWorkload.Fragment(1000, 100.0, 1), - SimTraceWorkload.Fragment(1000, 3000.0, 1), - SimTraceWorkload.Fragment(1000, 4500.0, 1), + SimTraceWorkload.Fragment(0, 1000, 28.0, 1), + SimTraceWorkload.Fragment(1000, 1000, 3500.0, 1), + SimTraceWorkload.Fragment(2000, 1000, 0.0, 1), + SimTraceWorkload.Fragment(3000, 1000, 183.0, 1), + SimTraceWorkload.Fragment(4000, 1000, 400.0, 1), + SimTraceWorkload.Fragment(5000, 1000, 100.0, 1), + SimTraceWorkload.Fragment(6000, 1000, 3000.0, 1), + SimTraceWorkload.Fragment(7000, 1000, 4500.0, 1), ) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index 139c66e0..f416643e 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -116,7 +116,6 @@ public abstract class SimAbstractMachine( // Cancel all cpus on cancellation cont.invokeOnCancellation { this.cont = null - interpreter.batch { for (cpu in cpus) { cpu.cancel() diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index 622bcd4d..fc49f357 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -27,25 +27,19 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext -import org.opendc.simulator.resources.consumer.SimConsumerBarrier /** * A [SimWorkload] that replays a workload trace consisting of multiple fragments, each indicating the resource * consumption for some period of time. + * + * @param trace The trace of fragments to use. + * @param offset The offset for the timestamps. */ -public class SimTraceWorkload(public val trace: Sequence) : SimWorkload { - private var offset = Long.MIN_VALUE +public class SimTraceWorkload(public val trace: Sequence, private val offset: Long = 0L) : SimWorkload { private val iterator = trace.iterator() private var fragment: Fragment? = null - private lateinit var barrier: SimConsumerBarrier override fun onStart(ctx: SimMachineContext) { - check(offset == Long.MIN_VALUE) { "Workload does not support re-use" } - - barrier = SimConsumerBarrier(ctx.cpus.size) - fragment = nextFragment() - offset = ctx.interpreter.clock.millis() - val lifecycle = SimWorkloadLifecycle(ctx) for (cpu in ctx.cpus) { @@ -56,43 +50,59 @@ public class SimTraceWorkload(public val trace: Sequence) : SimWorkloa override fun toString(): String = "SimTraceWorkload" /** - * Obtain the next fragment. + * Obtain the fragment with a timestamp equal or greater than [now]. */ - private fun nextFragment(): Fragment? { - return if (iterator.hasNext()) { - iterator.next() - } else { - null + private fun pullFragment(now: Long): Fragment? { + var fragment = fragment + if (fragment != null && !fragment.isExpired(now)) { + return fragment + } + + while (iterator.hasNext()) { + fragment = iterator.next() + if (!fragment.isExpired(now)) { + this.fragment = fragment + return fragment + } } + + this.fragment = null + return null + } + + /** + * Determine if the specified [Fragment] is expired, i.e., it has already passed. + */ + private fun Fragment.isExpired(now: Long): Boolean { + val timestamp = this.timestamp + offset + return now >= timestamp + duration } private inner class Consumer(val cpu: ProcessingUnit) : SimResourceConsumer { override fun onNext(ctx: SimResourceContext): SimResourceCommand { val now = ctx.clock.millis() - val fragment = fragment ?: return SimResourceCommand.Exit - val usage = fragment.usage / fragment.cores - val work = (fragment.duration / 1000) * usage - val deadline = offset + fragment.duration + val fragment = pullFragment(now) ?: return SimResourceCommand.Exit + val timestamp = fragment.timestamp + offset - assert(deadline >= now) { "Deadline already passed" } - - val cmd = - if (cpu.id < fragment.cores && work > 0.0) - SimResourceCommand.Consume(work, usage, deadline) - else - SimResourceCommand.Idle(deadline) - - if (barrier.enter()) { - this@SimTraceWorkload.fragment = nextFragment() - this@SimTraceWorkload.offset += fragment.duration + // Fragment is in the future + if (timestamp > now) { + return SimResourceCommand.Idle(timestamp) } - return cmd + val usage = fragment.usage / fragment.cores + val deadline = timestamp + fragment.duration + val duration = deadline - now + val work = duration * usage / 1000 + + return if (cpu.id < fragment.cores && work > 0.0) + SimResourceCommand.Consume(work, usage, deadline) + else + SimResourceCommand.Idle(deadline) } } /** * A fragment of the workload. */ - public data class Fragment(val duration: Long, val usage: Double, val cores: Int) + public data class Fragment(val timestamp: Long, val duration: Long, val usage: Double, val cores: Int) } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt index a6d955ca..19808a77 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt @@ -44,7 +44,6 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer /** * Test suite for the [SimBareMetalMachine] class. */ -@OptIn(ExperimentalCoroutinesApi::class) class SimMachineTest { private lateinit var machineModel: MachineModel diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index a61cba8d..afc4c949 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -91,10 +91,10 @@ internal class SimHypervisorTest { val workloadA = SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 183.0, 1) + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) ), ) @@ -154,19 +154,19 @@ internal class SimHypervisorTest { val workloadA = SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 183.0, 1) + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) ), ) val workloadB = SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 3100.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 73.0, 1) + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3100.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) ) ) @@ -251,19 +251,19 @@ internal class SimHypervisorTest { val workloadA = SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 183.0, 1) + SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) ), ) val workloadB = SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 3100.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 73.0, 1) + SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3100.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) ) ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index 7c77b283..80496992 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -71,10 +71,10 @@ internal class SimSpaceSharedHypervisorTest { val workloadA = SimTraceWorkload( sequenceOf( - SimTraceWorkload.Fragment(duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, 183.0, 1) + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) ), ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt new file mode 100644 index 00000000..39c1eb5a --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.compute.workload + +import kotlinx.coroutines.delay +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.opendc.simulator.compute.SimBareMetalMachine +import org.opendc.simulator.compute.model.* +import org.opendc.simulator.compute.power.ConstantPowerModel +import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.resources.SimResourceInterpreter + +/** + * Test suite for the [SimTraceWorkloadTest] class. + */ +class SimTraceWorkloadTest { + private lateinit var machineModel: MachineModel + + @BeforeEach + fun setUp() { + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) + + machineModel = MachineModel( + cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, + memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } + ) + } + + @Test + fun testSmoke() = runBlockingSimulation { + val machine = SimBareMetalMachine( + SimResourceInterpreter(coroutineContext, clock), + machineModel, + SimplePowerDriver(ConstantPowerModel(0.0)) + ) + + val workload = SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), + SimTraceWorkload.Fragment(2000, 1000, 0.0, 2), + SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + ), + offset = 0 + ) + + try { + machine.run(workload) + + assertEquals(4000, clock.millis()) + } finally { + machine.close() + } + } + + @Test + fun testOffset() = runBlockingSimulation { + val machine = SimBareMetalMachine( + SimResourceInterpreter(coroutineContext, clock), + machineModel, + SimplePowerDriver(ConstantPowerModel(0.0)) + ) + + val workload = SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), + SimTraceWorkload.Fragment(2000, 1000, 0.0, 2), + SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + ), + offset = 1000 + ) + + try { + machine.run(workload) + + assertEquals(5000, clock.millis()) + } finally { + machine.close() + } + } + + @Test + fun testSkipFragment() = runBlockingSimulation { + val machine = SimBareMetalMachine( + SimResourceInterpreter(coroutineContext, clock), + machineModel, + SimplePowerDriver(ConstantPowerModel(0.0)) + ) + + val workload = SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), + SimTraceWorkload.Fragment(2000, 1000, 0.0, 2), + SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + ), + offset = 0 + ) + + try { + delay(1000L) + machine.run(workload) + + assertEquals(4000, clock.millis()) + } finally { + machine.close() + } + } +} -- cgit v1.2.3 From 484848e2e0bfdaf46f10112e358d3475dbf8e725 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 12:13:07 +0200 Subject: fix(simulator): Record overcommit only after deadline This change fixes an issue with the simulator where it would record overcomitted work if the output was updated before the deadline was reached. --- .../org/opendc/experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../opendc/simulator/resources/SimAbstractResourceAggregator.kt | 4 ++-- .../org/opendc/simulator/resources/SimAbstractResourceProvider.kt | 7 +++++-- .../org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt | 7 ++++--- .../org/opendc/simulator/resources/SimResourceProviderLogic.kt | 3 ++- .../kotlin/org/opendc/simulator/resources/SimResourceSource.kt | 4 ++-- .../org/opendc/simulator/resources/impl/SimResourceContextImpl.kt | 5 +++-- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 00ab9190..3dca1e09 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -116,7 +116,7 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, { assertEquals(155252275350, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, { assertEquals(155086837649, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(165488283, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(155088144, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt index 8a24b3e7..00648876 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt @@ -112,8 +112,8 @@ public abstract class SimAbstractResourceAggregator( doFinish() } - override fun onUpdate(ctx: SimResourceControllableContext, work: Double) { - updateCounters(ctx, work) + override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { + updateCounters(ctx, work, willOvercommit) } override fun getConsumedWork(ctx: SimResourceControllableContext, work: Double, speed: Double, duration: Long): Double { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt index 860c50ee..4e8e803a 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt @@ -87,7 +87,7 @@ public abstract class SimAbstractResourceProvider( /** * Update the counters of the resource provider. */ - protected fun updateCounters(ctx: SimResourceContext, work: Double) { + protected fun updateCounters(ctx: SimResourceContext, work: Double, willOvercommit: Boolean) { if (work <= 0.0) { return } @@ -96,7 +96,10 @@ public abstract class SimAbstractResourceProvider( val remainingWork = ctx.remainingWork counters.demand += work counters.actual += work - remainingWork - counters.overcommit += remainingWork + + if (willOvercommit && remainingWork > 0.0) { + counters.overcommit += remainingWork + } } final override fun startConsumer(consumer: SimResourceConsumer) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index 398797cf..6b420911 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -160,7 +160,8 @@ public class SimResourceDistributorMaxMin( this.totalRequestedWork = totalRequestedWork this.totalRequestedSpeed = totalRequestedSpeed - this.totalAllocatedSpeed = capacity - availableSpeed + val totalAllocatedSpeed = capacity - availableSpeed + this.totalAllocatedSpeed = totalAllocatedSpeed val totalAllocatedWork = min( totalRequestedWork, totalAllocatedSpeed * min((deadline - interpreter.clock.millis()) / 1000.0, duration) @@ -262,8 +263,8 @@ public class SimResourceDistributorMaxMin( return Long.MAX_VALUE } - override fun onUpdate(ctx: SimResourceControllableContext, work: Double) { - updateCounters(ctx, work) + override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { + updateCounters(ctx, work, willOvercommit) } override fun onFinish(ctx: SimResourceControllableContext) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt index 17045557..2fe1b00f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt @@ -52,8 +52,9 @@ public interface SimResourceProviderLogic { * * @param ctx The context in which the provider runs. * @param work The amount of work that was requested by the resource consumer. + * @param willOvercommit A flag to indicate that the remaining work is overcommitted. */ - public fun onUpdate(ctx: SimResourceControllableContext, work: Double) {} + public fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) {} /** * This method is invoked when the resource consumer has finished. diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt index 2f70e3cc..2d53198a 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt @@ -51,8 +51,8 @@ public class SimResourceSource( } } - override fun onUpdate(ctx: SimResourceControllableContext, work: Double) { - updateCounters(ctx, work) + override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { + updateCounters(ctx, work, willOvercommit) } override fun onFinish(ctx: SimResourceControllableContext) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index 98fad068..b79998a3 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -202,17 +202,18 @@ internal class SimResourceContextImpl( val isInterrupted = _flag and FLAG_INTERRUPT != 0 val remainingWork = getRemainingWork(timestamp) val isConsume = _limit > 0.0 + val reachedDeadline = _deadline <= timestamp // Update the resource counters only if there is some progress if (timestamp > _timestamp) { - logic.onUpdate(this, _work) + logic.onUpdate(this, _work, reachedDeadline) } // We should only continue processing the next command if: // 1. The resource consumption was finished. // 2. The resource capacity cannot satisfy the demand. // 3. The resource consumer should be interrupted (e.g., someone called .interrupt()) - if ((isConsume && remainingWork == 0.0) || _deadline <= timestamp || isInterrupted) { + if ((isConsume && remainingWork == 0.0) || reachedDeadline || isInterrupted) { when (val command = consumer.onNext(this)) { is SimResourceCommand.Idle -> interpretIdle(timestamp, command.deadline) is SimResourceCommand.Consume -> interpretConsume(timestamp, command.work, command.limit, command.deadline) -- cgit v1.2.3 From a9539a3e444c1bd4fb7090dad38f3b568afe092a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 12:18:08 +0200 Subject: fix(simulator): Support trace fragments with zero cores available This change fixes an issue with the simulator where trace fragments with zero cores to execute would give a NaN amount of work. --- .../simulator/compute/workload/SimTraceWorkload.kt | 10 +++++++- .../compute/workload/SimTraceWorkloadTest.kt | 27 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index fc49f357..48be8e1a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -89,7 +89,10 @@ public class SimTraceWorkload(public val trace: Sequence, private val return SimResourceCommand.Idle(timestamp) } - val usage = fragment.usage / fragment.cores + val usage = if (fragment.cores > 0) + fragment.usage / fragment.cores + else + 0.0 val deadline = timestamp + fragment.duration val duration = deadline - now val work = duration * usage / 1000 @@ -103,6 +106,11 @@ public class SimTraceWorkload(public val trace: Sequence, private val /** * A fragment of the workload. + * + * @param timestamp The timestamp at which the fragment starts. + * @param duration The duration of the fragment. + * @param usage The CPU usage during the fragment. + * @param cores The amount of cores utilized during the fragment. */ public data class Fragment(val timestamp: Long, val duration: Long, val usage: Double, val cores: Int) } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt index 39c1eb5a..78019c2e 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt @@ -130,4 +130,31 @@ class SimTraceWorkloadTest { machine.close() } } + + @Test + fun testZeroCores() = runBlockingSimulation { + val machine = SimBareMetalMachine( + SimResourceInterpreter(coroutineContext, clock), + machineModel, + SimplePowerDriver(ConstantPowerModel(0.0)) + ) + + val workload = SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), + SimTraceWorkload.Fragment(2000, 1000, 0.0, 0), + SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + ), + offset = 0 + ) + + try { + machine.run(workload) + + assertEquals(4000, clock.millis()) + } finally { + machine.close() + } + } } -- cgit v1.2.3 From c46ff4c5cc18ba8a82ee0135f087c4d7aed1e804 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 14:39:03 +0200 Subject: fix(simulator): Support unaligned trace fragments --- .../experiments/capelin/CapelinIntegrationTest.kt | 8 +-- .../resources/SimResourceDistributorMaxMin.kt | 59 ++++++++++++++++++---- .../simulator/resources/SimResourceSwitchMaxMin.kt | 2 +- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 3dca1e09..393fb88d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -114,9 +114,9 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(155252275350, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(155086837649, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(155088144, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(155252275351, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(155086837645, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(725049, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } @@ -153,7 +153,7 @@ class CapelinIntegrationTest { assertAll( { assertEquals(29454904468, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, { assertEquals(29355293349, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(99627123, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(0, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index 6b420911..a985986d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -22,6 +22,7 @@ package org.opendc.simulator.resources +import org.opendc.simulator.resources.impl.SimResourceCountersImpl import org.opendc.simulator.resources.interference.InterferenceDomain import org.opendc.simulator.resources.interference.InterferenceKey import kotlin.math.min @@ -53,9 +54,9 @@ public class SimResourceDistributorMaxMin( private val activeOutputs: MutableList = mutableListOf() /** - * The total amount of work requested by the output resources. + * The total amount of work allocated to be executed. */ - private var totalRequestedWork = 0.0 + private var totalAllocatedWork = 0.0 /** * The total allocated speed for the output resources. @@ -67,6 +68,13 @@ public class SimResourceDistributorMaxMin( */ private var totalRequestedSpeed = 0.0 + /** + * The resource counters of this distributor. + */ + public val counters: SimResourceCounters + get() = _counters + private val _counters = SimResourceCountersImpl() + /* SimResourceDistributor */ override fun newOutput(key: InterferenceKey?): SimResourceCloseableProvider { val provider = Output(ctx?.capacity ?: 0.0, key) @@ -102,6 +110,25 @@ public class SimResourceDistributorMaxMin( } } + /** + * Update the counters of the distributor. + */ + private fun updateCounters(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { + if (work <= 0.0) { + return + } + + val counters = _counters + val remainingWork = ctx.remainingWork + + counters.demand += work + counters.actual += work - remainingWork + + if (willOvercommit && remainingWork > 0.0) { + counters.overcommit += remainingWork + } + } + /** * Schedule the work of the outputs. */ @@ -116,7 +143,6 @@ public class SimResourceDistributorMaxMin( var deadline: Long = Long.MAX_VALUE var availableSpeed = capacity var totalRequestedSpeed = 0.0 - var totalRequestedWork = 0.0 // Pull in the work of the outputs val outputIterator = activeOutputs.listIterator() @@ -138,6 +164,7 @@ public class SimResourceDistributorMaxMin( for (output in activeOutputs) { val availableShare = availableSpeed / remaining-- val grantedSpeed = min(output.allowedSpeed, availableShare) + deadline = min(deadline, output.deadline) // Ignore idle computation @@ -147,7 +174,6 @@ public class SimResourceDistributorMaxMin( } totalRequestedSpeed += output.limit - totalRequestedWork += output.work output.actualSpeed = grantedSpeed availableSpeed -= grantedSpeed @@ -156,19 +182,28 @@ public class SimResourceDistributorMaxMin( duration = min(duration, output.work / grantedSpeed) } + val targetDuration = min(duration, (deadline - interpreter.clock.millis()) / 1000.0) + var totalRequestedWork = 0.0 + var totalAllocatedWork = 0.0 + for (output in activeOutputs) { + val work = output.work + val speed = output.actualSpeed + if (speed > 0.0) { + val outputDuration = work / speed + totalRequestedWork += work * (duration / outputDuration) + totalAllocatedWork += work * (targetDuration / outputDuration) + } + } + assert(deadline >= interpreter.clock.millis()) { "Deadline already passed" } - this.totalRequestedWork = totalRequestedWork this.totalRequestedSpeed = totalRequestedSpeed + this.totalAllocatedWork = totalAllocatedWork val totalAllocatedSpeed = capacity - availableSpeed this.totalAllocatedSpeed = totalAllocatedSpeed - val totalAllocatedWork = min( - totalRequestedWork, - totalAllocatedSpeed * min((deadline - interpreter.clock.millis()) / 1000.0, duration) - ) return if (totalAllocatedWork > 0.0 && totalAllocatedSpeed > 0.0) - SimResourceCommand.Consume(totalRequestedWork, totalAllocatedSpeed, deadline) + SimResourceCommand.Consume(totalAllocatedWork, totalAllocatedSpeed, deadline) else SimResourceCommand.Idle(deadline) } @@ -265,6 +300,8 @@ public class SimResourceDistributorMaxMin( override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { updateCounters(ctx, work, willOvercommit) + + this@SimResourceDistributorMaxMin.updateCounters(ctx, work, willOvercommit) } override fun onFinish(ctx: SimResourceControllableContext) { @@ -289,7 +326,7 @@ public class SimResourceDistributorMaxMin( } // Compute the work that was actually granted to the output. - return (totalRequestedWork - totalRemainingWork) * fraction * perfScore + return (totalAllocatedWork - totalRemainingWork) * fraction * perfScore } /* Comparable */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt index ceb5a1a4..d988b70d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt @@ -54,7 +54,7 @@ public class SimResourceSwitchMaxMin( * The resource counters to track the execution metrics of all switch resources. */ override val counters: SimResourceCounters - get() = aggregator.counters + get() = distributor.counters /** * A flag to indicate that the switch was closed. -- cgit v1.2.3 From a23ad09d5a1c4033781bd5403ad766cae83a2beb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 12:11:22 +0200 Subject: refactor(format): Clean up Bitbrains trace reader to enable re-use This change updates the code for the Bitbrains trace reader and upgrades the TraceConverter to re-use existing code of the Bitbrains trace reader. --- gradle/libs.versions.toml | 1 + .../experiments/capelin/trace/TraceConverter.kt | 127 +- opendc-format/build.gradle.kts | 1 + .../trace/bitbrains/BitbrainsRawTraceReader.kt | 100 + .../format/trace/bitbrains/BitbrainsTraceReader.kt | 97 +- .../trace/bitbrains/BitbrainsTraceReaderTest.kt | 45 + opendc-format/src/test/resources/bitbrains.csv | 8620 ++++++++++++++++++++ 7 files changed, 8833 insertions(+), 158 deletions(-) create mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt create mode 100644 opendc-format/src/test/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReaderTest.kt create mode 100644 opendc-format/src/test/resources/bitbrains.csv diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a9b1bf53..a15fa45d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,6 +39,7 @@ progressbar = { module = "me.tongfei:progressbar", version = "0.9.0" } # Format jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } +jackson-dataformat-csv = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-csv", version.ref = "jackson" } parquet = { module = "org.apache.parquet:parquet-avro", version = "1.12.0" } yaml = { module = "org.yaml:snakeyaml", version = "1.29" } config = { module = "com.typesafe:config", version = "1.4.1" } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt index 7cd1f159..d7daa35b 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt @@ -26,12 +26,7 @@ import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.groups.OptionGroup import com.github.ajalt.clikt.parameters.groups.groupChoice -import com.github.ajalt.clikt.parameters.options.convert -import com.github.ajalt.clikt.parameters.options.default -import com.github.ajalt.clikt.parameters.options.defaultLazy -import com.github.ajalt.clikt.parameters.options.option -import com.github.ajalt.clikt.parameters.options.required -import com.github.ajalt.clikt.parameters.options.split +import com.github.ajalt.clikt.parameters.options.* import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.long import me.tongfei.progressbar.ProgressBar @@ -41,11 +36,13 @@ import org.apache.avro.generic.GenericData import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.format.trace.bitbrains.BitbrainsTraceReader import org.opendc.format.util.LocalOutputFile +import org.opendc.simulator.compute.workload.SimTraceWorkload import java.io.BufferedReader import java.io.File import java.io.FileReader -import java.util.Random +import java.util.* import kotlin.math.max import kotlin.math.min @@ -340,106 +337,36 @@ class BitbrainsConversion : TraceConversion("Bitbrains") { metaSchema: Schema, metaWriter: ParquetWriter ): MutableList { - val timestampCol = 0 - val cpuUsageCol = 3 - val coreCol = 1 - val provisionedMemoryCol = 5 - val traceInterval = 5 * 60 * 1000L - - val allFragments = mutableListOf() - - traceDirectory.walk() - .filterNot { it.isDirectory } - .filter { it.extension == "csv" || it.extension == "txt" } - .toList() - .forEach { vmFile -> - println(vmFile) - - var vmId = "" - var maxCores = -1 - var requiredMemory = -1L - var cores: Int - var minTime = Long.MAX_VALUE - - val flopsFragments = sequence { - var last: Fragment? = null - - BufferedReader(FileReader(vmFile)).use { reader -> - reader.lineSequence() - .drop(1) - .chunked(128) - .forEach { lines -> - for (line in lines) { - // Ignore comments in the trace - if (line.startsWith("#") || line.isBlank()) { - continue - } - - val values = line.split(";\t") - - vmId = vmFile.name - - val timestamp = (values[timestampCol].trim().toLong() - 5 * 60) * 1000L - - cores = values[coreCol].trim().toInt() - val provisionedMemory = values[provisionedMemoryCol].trim().toDouble() // KB - requiredMemory = max(requiredMemory, (provisionedMemory / 1000).toLong()) - maxCores = max(maxCores, cores) - minTime = min(minTime, timestamp) - val cpuUsage = values[cpuUsageCol].trim().toDouble() // MHz - - val flops: Long = (cpuUsage * 5 * 60).toLong() - - last = if (last != null && last!!.flops == 0L && flops == 0L) { - val oldFragment = last!! - Fragment( - vmId, - oldFragment.tick, - oldFragment.flops + flops, - oldFragment.duration + traceInterval, - cpuUsage, - cores - ) - } else { - val fragment = - Fragment( - vmId, - timestamp, - flops, - traceInterval, - cpuUsage, - cores - ) - if (last != null) { - yield(last!!) - } - fragment - } - } - } - } - - if (last != null) { - yield(last!!) - } - } - + val fragments = mutableListOf() + BitbrainsTraceReader(traceDirectory).use { reader -> + reader.forEach { entry -> + val trace = (entry.workload as SimTraceWorkload).trace var maxTime = Long.MIN_VALUE - flopsFragments.forEach { fragment -> - allFragments.add(fragment) - maxTime = max(maxTime, fragment.tick) + trace.forEach { fragment -> + val flops: Long = (fragment.usage * fragment.duration / 1000).toLong() + fragments.add( + Fragment( + entry.name, + fragment.timestamp, + flops, + fragment.duration, + fragment.usage, + fragment.cores + ) + ) + maxTime = max(maxTime, fragment.timestamp + fragment.duration) } val metaRecord = GenericData.Record(metaSchema) - metaRecord.put("id", vmId) - metaRecord.put("submissionTime", minTime) + metaRecord.put("id", entry.name) + metaRecord.put("submissionTime", entry.start) metaRecord.put("endTime", maxTime) - metaRecord.put("maxCores", maxCores) - metaRecord.put("requiredMemory", requiredMemory) + metaRecord.put("maxCores", entry.meta["cores"]) + metaRecord.put("requiredMemory", entry.meta["required-memory"]) metaWriter.write(metaRecord) } - - return allFragments + } + return fragments } } diff --git a/opendc-format/build.gradle.kts b/opendc-format/build.gradle.kts index e19e0ec8..c8e30846 100644 --- a/opendc-format/build.gradle.kts +++ b/opendc-format/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { api(libs.jackson.module.kotlin) { exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") } + implementation(libs.jackson.dataformat.csv) implementation(kotlin("reflect")) /* This configuration is necessary for a slim dependency on Apache Parquet */ diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt new file mode 100644 index 00000000..ff6cdd02 --- /dev/null +++ b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.format.trace.bitbrains + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.MappingIterator +import com.fasterxml.jackson.dataformat.csv.CsvMapper +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import java.io.InputStream + +/** + * A trace reader that enables the user to read Bitbrains specific trace data. + */ +public class BitbrainsRawTraceReader(input: InputStream) : Iterator, AutoCloseable { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("Timestamp [ms]", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU cores", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU capacity provisioned [MHZ]", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU usage [MHZ]", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU usage [%]", CsvSchema.ColumnType.NUMBER) + .addColumn("Memory capacity provisioned [KB]", CsvSchema.ColumnType.NUMBER) + .addColumn("Memory usage [KB]", CsvSchema.ColumnType.NUMBER) + .addColumn("Disk read throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Disk write throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Network received throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Network transmitted throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .setUseHeader(true) + .setColumnSeparator(';') + .build() + + /** + * The mapping iterator to use. + */ + private val iterator: MappingIterator = CsvMapper().readerFor(Entry::class.java).with(schema) + .readValues(input) + + override fun hasNext(): Boolean { + return iterator.hasNext() + } + + override fun next(): Entry { + return iterator.next() + } + + override fun close() { + iterator.close() + } + + /** + * A single entry in the trace. + */ + public data class Entry( + @JsonProperty("Timestamp [ms]") + val timestamp: Long, + @JsonProperty("CPU cores") + val cpuCores: Int, + @JsonProperty("CPU capacity provisioned [MHZ]") + val cpuCapacity: Double, + @JsonProperty("CPU usage [MHZ]") + val cpuUsage: Double, + @JsonProperty("CPU usage [%]") + val cpuUsagePct: Double, + @JsonProperty("Memory capacity provisioned [KB]") + val memCapacity: Double, + @JsonProperty("Memory usage [KB]") + val memUsage: Double, + @JsonProperty("Disk read throughput [KB/s]") + val diskRead: Double, + @JsonProperty("Disk write throughput [KB/s]") + val diskWrite: Double, + @JsonProperty("Network received throughput [KB/s]") + val netReceived: Double, + @JsonProperty("Network transmitted throughput [KB/s]") + val netTransmitted: Double + ) +} diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt index cd8021fe..9e4876df 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt @@ -26,10 +26,10 @@ import org.opendc.format.trace.TraceEntry import org.opendc.format.trace.TraceReader import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload -import java.io.BufferedReader import java.io.File -import java.io.FileReader +import java.io.FileInputStream import java.util.* +import kotlin.math.max import kotlin.math.min /** @@ -48,74 +48,55 @@ public class BitbrainsTraceReader(traceDirectory: File) : TraceReader>() - - var timestampCol = 0 - var coreCol = 0 - var cpuUsageCol = 0 - var provisionedMemoryCol = 0 val traceInterval = 5 * 60 * 1000L traceDirectory.walk() .filterNot { it.isDirectory } + .filter { it.extension == "csv" } .forEach { vmFile -> - println(vmFile) val flopsHistory = mutableListOf() var vmId = -1L - var cores = -1 - var requiredMemory = -1L - var startTime = -1L - - BufferedReader(FileReader(vmFile)).use { reader -> - reader.lineSequence() - .filter { line -> - // Ignore comments in the trace - !line.startsWith("#") && line.isNotBlank() + var maxCores = Int.MIN_VALUE + var requiredMemory = Long.MIN_VALUE + var startTime = Long.MAX_VALUE + var lastTimestamp = Long.MIN_VALUE + + BitbrainsRawTraceReader(FileInputStream(vmFile)).use { reader -> + reader.forEach { entry -> + val timestamp = entry.timestamp * 1000L + val cpuUsage = entry.cpuUsage + vmId = vmFile.nameWithoutExtension.trim().toLong() + val cores = entry.cpuCores + maxCores = max(maxCores, cores) + requiredMemory = max(requiredMemory, (entry.memCapacity / 1000).toLong()) + + if (lastTimestamp < 0) { + lastTimestamp = timestamp - 5 * 60 * 1000L + startTime = min(startTime, lastTimestamp) } - .forEachIndexed { idx, line -> - val values = line.split(";\t") - - // Parse GWF header - if (idx == 0) { - val header = values.mapIndexed { col, name -> Pair(name.trim(), col) }.toMap() - timestampCol = header["Timestamp [ms]"]!! - coreCol = header["CPU cores"]!! - cpuUsageCol = header["CPU usage [MHZ]"]!! - provisionedMemoryCol = header["Memory capacity provisioned [KB]"]!! - return@forEachIndexed - } - vmId = vmFile.nameWithoutExtension.trim().toLong() - val timestamp = values[timestampCol].trim().toLong() - 5 * 60 - startTime = min(startTime, timestamp) - cores = values[coreCol].trim().toInt() - val cpuUsage = values[cpuUsageCol].trim().toDouble() // MHz - requiredMemory = (values[provisionedMemoryCol].trim().toDouble() / 1000).toLong() - - if (flopsHistory.isEmpty()) { - flopsHistory.add(SimTraceWorkload.Fragment(timestamp, traceInterval, cpuUsage, cores)) + if (flopsHistory.isEmpty()) { + flopsHistory.add(SimTraceWorkload.Fragment(lastTimestamp, traceInterval, cpuUsage, cores)) + } else { + val last = flopsHistory.last() + val duration = timestamp - lastTimestamp + // Perform run-length encoding + if (duration == 0L || last.usage == cpuUsage) { + flopsHistory[flopsHistory.size - 1] = last.copy(duration = last.duration + duration) } else { - if (flopsHistory.last().usage != cpuUsage) { - flopsHistory.add( - SimTraceWorkload.Fragment( - timestamp, - traceInterval, - cpuUsage, - cores - ) - ) - } else { - val oldFragment = flopsHistory.removeAt(flopsHistory.size - 1) - flopsHistory.add( - SimTraceWorkload.Fragment( - oldFragment.timestamp, - oldFragment.duration + traceInterval, - cpuUsage, - cores - ) + flopsHistory.add( + SimTraceWorkload.Fragment( + lastTimestamp, + duration, + cpuUsage, + cores ) - } + ) } } + + lastTimestamp = timestamp + } } val uuid = UUID(0L, vmId) @@ -127,7 +108,7 @@ public class BitbrainsTraceReader(traceDirectory: File) : TraceReader + val entry = reader.next() + + assertAll( + { assertEquals(1376314846, entry.timestamp) }, + { assertEquals(19.066, entry.cpuUsage, 0.01) } + ) + } + } +} diff --git a/opendc-format/src/test/resources/bitbrains.csv b/opendc-format/src/test/resources/bitbrains.csv new file mode 100644 index 00000000..f5e300e8 --- /dev/null +++ b/opendc-format/src/test/resources/bitbrains.csv @@ -0,0 +1,8620 @@ +Timestamp [ms]; CPU cores; CPU capacity provisioned [MHZ]; CPU usage [MHZ]; CPU usage [%]; Memory capacity provisioned [KB]; Memory usage [KB]; Disk read throughput [KB/s]; Disk write throughput [KB/s]; Network received throughput [KB/s]; Network transmitted throughput [KB/s] +1376314846; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1376315146; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376315446; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376315746; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376316046; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376316346; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1376316646; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 128624.26666666666; 0.06666666666666667; 8.733333333333333; 0.3333333333333333; 0.6 +1376316946; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 134216.8; 0.0; 1.2; 0.0; 0.0 +1376317246; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376317546; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1376317846; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376318146; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.06666666666666667; 1.6; 0.06666666666666667; 0.13333333333333333 +1376318446; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376318746; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376319046; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1376319346; 1; 2599.999626; 38.99999439; 1.5; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376319646; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1376319946; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1376320246; 1; 2599.999626; 41.599994016000004; 1.6; 2097152.0; 150993.6; 0.0; 2.7333333333333334; 67.46666666666667; 0.5333333333333333 +1376320546; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376320846; 1; 2599.999626; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376321146; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1376321446; 1; 2599.999626; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376321746; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376322046; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376322346; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.6; 0.0 +1376322647; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376322947; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376323247; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 117439.2; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376323547; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1376323847; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 146800.0; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 +1376324147; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.2; 1.5333333333333334; 0.0; 0.0 +1376324447; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.5333333333333334; 0.0; 0.0 +1376324747; 1; 2599.999626; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376325047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376325347; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1376325647; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.2; 0.0; 0.0 +1376325947; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376326247; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376326547; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376326847; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376327147; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376327447; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 198527.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376327747; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376328047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376328347; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376328647; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 +1376328947; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376329247; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1376329547; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1376329847; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376330147; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 125828.0; 0.2; 7.466666666666667; 0.2; 0.13333333333333333 +1376330447; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376330747; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 155188.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376331047; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 167771.2; 0.0; 2.466666666666667; 0.3333333333333333; 0.4666666666666667 +1376331347; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 132817.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1376331647; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376331947; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376332247; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376332547; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376332847; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.6; 0.0; 0.0 +1376333147; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376333447; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376333747; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376334047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376334347; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376334647; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 170565.86666666667; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1376334947; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 128624.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376335247; 1; 2599.999626; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1376335547; 1; 2599.999626; 46.799993268; 1.8; 2097152.0; 341134.4; 161.73333333333332; 14.666666666666666; 0.0; 0.2 +1376335847; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 216702.93333333332; 0.0; 7.733333333333333; 0.26666666666666666; 0.13333333333333333 +1376336147; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 160780.53333333333; 31.8; 3.8666666666666667; 0.0; 0.0 +1376336447; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 1.3333333333333333; 0.26666666666666666; 0.0 +1376336747; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376337047; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1376337347; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1376337647; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376337947; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.0; 0.0 +1376338248; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 205518.66666666666; 0.0; 3.066666666666667; 0.0; 0.4666666666666667 +1376338548; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 138410.93333333332; 0.06666666666666667; 1.5333333333333334; 0.0; 0.0 +1376338848; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376339148; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376339448; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376339748; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376340048; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.2; 0.0; 0.0 +1376340348; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.6666666666666666; 0.0 +1376340648; 1; 2599.999626; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376340948; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376341248; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376341548; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1376341848; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 127225.33333333333; 0.2; 2.6666666666666665; 0.0; 0.4666666666666667 +1376342148; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1376342448; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 +1376342748; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 +1376343048; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376343348; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.13333333333333333; 0.0 +1376343648; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.3333333333333333; 0.0 +1376343948; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 149594.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1376344248; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 1.1333333333333333; 0.6; 0.0 +1376344548; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376344848; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376345148; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1376345448; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 162177.86666666667; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376345748; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376346048; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1376346348; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376346648; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 74097.06666666667; 2.6666666666666665; 1.4666666666666666; 0.13333333333333333; 0.0 +1376346948; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1376347248; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 +1376347548; 1; 2599.999626; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376347848; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376348148; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 7.466666666666667; 0.26666666666666666; 0.2 +1376348448; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376348749; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376349049; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376349349; 1; 2599.999626; 41.599994016000004; 1.6; 2097152.0; 187343.73333333334; 161.0; 21.6; 0.06666666666666667; 0.4 +1376349649; 1; 2599.999626; 22.533330092; 0.8666666666666667; 2097152.0; 577414.1333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1376349949; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 234878.4; 31.8; 3.6666666666666665; 0.0; 0.0 +1376350249; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 178954.4; 0.8; 2.466666666666667; 0.0; 0.06666666666666667 +1376350549; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1376350849; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376351149; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.06666666666666667; 0.0 +1376351449; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376351749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376352049; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 1.4666666666666666; 1.6666666666666667; 0.0; 0.0 +1376352349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376352649; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 178954.13333333333; 3.8666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1376352949; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 141206.4; 0.0; 1.0; 0.0; 0.0 +1376353249; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376353549; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376353849; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.6; 12.4; 0.0; 0.0 +1376354149; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 192936.0; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.13333333333333333 +1376354449; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 130022.4; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1376354749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.4; 0.0; 0.0 +1376355049; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376355349; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 +1376355649; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1376355949; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376356249; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 138410.66666666666; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376356549; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 121633.33333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1376356849; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1376357149; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376357449; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376357749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376358049; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376358349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376358649; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1376358949; 1; 2599.999626; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376359250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376359550; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 138411.2; 0.0; 7.4; 0.2; 0.13333333333333333 +1376359850; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 160780.53333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1376360150; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376360450; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376360750; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376361050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1376361350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376361650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.4; 0.06666666666666667; 0.0 +1376361950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.4666666666666666; 0.0; 0.0 +1376362250; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376362550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376362849; 1; 2599.999626; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 +1376363149; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1376363449; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 169168.53333333333; 0.06666666666666667; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 +1376363749; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 +1376364049; 1; 2599.999626; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376364349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 +1376364650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 135614.66666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376364950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376365250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1376365550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1376365850; 1; 2599.999626; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376366150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.4666666666666666; 0.0; 0.0 +1376366450; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.06666666666666667; 7.466666666666667; 0.2; 0.13333333333333333 +1376366750; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376367050; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 2.6; 0.4; 0.5333333333333333 +1376367350; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 139809.33333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376367650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376367950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 +1376368250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376368550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376368850; 1; 2599.999626; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 1.6; 0.0; 0.0 +1376369150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376369450; 1; 2599.999626; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.26666666666666666; 0.0 +1376369750; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376370050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 58717.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376370350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376370650; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 142604.0; 0.06666666666666667; 3.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376370950; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.6666666666666666; 0.0 +1376371250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.2; 0.0 +1376371550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376371850; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 167770.13333333333; 0.0; 7.066666666666666; 0.3333333333333333; 0.13333333333333333 +1376372150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 1.2; 0.0; 0.0 +1376372450; 1; 2599.999626; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376372750; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.4; 0.0; 0.0 +1376373050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1376373350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376373651; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1376373951; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376374251; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 163575.46666666667; 0.06666666666666667; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376374551; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 128623.73333333334; 0.0; 1.2; 0.0; 0.0 +1376374851; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376375151; 1; 2599.999626; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376375451; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376375751; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 3.0; 0.13333333333333333; 0.13333333333333333 +1376376051; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 2.066666666666667; 0.06666666666666667; 0.0 +1376376351; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376376651; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 127225.33333333333; 0.0; 1.2; 0.0; 0.0 +1376376951; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 +1376377251; 1; 2599.999626; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376377551; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376377851; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 180353.6; 0.6; 2.6666666666666665; 0.13333333333333333; 0.4666666666666667 +1376378151; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376378451; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 116041.06666666667; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 +1376378751; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376379051; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376379351; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376379651; 1; 2599.999626; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376379951; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 2.0; 0.0; 0.0 +1376380251; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376380551; 1; 2599.999626; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376380851; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376381151; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376381451; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 144003.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376381751; 1; 2599.999626; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1376382051; 1; 2599.999626; 0.0; 0.0; 2097152.0; 138409.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376382351; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1376382651; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 81087.73333333334; 0.0; 1.4; 0.0; 0.0 +1376382951; 1; 2599.999626; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376383251; 1; 2599.999626; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.0; 0.0 +1376383551; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376383851; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.4; 0.0; 0.0 +1376384151; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376384451; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1376384752; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376385052; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1376385352; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376385652; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 95069.06666666667; 0.0; 7.0; 1.0666666666666667; 0.2 +1376385952; 1; 2599.999626; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376386252; 1; 2599.999626; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376386552; 1; 2599.999626; 0.0; 0.0; 2097152.0; 127225.86666666667; 0.0; 1.2; 0.0; 0.0 +1376386852; 1; 2599.999626; 0.0; 0.0; 2097152.0; 132818.4; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376387152; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376387452; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.2; 0.0 +1376387752; 1; 2599.999626; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1376388052; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376388352; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376388652; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 169168.26666666666; 0.0; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 +1376388952; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.2; 0.0; 0.0 +1376389252; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376389552; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.4; 0.0; 0.0 +1376389852; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376390152; 1; 2599.999626; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376390452; 1; 2599.999626; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376390752; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376391052; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376391352; 1; 2599.999626; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376391652; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376391952; 1; 2599.999626; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1376392252; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 191537.33333333334; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376392552; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 163576.0; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1376392853; 1; 2599.999626; 0.0; 0.0; 2097152.0; 138409.6; 0.0; 1.2; 0.13333333333333333; 0.0 +1376393153; 1; 2599.999602; 38.999994029999996; 1.5; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376393453; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 109049.6; 0.0; 1.5333333333333334; 0.0; 0.0 +1376393753; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376394053; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376394353; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 111846.66666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1376394653; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376394953; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 60115.73333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376395253; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1376395552; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376395852; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1376396152; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 103457.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376396452; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376396752; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376397052; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376397352; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376397652; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 97865.33333333333; 0.0; 12.533333333333333; 0.0; 0.0 +1376397952; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376398252; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376398552; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376398853; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 7.2; 7.2; 0.13333333333333333 +1376399153; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 1.4; 0.0; 0.0 +1376399453; 1; 2599.999602; 22.533329884; 0.8666666666666667; 2097152.0; 178955.46666666667; 0.0; 2.6666666666666665; 0.06666666666666667; 0.5333333333333333 +1376399753; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376400053; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376400353; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 74097.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376400653; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 92272.8; 0.0; 1.6666666666666667; 0.0; 0.0 +1376400953; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 2.0; 0.0; 0.0 +1376401253; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 69902.66666666667; 0.0; 1.2; 0.0; 0.0 +1376401553; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376401853; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 130022.4; 0.0; 1.4; 0.0; 0.0 +1376402153; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1376402453; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376402753; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376403053; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 113244.8; 0.0; 3.1333333333333333; 0.0; 0.4666666666666667 +1376403353; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376403653; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376403953; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376404253; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 74097.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1376404553; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.13333333333333333 +1376404853; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376405153; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 65708.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376405453; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376405753; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 106254.13333333333; 0.0; 7.4; 0.2; 0.13333333333333333 +1376406053; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376406353; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1376406653; 1; 2599.999602; 74.53332192399999; 2.8666666666666667; 2097152.0; 630542.1333333333; 161.13333333333333; 23.266666666666666; 0.06666666666666667; 0.8666666666666667 +1376406954; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 369096.8; 0.3333333333333333; 20.2; 0.0; 0.0 +1376407254; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 237674.93333333332; 31.8; 3.933333333333333; 0.0; 0.0 +1376407554; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 141207.46666666667; 4.266666666666667; 2.533333333333333; 0.06666666666666667; 0.0 +1376407854; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.7333333333333334; 0.0; 0.0 +1376408154; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376408454; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376408754; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.5333333333333334; 0.2; 0.0 +1376409054; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376409354; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376409654; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 +1376409954; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376410254; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 149595.46666666667; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376410554; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1376410854; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376411154; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376411454; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1376411754; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 100661.6; 12.733333333333333; 13.466666666666667; 0.3333333333333333; 0.2 +1376412054; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.6666666666666667; 0.0; 0.0 +1376412354; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376412654; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1376412954; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1376413255; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376413555; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376413855; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 138409.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 +1376414155; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 96467.2; 0.0; 1.4666666666666666; 0.0; 0.0 +1376414455; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376414755; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376415055; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376415355; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376415655; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376415955; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376416255; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376416555; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376416855; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 82485.86666666667; 1.0666666666666667; 1.9333333333333333; 0.0; 0.0 +1376417155; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.4666666666666666; 0.0; 0.0 +1376417455; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 195732.26666666666; 0.0; 2.4; 0.0; 0.5333333333333333 +1376417755; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376418055; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376418355; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1376418655; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376418955; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376419255; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376419555; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 1.2; 0.0; 0.0 +1376419855; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 64310.13333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376420155; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 +1376420455; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.6; 0.0; 0.06666666666666667 +1376420755; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376421055; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 202721.86666666667; 0.0; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 +1376421355; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 100661.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1376421655; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376421955; 1; 2599.999602; 45.066659768; 1.7333333333333334; 2097152.0; 360707.73333333334; 161.73333333333332; 14.466666666666667; 0.0; 0.2 +1376422255; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 282414.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1376422555; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 194334.13333333333; 31.8; 3.8666666666666667; 0.0; 0.0 +1376422856; 1; 2599.999602; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376423156; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376423456; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376423756; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1376424056; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376424356; 1; 2599.999602; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1376424656; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 153790.13333333333; 0.06666666666666667; 8.933333333333334; 0.26666666666666666; 0.6 +1376424956; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 +1376425256; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 82485.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376425556; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 +1376425856; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1376426156; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1376426456; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 83884.0; 0.0; 1.4; 0.0; 0.0 +1376426756; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376427056; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.0; 0.06666666666666667; 0.0 +1376427356; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376427656; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.06666666666666667; 0.0 +1376427956; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376428256; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 199926.4; 0.06666666666666667; 3.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376428556; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 163576.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376428856; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376429156; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376429456; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1376429756; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 1.2; 0.0; 0.0 +1376430056; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376430356; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376430656; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376430956; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1376431256; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 121633.6; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376431556; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.2; 0.0; 0.0 +1376431856; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1376432156; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.4; 0.0; 0.0 +1376432456; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 +1376432756; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376433056; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 131419.73333333334; 0.06666666666666667; 2.7333333333333334; 0.0; 0.0 +1376433356; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 137013.06666666668; 0.0; 1.6666666666666667; 0.4666666666666667; 0.13333333333333333 +1376433656; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 +1376433956; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376434256; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376434556; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376434856; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376435156; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 103457.86666666667; 0.0; 1.6; 0.0; 0.0 +1376435456; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 178955.46666666667; 0.13333333333333333; 3.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376435756; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376436056; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 1.2; 0.0; 0.0 +1376436356; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.4; 0.0; 0.0 +1376436656; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376436956; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376437256; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 +1376437556; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.06666666666666667; 7.8; 0.3333333333333333; 0.13333333333333333 +1376437856; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376438156; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376438456; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376438756; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1376439056; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 197130.4; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376439356; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 1.2; 0.0; 0.0 +1376439656; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376439956; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.2; 0.0 +1376440256; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 67106.4; 0.0; 1.8; 0.0; 0.0 +1376440557; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 69902.66666666667; 0.0; 1.4; 0.0; 0.0 +1376440857; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1376441157; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 12.0; 0.06666666666666667; 0.0 +1376441457; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376441757; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1376442057; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 134216.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376442357; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1376442657; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 180353.6; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1376442957; 1; 2599.99945; 31.777771055555554; 1.2222222222222223; 2097152.0; 97865.33333333333; 0.0; 0.625; 0.0; 0.0 +1376443257; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 156585.33333333334; 0.0; 7.2; 0.3333333333333333; 0.13333333333333333 +1376443557; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 146800.0; 0.0; 1.2; 0.0; 0.0 +1376443857; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1376444157; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 114642.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376444457; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 148197.33333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1376444757; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 1.4666666666666666; 0.0; 0.0 +1376445057; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376445357; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376445657; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 96467.2; 0.0; 1.8666666666666667; 10.933333333333334; 0.0 +1376445957; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376446257; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 134216.0; 0.0; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 +1376446557; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376446857; 1; 2599.99945; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376447157; 1; 2599.99945; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376447457; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 141206.66666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1376447757; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 153789.6; 0.0; 1.2; 0.13333333333333333; 0.0 +1376448057; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376448357; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376448657; 1; 2599.99945; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376448957; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 103457.86666666667; 0.0; 1.6; 0.3333333333333333; 0.0 +1376449257; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1376449558; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376449858; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 152390.93333333332; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1376450158; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 137012.8; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1376450458; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376450758; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376451058; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376451358; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376451658; 1; 2599.99945; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1376451958; 1; 2599.99945; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.4; 0.0; 0.0 +1376452258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376452558; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376452858; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376453158; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1376453458; 1; 2599.99945; 13.866663733333333; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.6; 0.2; 0.4666666666666667 +1376453758; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 104856.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376454058; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376454358; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 +1376454658; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376454958; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1376455258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376455558; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 89476.53333333334; 0.0; 6.933333333333334; 0.3333333333333333; 0.2 +1376455858; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 116041.06666666667; 0.0; 2.1333333333333333; 0.0; 0.0 +1376456158; 1; 2599.99945; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1376456458; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376456758; 1; 2599.99945; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1376457058; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1376457359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376457659; 1; 2599.99945; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376457959; 1; 2599.99945; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376458259; 1; 2599.99945; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376458559; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.5333333333333334; 0.06666666666666667; 0.0 +1376458859; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376459159; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376459459; 1; 2599.99945; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376459759; 1; 2599.99945; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376460059; 1; 2599.99945; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.4; 0.0; 0.0 +1376460359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.3333333333333333; 1.6; 0.0 +1376460659; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 150993.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 +1376460959; 1; 2599.99945; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376461258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1376461558; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 75495.2; 0.06666666666666667; 6.8; 0.26666666666666666; 0.2 +1376461858; 1; 2599.99945; 124.79997359999999; 4.8; 2097152.0; 524285.86666666664; 161.46666666666667; 170.26666666666668; 20.866666666666667; 1.0666666666666667 +1376462158; 1; 2599.99945; 17.333329666666668; 0.6666666666666667; 2097152.0; 541063.2; 5.066666666666666; 12.2; 0.13333333333333333; 0.06666666666666667 +1376462458; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 243267.2; 31.8; 4.6; 0.06666666666666667; 0.0 +1376462758; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 187343.2; 0.0; 2.8666666666666667; 0.0; 0.0 +1376463059; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1376463359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1376463659; 1; 2599.99945; 20.7999956; 0.8; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1376463959; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376464259; 1; 2599.999602; 28.599995622; 1.1; 2097152.0; 188740.0; 0.0; 1.4444444444444444; 0.1111111111111111; 0.0 +1376464559; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 125827.46666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1376464859; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1376465159; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376465459; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376465759; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376466059; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376466359; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 125828.0; 0.0; 1.6; 0.0; 0.0 +1376466659; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 +1376466959; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376467259; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 107651.46666666666; 0.0; 1.2; 0.0; 0.0 +1376467559; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376467859; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 152391.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1376468159; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376468459; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 131420.53333333333; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 +1376468759; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376469059; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376469359; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376469659; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.6; 0.0; 0.0 +1376469959; 1; 2599.999602; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376470259; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376470559; 1; 2599.999602; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376470859; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.3333333333333333; 0.9333333333333333; 0.0 +1376471159; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376471459; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 159381.6; 0.06666666666666667; 2.8; 0.13333333333333333; 0.4666666666666667 +1376471759; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1376472059; 1; 2599.999602; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.2; 0.0; 0.0 +1376472359; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 1.4; 0.0; 0.0 +1376472659; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376472959; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 150993.6; 20.6; 2.2666666666666666; 0.0; 0.06666666666666667 +1376473260; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 114642.93333333333; 0.0; 4.2; 0.0; 0.0 +1376473560; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 110448.53333333334; 0.0; 2.933333333333333; 0.0; 0.0 +1376473860; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 142604.53333333333; 12.733333333333333; 13.666666666666666; 0.26666666666666666; 0.13333333333333333 +1376474160; 1; 2599.999602; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376474460; 1; 2599.999602; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376474760; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376475060; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 162177.86666666667; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376475360; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1376475660; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376475960; 1; 2599.999602; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376476260; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1376476560; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376476860; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376477160; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376477460; 1; 2599.999602; 0.0; 0.0; 2097152.0; 148197.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1376477760; 1; 2599.99945; 31.199993399999997; 1.2; 2097152.0; 134216.8; 0.0; 1.2222222222222223; 0.0; 0.0 +1376478060; 1; 2599.99945; 13.866663733333333; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1376478360; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376478660; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 174760.0; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1376478960; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 121632.8; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376479260; 1; 2599.99945; 17.333329666666668; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.6; 0.06666666666666667; 0.0 +1376479560; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376479860; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1376480160; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 124429.06666666667; 0.0; 1.2; 0.0; 0.0 +1376480460; 1; 2599.999343; 37.55554606555556; 1.4444444444444446; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1376480760; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.8; 0.06666666666666667; 0.0 +1376481060; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376481360; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376481660; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376481960; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 +1376482261; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 142604.0; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1376482561; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376482861; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1376483161; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376483461; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.6; 0.0; 0.0 +1376483761; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.2; 0.0; 0.0 +1376484061; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 1.2; 0.0; 0.0 +1376484361; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376484661; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376484961; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 79689.6; 0.0; 12.266666666666667; 0.0; 0.0 +1376485261; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142605.6; 0.06666666666666667; 7.6; 0.2; 0.13333333333333333 +1376485561; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130021.6; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376485861; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 166371.46666666667; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 +1376486161; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 113244.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376486461; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376486761; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376487061; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1376487361; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376487661; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130021.6; 0.0; 1.6; 0.0; 0.0 +1376487961; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376488261; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376488561; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376488861; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.8; 1.8; 1.5333333333333334; 0.0; 0.06666666666666667 +1376489161; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376489461; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1376489761; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376490061; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.8; 0.06666666666666667; 0.0 +1376490362; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 +1376490662; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376490962; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 130022.4; 0.0; 7.6; 0.26666666666666666; 0.26666666666666666 +1376491262; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376491562; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376491862; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125827.2; 0.0; 1.3333333333333333; 0.13333333333333333; 0.0 +1376492162; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376492462; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 +1376492762; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376493062; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 162177.86666666667; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376493362; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121632.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376493662; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376493962; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 2.4; 0.0 +1376494261; 1; 2599.999309; 25.999993089999997; 1.0; 2097152.0; 71300.8; 0.0; 1.1111111111111112; 0.0; 0.0 +1376494561; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376494861; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376495161; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1376495461; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376495761; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1376496061; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376496362; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376496662; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 163575.2; 0.2; 2.8666666666666667; 0.13333333333333333; 0.5333333333333333 +1376496962; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 7.466666666666667; 0.3333333333333333; 0.13333333333333333 +1376497262; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 120235.46666666666; 0.0; 1.6; 0.0; 0.0 +1376497562; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 72698.93333333333; 0.0; 1.2; 0.0; 0.0 +1376497862; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376498162; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376498462; 1; 2599.999297; 29.249992091249997; 1.125; 2097152.0; 76019.5; 0.0; 1.0; 0.0; 0.0 +1376498762; 1; 2599.999297; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376499062; 1; 2599.999297; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376499362; 1; 2599.999297; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376499662; 1; 2599.999297; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376499962; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.4; 0.0; 0.0 +1376500262; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 152391.2; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376500562; 1; 2599.999297; 0.0; 0.0; 2097152.0; 117438.93333333333; 0.0; 1.2; 0.2; 0.0 +1376500862; 1; 2599.999297; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376501162; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 143.66666666666666; 0.0 +1376501462; 1; 2599.999297; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376501762; 1; 2599.999297; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 +1376502062; 1; 2599.999297; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.4; 0.0; 0.0 +1376502362; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376502662; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 8.4; 0.0 +1376502962; 1; 2599.999297; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1376503263; 1; 2599.999297; 0.0; 0.0; 2097152.0; 113244.26666666666; 0.0; 1.2; 0.0; 0.0 +1376503563; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 138410.93333333332; 0.0; 7.466666666666667; 0.2; 0.13333333333333333 +1376503863; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 169168.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1376504163; 1; 2599.999297; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 1.6; 0.0; 0.0 +1376504463; 1; 2599.999297; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376504763; 1; 2599.999297; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376505063; 1; 2599.999297; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.2; 0.0; 0.0 +1376505363; 1; 2599.999297; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376505663; 1; 2599.999297; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376505963; 1; 2599.999297; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 1.2; 0.0; 0.0 +1376506263; 1; 2599.999297; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376506563; 1; 2599.999297; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376506863; 1; 2599.999297; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.4; 0.0; 0.0 +1376507163; 1; 2599.999297; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376507463; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 162177.86666666667; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 +1376507763; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376508063; 1; 2599.999297; 317.19991423399995; 12.2; 2097152.0; 437603.2; 907.8; 1409.7333333333333; 246.6; 7.866666666666666 +1376508363; 1; 2599.999297; 109.199970474; 4.2; 2097152.0; 829071.7333333333; 1.4666666666666666; 6.466666666666667; 0.0; 0.13333333333333333 +1376508663; 1; 2599.999304; 31.199991648; 1.2; 2097152.0; 419428.0; 0.0; 1.7777777777777777; 0.0; 0.0 +1376508963; 1; 2599.999304; 34.66665738666667; 1.3333333333333335; 2097152.0; 321561.86666666664; 0.8; 5.0; 0.0; 0.06666666666666667 +1376509263; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 223693.33333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376509563; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376509863; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.13333333333333333; 0.0 +1376510163; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376510463; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376510763; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376511064; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 201324.8; 17.266666666666666; 2.6; 0.06666666666666667; 0.4666666666666667 +1376511364; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376511664; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376511964; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376512264; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376512564; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376512864; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376513164; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1376513464; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376513764; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1376514064; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1376514364; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376514664; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1376514964; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376515264; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376515564; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376515864; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376516164; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376516464; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376516764; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1376517064; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376517365; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121632.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376517665; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8; 0.0; 0.0 +1376517965; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376518265; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163576.0; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1376518565; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376518865; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376519165; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 +1376519465; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 2.7333333333333334; 1.2; 0.0; 0.0 +1376519765; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.06666666666666667 +1376520065; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1376520365; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376520665; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1376520965; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376521265; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376521565; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 141206.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376521865; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 164974.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376522165; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1376522465; 1; 2599.999304; 136.93329667733332; 5.266666666666667; 2097152.0; 171964.0; 161.86666666666667; 14.466666666666667; 0.0; 0.0 +1376522765; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 289404.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376523065; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 170567.46666666667; 31.8; 3.7333333333333334; 0.0; 0.0 +1376523365; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 226490.4; 0.0; 0.8; 0.0; 0.0 +1376523665; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376523965; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376524265; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 7.0; 0.2; 0.13333333333333333 +1376524565; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 146798.4; 0.0; 0.8; 0.0; 0.0 +1376524865; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376525165; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1376525465; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 159380.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376525765; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 +1376526065; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 0.8; 0.0; 0.0 +1376526365; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376526665; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.6666666666666666; 1.1333333333333333; 0.0; 0.0 +1376526965; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1376527265; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376527565; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376527865; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376528165; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376528465; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 86680.26666666666; 0.0; 11.666666666666666; 0.0; 0.0 +1376528765; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 142604.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376529065; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163576.0; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1376529365; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376529666; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376529966; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376530266; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.26666666666; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 +1376530566; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1376530866; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 159382.4; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1376531166; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376531466; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376531766; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1376532066; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376532366; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376532666; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163575.73333333334; 0.0; 2.066666666666667; 0.0; 0.5333333333333333 +1376532966; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 +1376533266; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376533566; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376533866; 1; 2599.999304; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376534166; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376534466; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.6; 0.0; 0.0 +1376534766; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376535066; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376535366; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376535666; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376535966; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1376536266; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 199926.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376536566; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 128624.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376536866; 1; 2599.999304; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1376537166; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376537466; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376537766; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.2 +1376538066; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.8; 0.0; 0.8; 0.0; 0.0 +1376538366; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 +1376538666; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376538967; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 174761.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376539267; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117438.13333333333; 0.0; 0.6; 0.0; 0.0 +1376539567; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1376539867; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 174760.53333333333; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1376540167; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376540466; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376540766; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376541066; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376541366; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376541666; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1376541966; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1376542267; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376542567; 1; 2599.999304; 0.0; 0.0; 2097152.0; 148196.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376542867; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1376543167; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376543467; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 188741.33333333334; 0.06666666666666667; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376543767; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.33333333334; 0.0; 6.8; 0.2; 0.13333333333333333 +1376544067; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1376544367; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376544667; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376544967; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1376545267; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376545567; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376545867; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376546167; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376546467; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376546767; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376547067; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 166371.73333333334; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376547367; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 131420.26666666666; 0.0; 0.8; 0.0; 0.0 +1376547667; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376547967; 1; 2599.999304; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 0.6; 0.0; 0.0 +1376548267; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1376548567; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 1.9333333333333333; 0.0; 0.0 +1376548867; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376549167; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376549467; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376549767; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1376550067; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 153789.06666666668; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376550367; 1; 2599.999304; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376550667; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 192936.0; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376550968; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.53333333333; 0.0; 0.6; 0.0; 0.0 +1376551268; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376551568; 1; 2599.999304; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6; 0.0; 0.0 +1376551868; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376552168; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376552468; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1376552768; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.6; 0.0; 0.0 +1376553068; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376553368; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376553668; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376553968; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.7333333333333333; 1.9333333333333333; 1.2; 0.0 +1376554268; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 159381.86666666667; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1376554568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155187.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376554868; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376555168; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1376555468; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376555768; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376556068; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1376556368; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 141207.46666666667; 0.0; 6.8; 0.2; 0.13333333333333333 +1376556668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 150993.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376556968; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376557268; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 1.5333333333333334; 1.4666666666666666; 0.0; 0.0 +1376557568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376557868; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 176159.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376558168; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1376558468; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376558768; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376559068; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376559368; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376559668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1376559968; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376560268; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376560568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376560868; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376561168; 1; 2599.999304; 0.0; 0.0; 2097152.0; 134215.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376561468; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 132818.4; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376561768; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376562068; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 7.2; 0.26666666666666666; 0.13333333333333333 +1376562368; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376562668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376562968; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376563269; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376563569; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376563869; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376564169; 1; 2599.999304; 195.86661423466666; 7.533333333333334; 2097152.0; 359310.4; 162.26666666666668; 117.66666666666667; 0.0; 0.4 +1376564469; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 655707.7333333333; 0.0; 6.0; 0.06666666666666667; 0.0 +1376564769; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 292200.8; 31.8; 3.466666666666667; 0.0; 0.0 +1376565069; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 255850.4; 18.0; 3.933333333333333; 0.7333333333333333; 0.4666666666666667 +1376565369; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 169168.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1376565669; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1376565969; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376566269; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.33333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376566569; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376566869; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1376567169; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376567469; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376567769; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376568069; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376568369; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376568669; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 211111.2; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376568969; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 149595.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376569269; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1376569569; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376569869; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1376570169; 1; 2599.999304; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376570469; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1376570769; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376571069; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376571369; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.3333333333333333; 0.0 +1376571669; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376571969; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 11.6; 0.0; 0.0 +1376572269; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 141207.2; 1.0; 3.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376572569; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376572869; 1; 2599.999304; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1376573169; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376573469; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1376573769; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376574069; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376574369; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376574669; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1376574969; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376575269; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376575569; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 +1376575869; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163576.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376576169; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.0; 0.06666666666666667; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1376576469; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 0.8; 0.13333333333333333; 0.0 +1376576769; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.3333333333333333; 0.0 +1376577069; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.8; 0.06666666666666667 +1376577369; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376577669; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376577970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376578270; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1376578570; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117438.4; 0.0; 0.6; 0.0; 0.0 +1376578870; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.8; 0.0; 0.0 +1376579170; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1376579470; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 155188.0; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376579770; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376580070; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.6; 0.0; 0.0 +1376580370; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376580670; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 141206.66666666666; 0.0; 0.6; 0.0; 0.0 +1376580970; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376581270; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376581570; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 7.4; 0.3333333333333333; 0.13333333333333333 +1376581870; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1376582170; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376582470; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376582770; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376583070; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 192936.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376583370; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376583670; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376583970; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1376584270; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376584570; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376584870; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376585170; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376585470; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 2.8; 0.0 +1376585770; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376586070; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 +1376586370; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142604.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376586670; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 176159.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376586970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376587270; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376587571; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1376587871; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376588171; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376588471; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 145401.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376588771; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376589071; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1376589371; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376589670; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376589970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1376590270; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 150993.6; 0.2; 2.0; 0.06666666666666667; 0.4666666666666667 +1376590570; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376590870; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1376591170; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376591470; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376591771; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376592071; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376592371; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 62912.0; 0.0; 0.5333333333333333; 0.13333333333333333; 0.0 +1376592671; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376592971; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376593271; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376593571; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 +1376593871; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 170565.86666666667; 0.0; 8.2; 0.26666666666666666; 0.6666666666666666 +1376594171; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376594471; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 79689.6; 0.0; 0.6; 0.0; 0.0 +1376594771; 1; 2599.999304; 65.86664903466666; 2.533333333333333; 2097152.0; 329950.13333333336; 161.73333333333332; 22.933333333333334; 0.0; 0.2 +1376595071; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 486536.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1376595371; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 174760.8; 31.8; 3.6666666666666665; 0.0; 0.0 +1376595671; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 135614.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376595971; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376596271; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121633.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376596571; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376596871; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1376597171; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376597471; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 190138.66666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.5333333333333333 +1376597771; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376598071; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1376598371; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376598671; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376598971; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376599271; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376599571; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 159381.6; 12.733333333333333; 13.0; 0.4; 0.13333333333333333 +1376599871; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376600171; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376600471; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376600771; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376601072; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 156586.13333333333; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1376601372; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376601672; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376601972; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 145401.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376602272; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1376602572; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1376602872; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1376603172; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1376603472; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376603772; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1376604072; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376604372; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376604672; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 220897.6; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376604972; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 7.266666666666667; 0.3333333333333333; 0.13333333333333333 +1376605272; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376605572; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376605872; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 2.6666666666666665; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1376606172; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1376606472; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376606772; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1376607072; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376607372; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376607672; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376607972; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1376608272; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1376608572; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376608872; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376609172; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376609472; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376609772; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 62912.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376610072; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1376610372; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376610672; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376610972; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1376611272; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376611572; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376611872; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 201324.53333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376612172; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1376612472; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376612772; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376613072; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 92272.8; 0.6; 1.2; 0.0; 0.0 +1376613372; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1376613672; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1376613972; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 125827.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376614272; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1376614572; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376614872; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376615172; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376615472; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 170565.86666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376615772; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 11.733333333333333; 0.06666666666666667; 0.0 +1376616072; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376616372; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376616672; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376616973; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376617273; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376617573; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376617873; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1376618173; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376618473; 1; 2599.999304; 71.06664764266665; 2.733333333333333; 2097152.0; 571821.6; 166.6; 21.533333333333335; 0.06666666666666667; 0.4 +1376618773; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 569025.0666666667; 0.0; 2.466666666666667; 0.0; 0.0 +1376619073; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 293599.4666666667; 31.866666666666667; 5.466666666666667; 0.06666666666666667; 0.5333333333333333 +1376619373; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 197130.93333333332; 0.0; 2.2666666666666666; 0.0; 0.0 +1376619673; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 139808.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376619973; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376620273; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 4.333333333333333; 0.0; 0.0 +1376620573; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376620873; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376621173; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 132818.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376621473; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 109049.86666666667; 0.0; 0.6; 0.0; 0.0 +1376621773; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376622073; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376622373; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376622673; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 146798.93333333332; 0.2; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376622973; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 0.8; 0.0; 0.0 +1376623273; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1376623573; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376623873; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 100661.6; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1376624173; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376624473; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376624773; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376625073; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376625373; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376625673; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 1.4666666666666666; 1.0; 0.06666666666666667; 0.06666666666666667 +1376625973; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376626273; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 104856.0; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376626573; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376626873; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376627173; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376627473; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376627773; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376628073; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1376628373; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376628673; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376628973; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 150993.6; 0.0; 0.6; 0.0; 0.0 +1376629273; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376629573; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376629873; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 139808.8; 0.0; 8.2; 0.26666666666666666; 0.6 +1376630173; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 152391.46666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376630474; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376630774; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1376631074; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1376631374; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376631674; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376631974; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376632274; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1376632574; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.06666666666666667; 0.0 +1376632874; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376633174; 1; 2599.999304; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376633474; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 173362.93333333332; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376633774; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376634074; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376634374; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376634674; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.06666666666666667 +1376634974; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 2.066666666666667; 0.0; 0.0 +1376635274; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1376635574; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376635874; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376636174; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376636474; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376636774; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376637074; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 157983.46666666667; 0.6; 8.666666666666666; 0.3333333333333333; 0.6666666666666666 +1376637374; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376637674; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376637974; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376638274; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376638574; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376638874; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376639174; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376639474; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376639774; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376640074; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376640374; 1; 2599.999304; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376640674; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1376640974; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1376641275; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376641575; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376641875; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376642175; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376642475; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376642775; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1376643075; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376643375; 1; 2599.999304; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376643675; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1376643975; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376644275; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 155187.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376644575; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1376644875; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376645175; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376645475; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 2.2666666666666666; 0.0 +1376645775; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376646075; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1376646375; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376646675; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376646975; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376647275; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376647575; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376647875; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 209713.6; 0.0; 2.2; 0.0; 0.4666666666666667 +1376648175; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376648475; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376648775; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376649075; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376649375; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1376649675; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376649975; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 +1376650276; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 +1376650576; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376650876; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376651176; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376651476; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 170566.66666666666; 0.0; 2.2; 0.0; 0.4666666666666667 +1376651776; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376652076; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 2.933333333333333; 0.0 +1376652376; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376652676; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376652976; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.6; 4.933333333333334; 0.0 +1376653276; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376653576; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121632.8; 0.0; 1.2; 0.0; 0.0 +1376653876; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376654176; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.6666666666666666; 0.0 +1376654476; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376654776; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376655076; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 157983.46666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376655376; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1376655676; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 62912.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376655976; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376656276; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376656576; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376656876; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376657176; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 1.3333333333333333; 0.0 +1376657476; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 1.5333333333333334; 0.0 +1376657776; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.3333333333333333; 0.0 +1376658076; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.6; 0.0 +1376658376; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.7333333333333333; 0.0 +1376658676; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 188741.6; 0.06666666666666667; 2.4; 0.4; 0.5333333333333333 +1376658976; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 139809.06666666668; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1376659276; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 11.533333333333333; 0.0; 0.0 +1376659576; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376659876; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376660176; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376660476; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376660776; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376661076; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142604.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376661376; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376661676; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.13333333333333333; 0.0 +1376661976; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1376662276; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 198528.53333333333; 12.733333333333333; 14.733333333333333; 0.4; 0.6 +1376662576; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 169169.06666666668; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376662876; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376663176; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 57319.46666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1376663476; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 62912.0; 0.0; 0.8; 0.2; 0.13333333333333333 +1376663777; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376664077; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376664377; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 121632.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376664677; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376664977; 1; 2599.999304; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1376665277; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1376665577; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1376665877; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 171964.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376666177; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376666477; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 +1376666777; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376667077; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376667377; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376667677; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1376667977; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.7333333333333334; 0.0; 0.0 +1376668277; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1376668577; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376668877; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376669177; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 118837.33333333333; 0.0; 7.2; 0.2; 0.13333333333333333 +1376669477; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 169168.53333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376669777; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 131420.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376670077; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376670377; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376670677; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1376670977; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1376671277; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376671577; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376671878; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376672178; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1376672478; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 146799.2; 0.0; 0.6; 0.0; 0.0 +1376672778; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376673078; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 195732.26666666666; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376673378; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376673678; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376673978; 1; 2599.999304; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376674278; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376674578; 1; 2599.999304; 25.99999304; 1.0; 2097152.0; 155188.26666666666; 161.06666666666666; 27.466666666666665; 0.4; 0.5333333333333333 +1376674878; 1; 2599.999304; 48.53332034133333; 1.8666666666666665; 2097152.0; 722816.5333333333; 0.0; 2.6; 0.0; 0.0 +1376675178; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 324357.86666666664; 31.8; 3.0; 0.06666666666666667; 0.0 +1376675478; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 174760.8; 0.0; 2.4; 0.0; 0.0 +1376675778; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 187343.73333333334; 0.0; 1.7333333333333334; 0.0; 0.0 +1376676078; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.13333333333; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376676378; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376676678; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 156585.33333333334; 0.0; 2.0; 0.13333333333333333; 0.4666666666666667 +1376676978; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376677278; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376677578; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376677878; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.6; 0.13333333333333333; 0.0 +1376678178; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.06666666666666667; 0.0 +1376678478; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376678778; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376679078; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142605.6; 0.0; 0.6; 0.0; 0.0 +1376679378; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.06666666666666667; 0.0 +1376679679; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.5333333333333333; 0.13333333333333333; 0.0 +1376679979; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376680279; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 183149.86666666667; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376680579; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 142605.6; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1376680879; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 164973.33333333334; 0.0; 0.6; 0.0; 0.0 +1376681179; 1; 2599.999304; 43.333321733333335; 1.6666666666666665; 2097152.0; 267036.26666666666; 161.0; 14.466666666666667; 0.0; 0.2 +1376681479; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 459973.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376681779; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 187344.0; 31.8; 3.466666666666667; 0.0; 0.0 +1376682079; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376682379; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376682679; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376682979; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376683279; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376683579; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376683879; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 150994.4; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376684179; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.06666666666666667; 1.6666666666666667; 0.0; 0.0 +1376684479; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376684779; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376685079; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376685379; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 149595.73333333334; 0.0; 1.0; 0.0; 0.0 +1376685679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376685979; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376686279; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376686579; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1376686879; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1376687179; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 145401.33333333334; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1376687479; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 192935.73333333334; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376687779; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376688079; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376688379; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376688679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376688979; 1; 2599.999304; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376689279; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1376689579; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 65708.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376689879; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376690179; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 62912.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376690479; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376690779; 1; 2599.999304; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376691079; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 187342.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1376691379; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137012.8; 0.0; 0.8; 0.0; 0.0 +1376691679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376691979; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376692279; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.13333333333333333 +1376692579; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 156586.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376692879; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376693179; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 137012.26666666666; 0.06666666666666667; 7.466666666666667; 0.2; 0.13333333333333333 +1376693480; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376693780; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376694080; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.2; 0.06666666666666667 +1376694380; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376694680; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376694980; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376695280; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376695580; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376695880; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376696180; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376696480; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 174760.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376696780; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 146800.0; 0.0; 1.0; 0.0; 0.0 +1376697080; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 +1376697380; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1376697680; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376697980; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376698280; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.0; 0.06666666666666667; 0.5333333333333333 +1376698580; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.5333333333333333; 0.0; 0.0 +1376698880; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1376699180; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 124429.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376699480; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1376699780; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376700080; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 +1376700380; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376700680; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376700980; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376701280; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376701581; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376701881; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 198529.06666666668; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376702181; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376702481; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376702781; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376703081; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 171964.53333333333; 0.0; 11.666666666666666; 0.0; 0.0 +1376703381; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376703681; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376703981; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376704281; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376704581; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376704881; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1376705181; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376705481; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 146799.2; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376705781; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 145401.06666666668; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1376706081; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376706381; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376706681; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376706981; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376707281; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376707581; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.4; 0.0 +1376707881; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 124429.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376708181; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376708481; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376708781; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376709081; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 159383.2; 0.06666666666666667; 2.2666666666666666; 1.0666666666666667; 0.5333333333333333 +1376709381; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 0.6; 0.0; 0.0 +1376709681; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376709981; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376710281; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376710581; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376710881; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376711181; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376711481; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376711781; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376712082; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 86680.26666666666; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1376712382; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.6; 0.06666666666666667; 0.0 +1376712682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1376712982; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376713282; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376713582; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376713882; 1; 2599.999304; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1376714182; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376714482; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376714782; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376715082; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376715382; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376715682; 1; 2599.999304; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 +1376715982; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1376716282; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 150993.06666666668; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376716582; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376716882; 1; 2599.999304; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376717182; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376717482; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1376717782; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376718082; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376718382; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 190138.93333333332; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1376718682; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.06666666666666667; 0.0 +1376718982; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376719282; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117437.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376719582; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376719882; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 187343.2; 0.2; 2.466666666666667; 0.0; 0.5333333333333333 +1376720182; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376720482; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376720782; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376721082; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376721382; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.2666666666666666; 0.26666666666666666; 0.13333333333333333 +1376721682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 1.4666666666666666; 0.13333333333333333; 0.0 +1376721982; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376722282; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 0.6; 0.0; 0.0 +1376722582; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.8; 3.7333333333333334; 0.0 +1376722882; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376723182; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376723482; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 173362.13333333333; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376723782; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 134216.8; 12.733333333333333; 17.0; 0.3333333333333333; 0.2 +1376724082; 1; 2599.999304; 60.66665042666666; 2.3333333333333335; 2097152.0; 279618.6666666667; 161.0; 22.133333333333333; 0.06666666666666667; 0.4 +1376724382; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 763362.4; 0.0; 2.7333333333333334; 0.06666666666666667; 0.0 +1376724682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 348124.8; 31.8; 3.533333333333333; 0.0; 0.0 +1376724982; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 188741.6; 0.0; 2.3333333333333335; 0.0; 0.0 +1376725282; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 +1376725582; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1376725882; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376726182; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376726482; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376726782; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376727082; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 181750.93333333332; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376727382; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1376727682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376727982; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376728282; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.2; 0.0 +1376728583; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376728883; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376729183; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376729483; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376729783; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376730083; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 7.0; 0.3333333333333333; 0.13333333333333333 +1376730383; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376730683; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 166372.0; 0.06666666666666667; 2.4; 0.13333333333333333; 0.4666666666666667 +1376730983; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376731283; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376731583; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376731883; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376732183; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376732483; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376732783; 1; 2599.999304; 0.0; 0.0; 2097152.0; 100660.8; 0.0; 1.0; 0.0; 0.0 +1376733083; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376733383; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376733683; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376733983; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376734283; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184547.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376734583; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376734883; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 64310.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376735184; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376735484; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 7.866666666666666; 0.0 +1376735784; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376736084; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 144002.93333333332; 0.0; 7.533333333333333; 0.2; 0.13333333333333333 +1376736384; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155188.0; 0.0; 0.8; 0.13333333333333333; 0.0 +1376736684; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1376736984; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376737284; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.2; 0.0 +1376737584; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376737884; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 160779.46666666667; 0.0; 2.466666666666667; 0.2; 0.5333333333333333 +1376738184; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376738484; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376738784; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376739084; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376739384; 1; 2599.999304; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376739684; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376739984; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376740284; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376740584; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1376740884; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376741184; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1376741484; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 171964.8; 0.0; 2.2; 0.13333333333333333; 0.4666666666666667 +1376741784; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376742084; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1376742384; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 6.866666666666666; 0.3333333333333333; 0.2 +1376742684; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376742984; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376743284; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376743584; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376743885; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376744185; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376744485; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376744785; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376745085; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.3333333333333335; 0.2; 0.4666666666666667 +1376745385; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376745685; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376745985; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376746285; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376746585; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 11.6; 0.13333333333333333; 0.0 +1376746885; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1376747185; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376747485; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376747785; 1; 2599.999304; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1376748085; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376748385; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.2; 0.13333333333333333 +1376748685; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 167769.86666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376748985; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138411.2; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1376749285; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376749585; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376749885; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.06666666666666667; 1.0666666666666667; 0.06666666666666667; 0.13333333333333333 +1376750185; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 128624.26666666666; 0.06666666666666667; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1376750485; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376750785; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376751085; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376751385; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1376751685; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376751985; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376752285; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 141207.46666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376752586; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376752886; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376753186; 1; 2599.999304; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376753485; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376753785; 1; 2599.999304; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376754085; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376754385; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376754685; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 81087.73333333334; 0.0; 7.2; 0.2; 0.13333333333333333 +1376754985; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376755285; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376755585; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376755885; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 155188.26666666666; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1376756185; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 124429.6; 0.0; 0.8; 0.0; 0.0 +1376756485; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125826.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376756785; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95068.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1376757085; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.4; 0.0; 0.0 +1376757385; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376757685; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376757985; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376758285; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 155188.8; 0.0; 0.6; 0.0; 0.0 +1376758585; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1376758885; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 65708.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376759186; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376759486; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 169168.8; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376759786; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125827.73333333334; 0.0; 1.0; 0.0; 0.0 +1376760086; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376760386; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 117438.66666666667; 0.0; 6.6; 0.2; 0.13333333333333333 +1376760686; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117438.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376760986; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376761286; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 125827.2; 0.0; 1.0; 0.0; 0.0 +1376761586; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376761886; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376762186; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376762486; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.06666666666666667 +1376762786; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1376763086; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 198528.8; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376763386; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 125827.73333333334; 0.0; 0.8; 0.0; 0.0 +1376763686; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376763986; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.5333333333333333; 0.0; 0.0 +1376764286; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376764586; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376764886; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376765186; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376765486; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376765786; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376766086; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376766386; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 139808.53333333333; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1376766686; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 185944.53333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376766986; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376767286; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138411.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1376767586; 1; 2599.999304; 45.06665460266667; 1.7333333333333334; 2097152.0; 166371.73333333334; 161.2; 14.133333333333333; 0.0; 0.2 +1376767886; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 432010.93333333335; 0.0; 1.2; 0.0; 0.0 +1376768187; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 177556.53333333333; 31.8; 3.4; 0.0; 0.0 +1376768487; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184546.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1376768787; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376769087; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376769387; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376769687; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1376769987; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376770287; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 155188.0; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376770587; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376770887; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376771187; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376771487; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376771787; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376772087; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376772387; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1376772687; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1376772987; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 117438.4; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1376773287; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376773587; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376773887; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 180352.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376774187; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376774487; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376774787; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1376775087; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376775387; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376775687; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376775988; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376776288; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376776588; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376776891; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376777191; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376777491; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 149594.4; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376777791; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 +1376778091; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376778391; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376778691; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1376778991; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 +1376779291; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376779591; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376779891; 1; 2599.999304; 46.799987472000005; 1.8; 2097152.0; 153789.6; 161.46666666666667; 27.933333333333334; 0.3333333333333333; 0.6 +1376780191; 1; 2599.999304; 34.66665738666667; 1.3333333333333335; 2097152.0; 735398.9333333333; 0.0; 2.4; 0.0; 0.0 +1376780491; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 290802.93333333335; 31.8; 3.3333333333333335; 0.0; 0.0 +1376780791; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 178954.4; 0.0; 2.3333333333333335; 0.0; 0.0 +1376781091; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184547.73333333334; 0.06666666666666667; 3.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376781391; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376781691; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376781991; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1376782291; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.6; 0.06666666666666667; 1.0666666666666667; 0.0; 0.0 +1376782591; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130021.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376782891; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376783191; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 137012.53333333333; 0.0; 1.2; 0.0; 0.0 +1376783491; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 164973.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376783791; 1; 2599.999304; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376784091; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376784392; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1376784692; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 156586.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376784992; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1376785292; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376785592; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376785892; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376786191; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 134216.8; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1376786491; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 134216.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376786791; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376787091; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376787391; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376787691; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1376787991; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376788291; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 131419.73333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 +1376788591; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376788891; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376789191; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376789491; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376789791; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376790092; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376790392; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 127225.6; 0.0; 12.0; 0.0; 0.0 +1376790692; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376790992; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376791292; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376791592; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1376791892; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376792192; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376792492; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 114642.93333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376792792; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376793092; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376793392; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376793692; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 +1376793992; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376794292; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376794592; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376794892; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1376795192; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376795492; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 159380.8; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1376795792; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1376796092; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 78291.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376796392; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1376796692; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 128623.46666666666; 0.0; 0.6; 0.0; 0.0 +1376796992; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.0; 0.0 +1376797292; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376797592; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 145401.86666666667; 0.0; 1.2; 0.0; 0.0 +1376797892; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376798193; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1376798493; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376798793; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376799093; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 185945.33333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376799393; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376799693; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1376799993; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1376800293; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376800593; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376800893; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376801193; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376801493; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 76893.33333333333; 0.0; 1.6; 0.0; 0.0 +1376801793; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.5333333333333333; 0.0; 0.0 +1376802093; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 144003.73333333334; 0.0; 0.6; 0.0; 0.0 +1376802393; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138410.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376802693; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 195731.2; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376802993; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376803293; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1376803593; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376803893; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 +1376804193; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376804493; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376804793; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 7.0; 0.2; 0.13333333333333333 +1376805093; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130021.6; 0.0; 0.6; 0.0; 0.0 +1376805393; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376805693; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376805993; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376806293; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 208314.93333333332; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376806593; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 169169.33333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376806893; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 149595.46666666667; 0.0; 0.8; 0.0; 0.0 +1376807193; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 0.8; 0.0; 0.0 +1376807493; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.13333333333333333 +1376807793; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.8; 0.06666666666666667; 0.0 +1376808093; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1376808393; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376808693; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376808993; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376809293; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376809593; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376809894; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 191537.86666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376810194; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376810494; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376810794; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376811094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376811394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376811694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376811994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376812294; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376812594; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376812894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376813194; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1376813494; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 191537.86666666667; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376813794; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376814094; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1376814394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.5333333333333333; 0.0; 0.0 +1376814694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376814994; 1; 2599.999304; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6; 0.06666666666666667; 0.0 +1376815294; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1376815594; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1376815894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376816194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1376816494; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376816794; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376817094; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 150993.6; 0.2; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376817394; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376817694; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376817994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376818294; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376818594; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376818894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376819194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 57319.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376819494; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376819794; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376820094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.8; 0.0; 0.0 +1376820394; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376820694; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 150993.6; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1376820994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376821294; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376821594; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376821894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376822194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376822494; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376822794; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376823094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 173362.93333333332; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376823394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376823694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376823995; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376824295; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 142604.8; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376824595; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376824895; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376825195; 1; 2599.999304; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376825495; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376825795; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376826095; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376826395; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 +1376826695; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120234.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376826995; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376827295; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376827595; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376827895; 1; 2599.999304; 25.99999304; 1.0; 2097152.0; 185945.6; 161.06666666666666; 22.0; 0.13333333333333333; 0.8666666666666667 +1376828195; 1; 2599.999304; 51.99998608; 2.0; 2097152.0; 812294.1333333333; 0.0; 3.533333333333333; 0.0; 0.0 +1376828495; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 402650.93333333335; 31.8; 3.066666666666667; 0.0; 0.0 +1376828795; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 215304.53333333333; 0.06666666666666667; 2.3333333333333335; 0.0; 0.0 +1376829095; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 1.8666666666666667; 0.0; 0.0 +1376829395; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376829695; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376829995; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1376830295; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376830595; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376830895; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.13333333333333333; 0.06666666666666667 +1376831195; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376831495; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163575.73333333334; 0.0; 2.3333333333333335; 0.13333333333333333; 0.5333333333333333 +1376831795; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376832096; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376832396; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376832696; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376832996; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1376833296; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376833596; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1376833896; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 11.4; 0.0; 0.0 +1376834196; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376834495; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134215.73333333334; 0.0; 0.8; 0.0; 0.0 +1376834795; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376835095; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 187343.73333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 +1376835395; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376835695; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.13333333333333333; 0.0 +1376835995; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376836295; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 141206.66666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.2 +1376836595; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 146800.0; 0.0; 0.8; 0.0; 0.0 +1376836895; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376837195; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376837495; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376837795; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376838096; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376838396; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376838696; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 192935.73333333334; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1376838996; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376839296; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376839596; 1; 2599.999304; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376839896; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1376840196; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376840496; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376840796; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376841096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376841396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376841696; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376841996; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1376842296; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 155188.0; 0.06666666666666667; 8.266666666666667; 0.26666666666666666; 0.6 +1376842596; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130022.4; 0.06666666666666667; 1.0; 0.06666666666666667; 0.0 +1376842896; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376843196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376843496; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376843796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376844096; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376844396; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376844696; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376844996; 1; 2599.999304; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376845296; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376845596; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376845896; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 104855.2; 0.06666666666666667; 2.8; 0.06666666666666667; 0.5333333333333333 +1376846196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137011.73333333334; 0.0; 0.8; 0.0; 0.0 +1376846496; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376846796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376847096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1376847396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376847696; 1; 2599.999304; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376847996; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376848296; 1; 2599.999304; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376848596; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 121633.6; 12.733333333333333; 13.4; 0.3333333333333333; 0.2 +1376848896; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 1.0; 0.0; 0.0 +1376849196; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 167771.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376849496; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.6; 0.0; 1.6666666666666667; 0.06666666666666667; 0.4666666666666667 +1376849796; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1376850096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376850396; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376850696; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376850996; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376851296; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376851596; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376851896; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376852196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376852496; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376852796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1376853096; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 184548.0; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 +1376853396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376853697; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1376853996; 1; 2599.999304; 36.399990255999995; 1.4; 2097152.0; 171964.8; 161.06666666666666; 14.333333333333334; 0.0; 0.2 +1376854297; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 461372.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376854597; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 222295.2; 31.8; 9.666666666666666; 0.2; 0.13333333333333333 +1376854897; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 218100.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376855197; 1; 2599.999304; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376855497; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376855797; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376856097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376856397; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376856697; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167769.6; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376856997; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 159381.6; 0.0; 1.0; 0.0; 0.0 +1376857297; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376857597; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376857897; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376858197; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376858497; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376858797; 1; 2599.999304; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376859097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376859397; 1; 2599.999304; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376859697; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376859997; 1; 2599.999304; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376860297; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 197129.6; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376860597; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 137012.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376860897; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 132818.66666666666; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376861197; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 144002.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376861497; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376861797; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 132818.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376862097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1376862397; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376862697; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376862997; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376863298; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376863598; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376863898; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 +1376864198; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1376864498; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376864798; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376865098; 1; 2599.999304; 9.2857118; 0.35714285714285715; 2097152.0; 140808.0; 0.07142857142857142; 1.4285714285714286; 0.14285714285714285; 0.14285714285714285 +1376865398; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376865698; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376865998; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376866298; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376866599; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376866899; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 107652.26666666666; 0.2; 0.9333333333333333; 0.0; 0.0 +1376867199; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376867500; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 174761.06666666668; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376867801; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376868101; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376868401; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376868701; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376869001; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376869301; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376869601; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376869901; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376870201; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376870501; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376870801; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 162178.66666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376871101; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167770.4; 0.0; 2.8; 0.06666666666666667; 0.5333333333333333 +1376871401; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376871701; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376872001; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376872301; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.06666666666666667; 1.4; 0.0; 0.0 +1376872601; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376872901; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376873201; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376873501; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376873801; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1376874101; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376874401; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376874701; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 181751.2; 0.2; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376875001; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 127225.86666666667; 0.0; 1.0; 0.0; 0.0 +1376875301; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376875601; 1; 2599.999304; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376875901; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376876201; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1376876501; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376876801; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376877101; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376877401; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125827.2; 0.0; 11.6; 0.0; 0.0 +1376877701; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376878001; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1376878302; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 171965.06666666668; 0.06666666666666667; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1376878602; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138410.93333333332; 0.0; 0.8; 0.0; 0.0 +1376878902; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376879202; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376879502; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376879802; 1; 2599.999304; 71.06664764266665; 2.733333333333333; 2097152.0; 661299.7333333333; 161.0; 21.466666666666665; 0.06666666666666667; 0.4 +1376880102; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 416631.73333333334; 0.0; 8.733333333333333; 0.2; 0.13333333333333333 +1376880402; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 262841.06666666665; 31.8; 3.7333333333333334; 0.0; 0.0 +1376880702; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163576.53333333333; 0.0; 2.2666666666666666; 0.0; 0.0 +1376881002; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 96467.2; 0.0; 1.4; 0.0; 0.0 +1376881302; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376881602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376881902; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 206917.33333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1376882202; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 131419.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376882502; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96466.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376882802; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83883.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376883102; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376883402; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376883702; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376884002; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376884302; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376884602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376884902; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376885202; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376885502; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 232082.93333333332; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1376885802; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376886102; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376886402; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376886702; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.06666666666666667; 6.8; 0.26666666666666666; 0.2 +1376887002; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 155186.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1376887302; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.2; 0.0; 1.0; 0.0; 0.0 +1376887602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1376887902; 1; 2599.999304; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376888202; 1; 2599.999304; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376888502; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376888802; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376889102; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 180352.53333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376889403; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376889703; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1376890003; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 124429.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376890303; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376890603; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1376890903; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376891203; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376891503; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1376891803; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376892103; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376892403; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 145401.06666666668; 0.0; 6.533333333333333; 0.2; 0.13333333333333333 +1376892703; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 176158.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376893003; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376893303; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1376893603; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376893903; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.06666666666666667 +1376894203; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 2.0; 0.06666666666666667; 0.0 +1376894503; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 144003.73333333334; 0.0; 1.4; 0.0; 0.0 +1376894803; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376895103; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 +1376895403; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376895703; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1376896003; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376896304; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 128623.46666666666; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1376896604; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376896904; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376897204; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376897504; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376897804; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376898104; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376898404; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 156586.13333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1376898704; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376899004; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376899304; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1376899604; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376899904; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167771.46666666667; 0.6; 2.2; 0.06666666666666667; 0.5333333333333333 +1376900204; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1376900504; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 71300.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376900804; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376901104; 1; 2599.999304; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1376901404; 1; 2599.999304; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376901704; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1376902004; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376902304; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376902604; 1; 2599.999304; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376902904; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1376903204; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 132818.4; 0.0; 0.6; 0.0; 0.0 +1376903504; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 218101.06666666668; 0.0; 1.9333333333333333; 0.06666666666666667; 0.5333333333333333 +1376903804; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376904104; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1376904404; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376904704; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127225.86666666667; 0.0; 6.733333333333333; 0.4; 0.06666666666666667 +1376905004; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142605.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1376905304; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1376905604; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376905904; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.4; 0.0; 0.8; 0.0; 0.0 +1376906204; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117438.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376906504; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 62912.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376906804; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376907104; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 184548.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376907404; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1376907704; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376908004; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376908304; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376908604; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1376908904; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.4; 0.0 +1376909204; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.0; 0.0 +1376909504; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 2.4; 0.0 +1376909804; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376910104; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.13333333333333333; 0.0 +1376910404; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376910705; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 170566.66666666666; 12.8; 16.466666666666665; 0.4666666666666667; 0.7333333333333333 +1376911005; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1376911305; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376911605; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376911905; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 162178.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376912205; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376912505; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96466.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376912805; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1376913105; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376913405; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376913705; 1; 2599.9993; 28.888881111111115; 1.1111111111111112; 2097152.0; 125828.0; 0.0; 1.125; 0.0; 0.0 +1376914005; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376914305; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 166372.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376914605; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376914905; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376915205; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 61513.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376915505; 1; 2599.999343; 28.599992773000004; 1.1; 2097152.0; 77592.4; 0.0; 1.0; 0.1111111111111111; 0.0 +1376915805; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376916105; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 146800.0; 0.0; 6.8; 0.3333333333333333; 0.13333333333333333 +1376916405; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376916705; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376917005; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376917305; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376917605; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 124429.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376917905; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 199925.33333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376918205; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376918505; 1; 2599.999343; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376918805; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376919105; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376919405; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1376919705; 1; 2599.999343; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1376920005; 1; 2599.999343; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376920306; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376920606; 1; 2599.99945; 25.9999945; 1.0; 2097152.0; 76257.81818181818; 0.0; 1.1; 0.0; 0.0 +1376920906; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376921206; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 11.6; 0.0; 0.0 +1376921506; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 156584.8; 0.0; 2.2; 0.0; 0.4666666666666667 +1376921806; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 130022.13333333333; 0.0; 7.2; 0.4; 0.2 +1376922106; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 159382.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376922406; 1; 2599.99945; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376922706; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1376923006; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 121633.06666666667; 0.0; 1.0; 0.0; 0.0 +1376923306; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 110448.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376923606; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376923906; 1; 2599.999306; 21.272721594545455; 0.8181818181818181; 2097152.0; 114388.72727272728; 0.0; 1.0; 0.0; 0.0 +1376924206; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376924506; 1; 2599.999297; 28.88888107777778; 1.1111111111111112; 2097152.0; 88544.44444444444; 0.0; 0.75; 0.0; 0.0 +1376924806; 1; 2599.999334; 28.363629098181818; 1.0909090909090908; 2097152.0; 101042.90909090909; 0.0; 0.8; 0.1; 0.0 +1376925106; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 141206.66666666666; 0.0; 2.2; 1.0; 0.5333333333333333 +1376925406; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 2.066666666666667; 0.0 +1376925706; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.6; 0.06666666666666667; 0.0 +1376926006; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1376926306; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376926606; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 61513.86666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376926906; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.13333333333333333; 0.0 +1376927206; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376927506; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376927806; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376928106; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376928406; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1376928706; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 155188.0; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376929006; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 +1376929306; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376929606; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376929906; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376930207; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376930507; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376930807; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 134216.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376931107; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.4; 0.0; 0.6; 0.0; 0.0 +1376931407; 1; 2599.999334; 57.19998534800001; 2.2; 2097152.0; 268433.3333333333; 161.0; 21.733333333333334; 0.0; 0.4 +1376931707; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 773148.0; 0.0; 2.6; 0.0; 0.0 +1376932007; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 304784.0; 31.8; 3.2666666666666666; 0.0; 0.0 +1376932307; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 219498.93333333332; 0.0; 3.6; 0.0; 0.4666666666666667 +1376932607; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1376932907; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376933207; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1376933507; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145400.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376933807; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1376934107; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376934407; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 146799.46666666667; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 +1376934707; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138410.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1376935007; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1376935307; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376935607; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1376935907; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 138410.4; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1376936207; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376936507; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376936807; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376937107; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376937407; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376937707; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376938007; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376938307; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1376938607; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.6; 0.06666666666666667; 0.0 +1376938907; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 +1376939208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376939508; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 139809.33333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376939808; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1376940108; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1376940408; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 111846.13333333333; 161.0; 13.266666666666667; 0.0; 0.2 +1376940708; 1; 2599.999334; 38.13332356533333; 1.4666666666666666; 2097152.0; 518693.6; 0.0; 7.933333333333334; 0.26666666666666666; 0.13333333333333333 +1376941008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 225092.53333333333; 31.8; 3.0; 0.0; 0.0 +1376941308; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 219499.73333333334; 0.0; 1.8; 0.0; 0.0 +1376941608; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116040.8; 0.0; 1.2; 0.0; 0.0 +1376941908; 1; 2599.999334; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376942208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376942508; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376942808; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376943108; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 190139.73333333334; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376943408; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376943708; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376944008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376944308; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376944608; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376944908; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376945208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376945508; 1; 2599.999334; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376945808; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.4; 0.0 +1376946108; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376946408; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1376946708; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 195732.26666666666; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1376947008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376947309; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376947609; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376947909; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376948209; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376948509; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376948809; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376949109; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376949408; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376949709; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376950009; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376950309; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 176158.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376950609; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 149594.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376950909; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376951209; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376951509; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.13333333333333333; 0.13333333333333333 +1376951809; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376952109; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376952409; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 114642.93333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1376952709; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376953009; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376953309; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376953610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376953910; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 137012.26666666666; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1376954210; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376954510; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376954810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376955110; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376955410; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 +1376955710; 1; 2599.999334; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376956010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1376956310; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376956610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376956910; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376957210; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376957510; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 176159.2; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376957810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1376958110; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 8.466666666666667; 0.0 +1376958410; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376958710; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 7.4; 0.26666666666666666; 0.2 +1376959010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1376959310; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1376959610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376959910; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1376960210; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376960510; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376960810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376961110; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 141205.86666666667; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376961410; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6; 0.06666666666666667; 0.0 +1376961710; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376962010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376962311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376962611; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376962911; 1; 2599.999334; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376963211; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376963511; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376963811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376964111; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376964411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1376964711; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 153789.86666666667; 0.0; 13.4; 0.06666666666666667; 0.4666666666666667 +1376965011; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376965311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.6; 0.0; 0.0 +1376965611; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1376965911; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376966211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376966511; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1376966811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376967111; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 +1376967411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376967711; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376968011; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 131419.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376968311; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 162177.86666666667; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376968611; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.06666666666666667; 0.6666666666666666; 0.0; 0.0 +1376968911; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376969211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376969511; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376969811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376970111; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1376970411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1376970711; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376971011; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376971311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376971611; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 130021.6; 12.733333333333333; 13.466666666666667; 0.3333333333333333; 0.2 +1376971911; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 156586.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1376972211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376972512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376972812; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376973112; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 156585.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376973412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 149594.93333333332; 0.0; 0.6; 0.0; 0.0 +1376973712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376974012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1376974312; 1; 2599.999626; 28.599995886000002; 1.1; 2097152.0; 62912.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376974612; 1; 2599.999626; 19.066663923999997; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376974912; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376975212; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 +1376975512; 1; 2599.999626; 19.066663923999997; 0.7333333333333333; 2097152.0; 191537.86666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376975812; 1; 2599.999334; 28.363629098181818; 1.0909090909090908; 2097152.0; 83884.0; 0.0; 0.9; 0.0; 0.0 +1376976112; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376976412; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1376976712; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1376977012; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376977312; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376977612; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 6.8; 0.2; 0.13333333333333333 +1376977912; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116040.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376978212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376978512; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376978812; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376979112; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 185945.6; 0.0; 2.0; 0.06666666666666667; 0.5333333333333333 +1376979412; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 148197.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376979712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1376980012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376980312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.26666666666666666; 0.13333333333333333 +1376980612; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 146799.2; 0.0; 2.2; 0.06666666666666667; 0.0 +1376980912; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376981212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376981512; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376981812; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.2; 0.0 +1376982112; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.6; 0.2; 0.0 +1376982412; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 128623.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376982712; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 150994.4; 0.06666666666666667; 2.8666666666666667; 2.3333333333333335; 0.4666666666666667 +1376983012; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.06666666666666667; 6.533333333333333; 0.2; 0.13333333333333333 +1376983312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.8; 0.0; 0.0 +1376983612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1376983912; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376984212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1376984512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376984812; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111845.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376985112; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1376985412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1376985712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376986012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1376986312; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 150993.06666666668; 0.0; 2.2666666666666666; 0.13333333333333333; 0.5333333333333333 +1376986612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 144003.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376986912; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376987212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376987512; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 1.3333333333333333; 4.0; 0.0; 0.0 +1376987812; 1; 2599.999334; 45.066655122666674; 1.7333333333333334; 2097152.0; 232082.4; 181.86666666666667; 31.2; 0.5333333333333333; 0.4 +1376988112; 1; 2599.999334; 41.59998934400001; 1.6; 2097152.0; 844450.9333333333; 0.0; 5.2; 0.0; 0.0 +1376988412; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 409641.3333333333; 31.8; 3.3333333333333335; 0.0; 0.0 +1376988712; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 244665.33333333334; 0.0; 2.533333333333333; 0.0; 0.0 +1376989012; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 184547.46666666667; 0.0; 7.666666666666667; 0.26666666666666666; 0.2 +1376989312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 174761.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376989612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.2666666666666666; 0.6666666666666666; 0.0 +1376989912; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 192935.73333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376990212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376990512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376990812; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376991112; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376991412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1376991712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1376992012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376992312; 1; 2599.999334; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376992612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1376992913; 1; 2599.999334; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376993213; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104855.73333333334; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1376993513; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 178955.2; 0.06666666666666667; 1.8; 0.0; 0.0 +1376993813; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376994123; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376994423; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376994724; 1; 2599.999334; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376995024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376995324; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 183150.13333333333; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376995624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376995924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376996224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376996524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376996824; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.4; 0.06666666666666667; 0.4666666666666667 +1376997124; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 153789.06666666668; 0.0; 1.9333333333333333; 0.0; 0.0 +1376997424; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376997724; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376998024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376998324; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376998624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1376998924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 149596.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376999224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.3333333333333333; 0.2; 0.0 +1376999524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376999824; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.13333333333333333; 0.0 +1377000124; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377000424; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.7333333333333333; 0.4666666666666667 +1377000724; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 149595.46666666667; 0.0; 1.6; 0.0; 0.0 +1377001024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377001324; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 146799.46666666667; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1377001624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137012.0; 0.0; 0.8; 0.0; 0.0 +1377001924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377002224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377002524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377002824; 1; 2599.999334; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377003125; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377003425; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377003725; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377004025; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 124429.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.4666666666666667 +1377004325; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 159382.13333333333; 0.13333333333333333; 1.8666666666666667; 0.06666666666666667; 0.0 +1377004625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377004925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1377005225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377005525; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377005825; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377006125; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1377006425; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377006725; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377007025; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377007325; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 +1377007625; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 +1377007925; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 188741.86666666667; 0.06666666666666667; 7.733333333333333; 0.4666666666666667; 0.13333333333333333 +1377008225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.8; 0.0; 0.0 +1377008525; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 11.8; 0.06666666666666667; 0.0 +1377008825; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377009125; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 0.9333333333333333; 0.13333333333333333; 0.06666666666666667 +1377009425; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377009725; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377010025; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 120234.93333333333; 0.0; 0.7333333333333333; 1.0; 0.0 +1377010325; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.0; 0.0; 1.0; 0.2; 0.0 +1377010625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.13333333333333333; 0.0 +1377010925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377011226; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.4666666666666667 +1377011526; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 137013.06666666668; 0.0; 1.7333333333333334; 0.0; 0.0 +1377011826; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377012126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377012426; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377012726; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1377013026; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1377013326; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1377013626; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.2; 0.0 +1377013926; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 176159.2; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377014226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377014526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377014825; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.06666666666666667; 0.4666666666666667 +1377015125; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 144003.73333333334; 0.0; 1.8666666666666667; 0.0; 0.0 +1377015425; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377015725; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377016025; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1377016325; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1377016625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377016925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377017225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377017526; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.2; 0.0 +1377017826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 162177.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377018126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146798.93333333332; 0.0; 0.8; 0.13333333333333333; 0.0 +1377018426; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.4666666666666667 +1377018726; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 171964.8; 0.06666666666666667; 1.9333333333333333; 0.0; 0.0 +1377019026; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377019326; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.06666666666666667; 7.0; 1.4; 0.13333333333333333 +1377019626; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377019926; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377020226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377020526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377020826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377021126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377021426; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377021726; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377022026; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.4666666666666667 +1377022326; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 152391.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377022626; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 120234.93333333333; 0.0; 0.8; 0.0; 0.0 +1377022926; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377023226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377023526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377023826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1377024126; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377024426; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128624.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377024726; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 121633.06666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377025026; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377025326; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 2.2666666666666666; 0.0 +1377025627; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.13333333333333333; 0.4666666666666667 +1377025927; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 163576.8; 0.0; 7.6; 0.26666666666666666; 0.13333333333333333 +1377026227; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 142605.6; 0.0; 0.6; 0.06666666666666667; 0.0 +1377026527; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377026827; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377027127; 1; 2599.999334; 43.33332223333333; 1.6666666666666665; 2097152.0; 510304.5333333333; 161.0; 14.333333333333334; 0.0; 0.2 +1377027427; 1; 2599.999334; 0.0; 0.0; 2097152.0; 223694.4; 0.0; 1.2; 0.0; 0.0 +1377027727; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 222296.8; 31.8; 3.6; 0.0; 0.0 +1377028027; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1377028327; 1; 2599.999334; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377028627; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377028927; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377029227; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 +1377029527; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 201324.0; 0.06666666666666667; 1.7333333333333334; 0.0; 0.0 +1377029827; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377030127; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377030427; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377030727; 1; 2599.999334; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377031027; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377031327; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 124428.8; 12.8; 13.4; 0.3333333333333333; 0.13333333333333333 +1377031627; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 +1377031927; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377032227; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377032527; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377032827; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.4666666666666667 +1377033127; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 160780.53333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1377033427; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377033727; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377034027; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377034327; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377034627; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377034928; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377035228; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377035528; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377035828; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377036128; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377036428; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 162177.86666666667; 0.0; 1.3333333333333333; 0.06666666666666667; 0.4666666666666667 +1377036728; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 233480.8; 0.13333333333333333; 2.066666666666667; 0.0; 0.0 +1377037028; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 141207.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377037328; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 132817.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377037628; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1377037928; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 120234.66666666667; 0.0; 1.6; 0.13333333333333333; 0.13333333333333333 +1377038229; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1377038529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377038829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377039129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377039429; 1; 2599.999334; 50.266653790666666; 1.9333333333333333; 2097152.0; 225093.06666666668; 161.0; 21.333333333333332; 0.06666666666666667; 0.4 +1377039729; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 724214.9333333333; 0.0; 2.2666666666666666; 0.0; 0.0 +1377040029; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 320164.0; 31.8; 4.0; 0.06666666666666667; 0.4666666666666667 +1377040329; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 229286.4; 0.06666666666666667; 2.2666666666666666; 0.0; 0.0 +1377040629; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.0; 1.8; 0.0; 0.0 +1377040929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377041229; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377041529; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 120234.66666666667; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 +1377041829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377042129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377042429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.9333333333333333; 0.0; 0.0 +1377042729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377043029; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377043329; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1377043629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1377043929; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 153790.66666666666; 0.0; 1.9333333333333333; 0.0; 0.0 +1377044229; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377044529; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377044829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377045129; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.4; 0.0; 0.0 +1377045429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377045729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377046029; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377046329; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377046629; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1377046929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377047230; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 127225.86666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377047529; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 205517.86666666667; 0.0; 2.1333333333333333; 0.0; 0.0 +1377047829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377048129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377048429; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377048729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377049029; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377049329; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377049629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377049929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377050229; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377050529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377050829; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 72698.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377051129; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 167770.4; 0.0; 1.4666666666666666; 0.0; 0.0 +1377051429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377051729; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377052029; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 17.933333333333334; 0.26666666666666666; 0.13333333333333333 +1377052329; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377052629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377052929; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377053229; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 135614.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377053529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377053830; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377054130; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377054430; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 109050.4; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377054730; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 146799.2; 0.06666666666666667; 1.6666666666666667; 0.0; 0.0 +1377055030; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377055330; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377055630; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377055930; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377056230; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377056530; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377056830; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377057130; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104855.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377057430; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377057730; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377058030; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.06666666666666667; 7.2; 0.3333333333333333; 0.6666666666666666 +1377058330; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 176158.4; 0.0; 1.6666666666666667; 0.0; 0.0 +1377058630; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1377058930; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1377059230; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377059530; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377059830; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377060130; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377060430; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377060730; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377061030; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377061330; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377061631; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.06666666666666667; 0.4666666666666667 +1377061931; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 150994.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1377062231; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8; 0.0; 0.0 +1377062531; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377062831; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377063131; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377063431; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377063731; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377064031; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377064331; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 155187.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377064631; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377064931; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377065231; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.4666666666666666; 0.06666666666666667; 0.4666666666666667 +1377065531; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 180353.6; 0.26666666666666666; 1.7333333333333334; 0.0; 0.0 +1377065831; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377066131; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1377066431; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377066731; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.06666666666666667; 0.8666666666666667; 0.06666666666666667; 0.06666666666666667 +1377067031; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.9333333333333333; 0.0; 0.0 +1377067331; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 50328.8; 0.0; 1.4; 0.0; 0.0 +1377067631; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377067931; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.2; 0.0 +1377068231; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.2; 0.0 +1377068531; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.7333333333333334; 0.06666666666666667; 0.0 +1377068831; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.4666666666666667 +1377069131; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 146798.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1377069432; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1377069732; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.6; 0.13333333333333333 +1377070032; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377070332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377070632; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1377070932; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377071232; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1377071532; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377071832; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377072132; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1377072432; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.4666666666666667 +1377072732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 2.2666666666666666; 0.0; 0.0 +1377073032; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377073332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1377073632; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377073932; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377074232; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.6; 0.0; 0.0 +1377074532; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377074832; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377075132; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377075432; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377075732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377076032; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.13333333333; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1377076332; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 176159.2; 0.0; 1.6666666666666667; 0.0; 0.0 +1377076632; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377076932; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 141207.46666666667; 0.0; 6.8; 0.2; 0.13333333333333333 +1377077232; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377077532; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377077832; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377078132; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 152390.13333333333; 20.2; 2.3333333333333335; 0.0; 0.06666666666666667 +1377078432; 1; 2599.999334; 24.266660450666663; 0.9333333333333332; 2097152.0; 138410.4; 0.0; 4.133333333333334; 0.0; 0.0 +1377078732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 125827.2; 0.2; 2.466666666666667; 0.0; 0.0 +1377079032; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377079332; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377079632; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 96467.2; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377079932; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 150993.33333333334; 0.0; 1.4; 0.0; 0.0 +1377080232; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377080532; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377080832; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 92272.8; 0.0; 1.7333333333333334; 0.0; 0.0 +1377081132; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377081432; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377081732; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377082032; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1377082332; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1377082632; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377082932; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377083232; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 124429.33333333333; 0.0; 7.533333333333333; 0.26666666666666666; 0.6666666666666666 +1377083532; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 206916.26666666666; 0.0; 1.8; 0.0; 0.0 +1377083832; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377084132; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377084432; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377084732; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377085032; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377085332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1377085632; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1377085932; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377086232; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377086532; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377086832; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 +1377087132; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 146799.2; 0.0; 1.6; 0.0; 0.0 +1377087432; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 0.8; 0.2; 0.0 +1377087732; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377088032; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377088332; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377088633; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377088933; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377089233; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 131419.73333333334; 12.733333333333333; 13.6; 0.4; 0.13333333333333333 +1377089533; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377089833; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377090133; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377090433; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1377090733; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 169169.33333333334; 0.06666666666666667; 1.4; 0.06666666666666667; 0.0 +1377091033; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377091333; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377091633; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377091933; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377092233; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.6; 0.0; 0.0 +1377092533; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377092833; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377093133; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377093433; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377093733; 1; 2599.999334; 62.399984016; 2.4; 2097152.0; 388670.93333333335; 161.06666666666666; 21.533333333333335; 0.13333333333333333; 0.4 +1377094033; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 581607.7333333333; 0.0; 4.2; 0.06666666666666667; 0.5333333333333333 +1377094333; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 320163.4666666667; 31.8; 4.333333333333333; 0.0; 0.0 +1377094633; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 216703.2; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.13333333333333333 +1377094933; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1377095233; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 142604.53333333333; 0.0; 0.8; 0.0; 0.0 +1377095533; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 150993.6; 0.06666666666666667; 11.866666666666667; 0.06666666666666667; 0.06666666666666667 +1377095833; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 156586.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377096133; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1377096433; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377096733; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377097033; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377097333; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377097633; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.5333333333333333 +1377097933; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 215305.06666666668; 0.0; 1.8; 0.0; 0.0 +1377098234; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377098534; 1; 2599.999334; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377098834; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1377099134; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1377099434; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.13333333333333333; 0.0 +1377099734; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377100034; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377100334; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377100634; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377100934; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 3.6666666666666665; 0.0 +1377101234; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.2; 0.4666666666666667 +1377101534; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 156586.13333333333; 0.06666666666666667; 8.2; 0.26666666666666666; 0.13333333333333333 +1377101834; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377102134; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377102434; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1377102734; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377103034; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377103334; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377103634; 1; 2599.999334; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377103934; 1; 2599.999334; 0.0; 0.0; 2097152.0; 54523.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377104234; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377104534; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 88078.4; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377104834; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.4666666666666667 +1377105134; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 155187.2; 0.0; 0.8; 0.0; 0.0 +1377105434; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1377105735; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377106035; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377106335; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 54523.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1377106635; 1; 2599.999334; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8; 0.0; 0.0 +1377106935; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377107235; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 74097.06666666667; 0.0; 6.8; 0.26666666666666666; 0.2 +1377107535; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377107835; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377108135; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377108435; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.26666666666; 0.0; 1.4; 0.06666666666666667; 0.4666666666666667 +1377108735; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 187342.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377109035; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377109335; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377109635; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377109935; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377110235; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377110535; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377110835; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377111135; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 1.0; 0.0; 0.0 +1377111435; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377111735; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377112036; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377112336; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 1.8; 0.0; 0.0 +1377112636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377112935; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.5333333333333334; 0.06666666666666667; 0.0 +1377113235; 1; 2599.999334; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377113535; 1; 2599.999334; 46.799988012; 1.8; 2097152.0; 466963.73333333334; 161.2; 20.266666666666666; 0.2; 0.3333333333333333 +1377113835; 1; 2599.999334; 0.0; 0.0; 2097152.0; 255851.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1377114135; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 167771.46666666667; 31.8; 3.6666666666666665; 0.0; 0.0 +1377114435; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377114735; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 134215.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377115035; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377115335; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 47532.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377115635; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 74097.06666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377115935; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1377116235; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377116535; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377116835; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1377117135; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377117435; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377117735; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377118036; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377118336; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1377118636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377118936; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377119236; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 9.066666666666666; 0.4; 0.6 +1377119536; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1377119836; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377120136; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377120436; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.2; 0.0 +1377120736; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377121036; 1; 2599.999334; 0.0; 0.0; 2097152.0; 152392.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377121336; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.4; 0.0; 1.0; 0.0; 0.0 +1377121636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377121936; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377122236; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377122537; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377122837; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 2.1333333333333333; 0.2; 0.4666666666666667 +1377123137; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 185945.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377123437; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377123737; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377124037; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377124337; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 1.6; 0.06666666666666667; 0.13333333333333333 +1377124637; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1377124937; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377125237; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 135614.13333333333; 169.73333333333332; 186.0; 0.2; 0.13333333333333333 +1377125537; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 260044.53333333333; 0.0; 0.8; 0.0; 0.0 +1377125837; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377126137; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.7333333333333333; 1.2; 0.0; 0.0 +1377126437; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377126737; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 176158.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377127037; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377127337; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377127637; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377127937; 1; 2599.999334; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377128237; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377128537; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377128837; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377129137; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377129437; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377129737; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377130037; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 97864.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377130337; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 215304.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377130637; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 167770.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377130937; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377131237; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377131537; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377131837; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377132138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377132438; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 113244.8; 0.0; 6.8; 0.2; 0.13333333333333333 +1377132738; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377133038; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377133338; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377133638; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377133938; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377134238; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377134538; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377134838; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377135138; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377135438; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377135738; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 58717.6; 0.0; 1.0; 0.0; 0.0 +1377136038; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377136338; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377136638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377136938; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377137238; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1377137538; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 170565.86666666667; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377137838; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377138138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377138438; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377138738; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 124429.86666666667; 0.06666666666666667; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1377139038; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377139338; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 11.8; 0.0; 0.0 +1377139638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377139938; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377140238; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377140538; 1; 2599.999334; 67.59998268400001; 2.6; 2097152.0; 669688.5333333333; 161.06666666666666; 22.0; 0.06666666666666667; 0.4 +1377140838; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 408244.26666666666; 0.0; 3.533333333333333; 0.0; 0.4666666666666667 +1377141138; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 258645.86666666667; 31.8; 3.533333333333333; 0.0; 0.0 +1377141438; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 149596.0; 0.0; 2.2666666666666666; 0.0; 0.0 +1377141738; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 160781.06666666668; 0.0; 1.9333333333333333; 0.0; 0.0 +1377142038; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 145400.8; 0.0; 0.8; 0.0; 0.0 +1377142338; 1; 2599.999334; 0.0; 0.0; 2097152.0; 148197.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377142638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128624.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377142938; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377143238; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377143538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377143838; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8; 0.0; 0.0 +1377144138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1377144438; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 152391.73333333334; 0.0; 8.4; 0.26666666666666666; 0.6 +1377144738; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377145039; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377145339; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377145638; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377145938; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377146238; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377146538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377146838; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377147138; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377147438; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377147738; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377148038; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 2.4; 0.0; 0.5333333333333333 +1377148338; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 173362.93333333332; 0.06666666666666667; 0.7333333333333333; 0.0; 0.0 +1377148638; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377148938; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377149238; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377149538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377149839; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377150139; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377150439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377150739; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377151039; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 173363.46666666667; 12.8; 13.4; 0.26666666666666666; 0.13333333333333333 +1377151339; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 142604.26666666666; 0.0; 1.4; 0.0; 0.0 +1377151639; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.0; 0.0; 2.2; 0.0; 0.4666666666666667 +1377151939; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 209712.26666666666; 0.0; 0.6; 0.0; 0.0 +1377152239; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377152539; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377152839; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377153139; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.13333333333333333 +1377153439; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 164973.86666666667; 0.0; 1.7333333333333334; 0.0; 0.0 +1377153739; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1377154039; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377154339; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377154639; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1377154939; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377155239; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377155539; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 132817.86666666667; 0.06666666666666667; 1.0; 0.13333333333333333; 0.0 +1377155839; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377156139; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377156439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377156739; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377157039; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377157339; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 8.2; 0.26666666666666666; 0.13333333333333333 +1377157639; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377157939; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1377158239; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377158539; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377158839; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1377159140; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 178955.46666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377159440; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377159740; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377160040; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377160340; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 +1377160640; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377160940; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377161240; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377161540; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1377161840; 1; 2599.999334; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.6; 0.0; 0.0 +1377162140; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1377162439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.2; 2.6666666666666665; 0.0; 0.4666666666666667 +1377162739; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 162177.86666666667; 0.0; 0.6; 0.0; 0.0 +1377163039; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377163339; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 +1377163639; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1377163939; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1377164239; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377164539; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377164840; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377165140; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377165440; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377165740; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377166040; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.53333333334; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377166340; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 184546.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377166640; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377166940; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377167240; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377167540; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377167840; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377168140; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 4.733333333333333; 0.0 +1377168440; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377168740; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377169040; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377169340; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377169640; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377169940; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377170240; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377170540; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377170840; 1; 2599.999334; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377171140; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1377171440; 1; 2599.999334; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377171740; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377172041; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1377172341; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377172641; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377172941; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1377173241; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 83884.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377173541; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 159381.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377173841; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377174141; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377174441; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377174741; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377175041; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377175341; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1377175641; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377175941; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 149594.66666666666; 0.0; 1.0; 0.0; 0.0 +1377176241; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377176541; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377176841; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377177141; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 142604.8; 0.0; 7.0; 0.26666666666666666; 0.2 +1377177441; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377177741; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377178041; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377178341; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377178641; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377178941; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377179241; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377179541; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377179841; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377180141; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377180441; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 142604.8; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1377180741; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1377181041; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377181341; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377181641; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377181941; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1377182241; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 142604.0; 0.0; 0.8; 0.0; 0.0 +1377182542; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377182842; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 85282.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377183142; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377183442; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1377183742; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377184042; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 110448.53333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1377184342; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 155187.2; 0.0; 0.7333333333333333; 0.2; 0.0 +1377184642; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377184942; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377185242; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377185542; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377185842; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377186142; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1377186442; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377186742; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377187042; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377187342; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377187642; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 88078.4; 0.13333333333333333; 2.4; 0.06666666666666667; 0.4666666666666667 +1377187942; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 +1377188242; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377188542; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377188842; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377189142; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377189442; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377189742; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377190042; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377190342; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377190643; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.13333333333333333; 0.0 +1377190943; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377191243; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.06666666666666667; 2.1333333333333333; 0.13333333333333333; 0.4666666666666667 +1377191543; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377191843; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377192143; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377192443; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377192743; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377193043; 1; 2599.999297; 27.999992429230765; 1.0769230769230769; 2097152.0; 77431.07692307692; 0.0; 0.8333333333333334; 0.08333333333333333; 0.0 +1377193343; 1; 2599.999297; 17.33332864666667; 0.6666666666666667; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377193643; 1; 2599.999297; 34.66665729333334; 1.3333333333333335; 2097152.0; 100661.06666666667; 161.13333333333333; 20.6; 0.06666666666666667; 0.4 +1377193943; 1; 2599.999297; 55.46665166933333; 2.1333333333333333; 2097152.0; 746584.8; 0.0; 3.6666666666666665; 0.0; 0.0 +1377194243; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 327154.13333333336; 31.8; 3.4; 0.06666666666666667; 0.0 +1377194543; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 181752.53333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1377194843; 1; 2599.999297; 20.799994376; 0.8; 2097152.0; 121633.6; 0.0; 9.2; 0.26666666666666666; 0.6666666666666666 +1377195143; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 181751.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377195443; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377195743; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1377196043; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377196343; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377196643; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377196943; 1; 2599.999297; 15.599995781999999; 0.6; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377197243; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377197543; 1; 2599.999297; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377197843; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377198143; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 111845.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377198443; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 103457.33333333333; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1377198743; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 157982.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377199043; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377199343; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377199643; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 107651.46666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1377199943; 1; 2599.999297; 45.06665448133334; 1.7333333333333334; 2097152.0; 392864.0; 161.06666666666666; 14.4; 0.06666666666666667; 0.2 +1377200243; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 290802.6666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1377200543; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 243268.0; 31.8; 4.466666666666667; 0.0; 0.0 +1377200843; 1; 2599.999297; 12.133330052666665; 0.4666666666666666; 2097152.0; 171965.06666666668; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1377201143; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377201443; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377201743; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377202043; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 3.1333333333333333; 0.0; 0.4666666666666667 +1377202343; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 160779.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377202643; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377202943; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377203243; 1; 2599.999306; 18.571423614285717; 0.7142857142857143; 2097152.0; 101860.0; 0.0; 0.9230769230769231; 1.9230769230769231; 0.0 +1377203543; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377203844; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377204144; 1; 2599.999306; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 1.0; 0.0; 0.0 +1377204444; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377204744; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377205044; 1; 2599.999306; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377205344; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.1333333333333333; 2.466666666666667; 0.0 +1377205644; 1; 2599.999306; 5.199998612000001; 0.2; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377205944; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 170566.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377206244; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.2; 0.0 +1377206844; 1; 2599.999306; 8.666664353333335; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377207144; 1; 2599.999306; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377207444; 1; 2599.999306; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377208044; 1; 2599.999306; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377208344; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377208644; 1; 2599.999306; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377208944; 1; 2599.999306; 8.666664353333335; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377209245; 1; 2599.999306; 5.199998612000001; 0.2; 2097152.0; 134216.0; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377209845; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1377210145; 1; 2599.999601; 25.99999601; 1.0; 2097152.0; 102059.73333333334; 0.0; 0.8571428571428571; 0.0; 0.0 +1377210445; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377210745; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 130021.6; 0.06666666666666667; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 +1377211045; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377211345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377211645; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377211945; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377212245; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377212545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377212845; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377213145; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 177557.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377213445; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.13333333333333333 +1377213745; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1377214045; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377214345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377214645; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377214945; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377215245; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 +1377215545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377215845; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377216145; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1377216445; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 99263.46666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377216745; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377217045; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377217345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377217645; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 131419.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377217945; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109049.6; 0.06666666666666667; 1.4666666666666666; 0.0; 0.0 +1377218245; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377218545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377218845; 1; 2599.999601; 12.133331471333332; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 1.0; 0.0; 0.0 +1377219145; 1; 2599.999601; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377219445; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377219745; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377220045; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 118837.33333333333; 0.13333333333333333; 2.4; 0.0; 0.5333333333333333 +1377220345; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 163576.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377220646; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 85282.13333333333; 0.06666666666666667; 1.7333333333333334; 0.0; 0.0 +1377220946; 1; 2599.999601; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377221246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377221546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377221846; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377222146; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377222446; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377222746; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377223046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377223346; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377223646; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.8666666666666667; 0.0; 0.4666666666666667 +1377223946; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 141206.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377224246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377224546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377224846; 1; 2599.999601; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377225146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377225446; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377225746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377226046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377226346; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377226646; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 11.733333333333333; 0.0; 0.0 +1377226946; 1; 2599.999601; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377227246; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 107652.0; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377227546; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 183148.53333333333; 0.0; 1.0; 0.0; 0.0 +1377227846; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377228146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377228446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377228746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377229046; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377229346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1377229646; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1377229946; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377230246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377230546; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377230846; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 83884.0; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377231146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377231446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377231746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232646; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232946; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 170566.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377233246; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377233547; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 155187.2; 0.2; 6.933333333333334; 0.2; 0.13333333333333333 +1377233847; 1; 2599.999309; 15.166662635833333; 0.5833333333333334; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1377234147; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377234447; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377234747; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 171964.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377235047; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377235347; 1; 2599.999309; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1377235647; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1377235947; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377236247; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377236547; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377236847; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1377237147; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377237447; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377237747; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1377238047; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 +1377238347; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 146798.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377238647; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377238947; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377239247; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 150992.8; 0.0; 6.666666666666667; 0.3333333333333333; 0.13333333333333333 +1377239547; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.06666666666666667 +1377239847; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 121633.6; 0.0; 1.8; 0.0; 0.0 +1377240147; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 149595.46666666667; 0.0; 1.6666666666666667; 0.13333333333333333; 0.0 +1377240447; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377240747; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377241047; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377241347; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.4; 0.0; 0.0 +1377241647; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1377241947; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 192936.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377242247; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377242547; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377242848; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1377243148; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377243448; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377243748; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377244048; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377244347; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.06666666666666667; 0.0 +1377244647; 1; 2599.999309; 57.199984798; 2.2; 2097152.0; 736797.0666666667; 161.0; 21.866666666666667; 0.13333333333333333; 0.4 +1377244947; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 394262.4; 0.0; 2.466666666666667; 0.06666666666666667; 0.0 +1377245247; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 247461.6; 32.06666666666667; 4.8; 0.0; 0.4666666666666667 +1377245547; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 197130.4; 0.0; 2.4; 0.06666666666666667; 0.0 +1377245847; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1377246147; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 6.666666666666667; 0.3333333333333333; 0.2 +1377246447; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 1.4; 1.2666666666666666; 0.0 +1377246748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377247048; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377247348; 1; 2599.999309; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.6; 0.0; 0.0 +1377247648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377247948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377248248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377248548; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377248848; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377249148; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 176158.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377249448; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377249748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377250048; 1; 2599.999309; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377250348; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377250648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377250948; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1377251248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377251548; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377251848; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377252148; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.06666666666666667; 0.0 +1377252448; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1377252748; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377253048; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377253348; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377253648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377253948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377254248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377254548; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377254848; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377255148; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377255448; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377255748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377256048; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377256348; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 1.2; 0.0; 0.0 +1377256648; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377256948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377257249; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377257549; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377257849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377258149; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377258449; 1; 2599.999309; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377258749; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377259049; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 +1377259349; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377259649; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1377259949; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 155186.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1377260249; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 117438.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377260549; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 156585.86666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377260849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.8666666666666667; 0.0 +1377261149; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 82.06666666666666; 0.0 +1377261449; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377261749; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377262049; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377262349; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377262649; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377262949; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377263249; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377263549; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 197130.4; 0.0; 1.0; 0.0; 0.0 +1377263849; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377264149; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1377264449; 1; 2599.999309; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377264749; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 113244.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377265049; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377265349; 1; 2599.999309; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1377265649; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 116041.06666666667; 0.0; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 +1377265949; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377266249; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1377266549; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377266849; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 107651.73333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377267149; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 188742.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377267449; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377267749; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377268049; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377268349; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 90874.66666666667; 0.06666666666666667; 1.4; 0.06666666666666667; 0.13333333333333333 +1377268649; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377268949; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377269249; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377269549; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377269849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377270149; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 11.933333333333334; 0.13333333333333333; 0.0 +1377270449; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 93670.4; 0.4666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377270749; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 137012.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377271049; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377271349; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377271649; 1; 2599.999309; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377271950; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377272250; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377272550; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 12.733333333333333; 16.733333333333334; 0.3333333333333333; 0.13333333333333333 +1377272850; 1; 2599.999309; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.6; 0.0; 0.0 +1377273150; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1377273450; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377273750; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377274050; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377274350; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 114642.4; 0.0; 1.0; 0.0; 0.0 +1377274650; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 144002.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377274950; 1; 2599.999309; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377275250; 1; 2599.999309; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377275550; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130021.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377275850; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 132818.4; 0.0; 1.2; 0.0; 0.0 +1377276150; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377276450; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377276750; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377277050; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377277350; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130021.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377277650; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 131420.26666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377277950; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 142604.0; 0.0; 0.8; 0.0; 0.0 +1377278250; 1; 2599.999309; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377278550; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377278850; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377279150; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1377279450; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 128624.26666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 +1377279750; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377280050; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377280350; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377280650; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377280950; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377281250; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 99262.93333333333; 0.0; 2.533333333333333; 0.13333333333333333; 0.4666666666666667 +1377281551; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 171964.0; 0.06666666666666667; 1.0666666666666667; 0.06666666666666667; 0.0 +1377281851; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 153790.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377282151; 1; 2599.999309; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1377282451; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377282751; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377283051; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377283351; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 178955.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377283651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377283951; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377284251; 1; 2599.999309; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.13333333333333333; 0.0 +1377284551; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 65708.26666666666; 0.0; 0.8; 0.0; 0.0 +1377284851; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377285151; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 159382.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377285451; 1; 2599.999309; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377285751; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377286051; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377286351; 1; 2599.999309; 38.13332319866666; 1.4666666666666666; 2097152.0; 430614.4; 161.53333333333333; 14.333333333333334; 0.0; 0.2 +1377286651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 394262.6666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1377286951; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 197129.86666666667; 31.8; 3.933333333333333; 0.0; 0.0 +1377287251; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 155187.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1377287551; 1; 2599.999309; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377287851; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377288151; 1; 2599.999309; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377288451; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 139808.8; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377288751; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 181750.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377289051; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1377289351; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377289651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377289951; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377290251; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377290551; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377290852; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1377291152; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377291452; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377291752; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 110448.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377292052; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 139808.26666666666; 0.0; 8.466666666666667; 0.3333333333333333; 0.6 +1377292352; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 177556.0; 0.0; 1.2; 0.0; 0.0 +1377292652; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 149596.26666666666; 0.0; 0.8; 0.0; 0.0 +1377292952; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377293251; 1; 2599.999309; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377293551; 1; 2599.999309; 55.46665192533332; 2.1333333333333333; 2097152.0; 268433.6; 161.0; 21.533333333333335; 0.06666666666666667; 0.4 +1377293851; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 717224.2666666667; 0.0; 2.6666666666666665; 0.0; 0.0 +1377294151; 1; 2599.999309; 12.133330108666664; 0.4666666666666666; 2097152.0; 317366.93333333335; 31.8; 3.6; 0.0; 0.0 +1377294451; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 212508.53333333333; 0.0; 2.1333333333333333; 0.0; 0.0 +1377294751; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 121633.6; 0.0; 1.8; 0.0; 0.0 +1377295051; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1377295352; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377295652; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1377295952; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 153789.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377296252; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 +1377296552; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377296852; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377297152; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1377297452; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1377297752; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377298052; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377298352; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377298652; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377298952; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377299252; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 127225.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377299552; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 166371.73333333334; 0.0; 0.8; 0.0; 0.0 +1377299852; 1; 2599.999309; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377300152; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377300452; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377300752; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377301052; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.26666666666666666; 0.0 +1377301352; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377301652; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377301952; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377302252; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377302552; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377302852; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377303152; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 188741.6; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377303452; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377303752; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377304052; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377304352; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 157984.26666666666; 0.06666666666666667; 1.4; 0.0; 0.0 +1377304652; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377304953; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 +1377305253; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1377305553; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377305853; 1; 2599.999309; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377306153; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377306453; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377306753; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377307053; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 120234.66666666667; 0.0; 0.8; 0.0; 0.0 +1377307353; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1377307653; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377307953; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377308253; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377308553; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377308853; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377309153; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377309453; 1; 2599.999309; 0.0; 0.0; 2097152.0; 149596.0; 0.0; 0.6; 0.0; 0.0 +1377309753; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 114642.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377310053; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 121633.33333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377310353; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 171965.06666666668; 0.0; 1.2; 0.0; 0.0 +1377310653; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377310953; 1; 2599.999309; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1377311253; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 +1377311553; 1; 2599.999309; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377311853; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377312153; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377312453; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377312753; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6; 0.0; 0.0 +1377313053; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377313353; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377313653; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 162178.13333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1377313953; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 164974.4; 0.0; 11.6; 0.0; 0.0 +1377314253; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377314553; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377314853; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377315154; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377315454; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377315754; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 139807.73333333334; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1377316054; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1377316354; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 +1377316654; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 +1377316954; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377317254; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 124429.6; 0.13333333333333333; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377317554; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 180353.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377317854; 1; 2599.999309; 0.0; 0.0; 2097152.0; 144003.2; 0.0; 0.8; 0.0; 0.0 +1377318154; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377318454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377318754; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377319054; 1; 2599.999309; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377319354; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1377319654; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377319954; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377320254; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377320554; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377320854; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.06666666666666667; 2.0; 0.06666666666666667; 0.4666666666666667 +1377321154; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 171963.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377321454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377321754; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377322054; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 128624.26666666666; 0.0; 6.6; 0.26666666666666666; 0.13333333333333333 +1377322354; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 +1377322655; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1377322955; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377323255; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1377323555; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377323855; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377324155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377324455; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 109050.4; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377324755; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377325055; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377325355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377325655; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377325955; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.06666666666666667 +1377326255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 146799.2; 0.0; 1.9333333333333333; 0.0; 0.0 +1377326554; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 134216.8; 0.0; 1.7333333333333334; 0.0; 0.0 +1377326854; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1377327154; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377327454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377327755; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377328055; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 134216.8; 0.06666666666666667; 8.6; 0.26666666666666666; 0.6 +1377328355; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 146800.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377328655; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377328955; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377329255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377329555; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377329855; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377330155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1377330455; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1377330755; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377331055; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377331355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377331655; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.06666666666666667; 1.9333333333333333; 0.13333333333333333; 0.5333333333333333 +1377331955; 1; 2599.999309; 12.133330108666664; 0.4666666666666666; 2097152.0; 176158.4; 0.0; 1.0; 0.0; 0.0 +1377332255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377332555; 1; 2599.999309; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377332855; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377333155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377333455; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377333755; 1; 2599.999309; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377334055; 1; 2599.999309; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377334355; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 132818.66666666666; 12.733333333333333; 14.066666666666666; 0.3333333333333333; 0.2 +1377334655; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1377334955; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377335255; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 2.6666666666666665; 0.0; 0.4666666666666667 +1377335555; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 150993.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1377335855; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377336155; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377336455; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377336755; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377337055; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377337355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377337655; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377337955; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377338255; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377338555; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377338855; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377339156; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377339456; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1377339756; 1; 2599.999309; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377340056; 1; 2599.999309; 0.0; 0.0; 2097152.0; 57319.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377340356; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377340656; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377340956; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377341256; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377341556; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377341856; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377342156; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377342456; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 107652.0; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377342756; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 180353.6; 0.0; 1.0; 0.0; 0.0 +1377343056; 1; 2599.999309; 64.13331628866666; 2.466666666666667; 2097152.0; 328552.5333333333; 161.06666666666666; 21.533333333333335; 0.2; 0.4 +1377343356; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 658504.0; 0.0; 2.533333333333333; 0.0; 0.0 +1377343656; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 268433.6; 31.8; 3.7333333333333334; 0.0; 0.0 +1377343956; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 167771.2; 0.0; 2.1333333333333333; 0.0; 0.0 +1377344256; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1377344556; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 1.0; 0.0; 0.0 +1377344856; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377345156; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377345456; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377345756; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377346056; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1377346356; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 159381.6; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377346656; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377346956; 1; 2599.999309; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377347256; 1; 2599.999601; 11.999998158461537; 0.4615384615384615; 2097152.0; 79044.30769230769; 0.0; 0.9166666666666666; 0.0; 0.0 +1377347556; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 107652.26666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 +1377347856; 1; 2599.99931; 25.9999931; 1.0; 2097152.0; 116840.0; 0.0; 0.8461538461538461; 0.0; 0.0 +1377348156; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377348456; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377348757; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377349057; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377349357; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1377349657; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 142605.06666666668; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377349957; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 162178.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377350257; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377350557; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377350857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377351157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377351457; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377351757; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 139808.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377352057; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377352357; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377352657; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377352957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377353257; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377353557; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 169169.33333333334; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377353857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377354157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377354457; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377354757; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.06666666666666667; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1377355057; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377355357; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.8; 0.26666666666666666; 0.0 +1377355657; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1377355957; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377356257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377356557; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377356857; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 2.2; 0.0; 0.4666666666666667 +1377357157; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 146798.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1377357457; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 11.933333333333334; 0.0; 0.0 +1377357757; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377358057; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377358357; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377358658; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377358957; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1377359257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377359557; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377359857; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377360157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1377360457; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377360757; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377361057; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377361357; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377361657; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377361957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377362257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1377362557; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377362857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 +1377363157; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377363457; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377363757; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.0; 0.0 +1377364057; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 103457.06666666667; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1377364357; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 164974.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377364657; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377364957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377365257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377365558; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377365858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377366158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377366458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377366758; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 145401.06666666668; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 +1377367058; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377367358; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377367658; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377367958; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377368258; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377368558; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377368858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1377369158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377369458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.6666666666666666; 0.26666666666666666; 0.0 +1377369758; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.9333333333333333; 0.0 +1377370058; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377370358; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377370658; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377370958; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 +1377371258; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 86680.26666666666; 0.0; 2.4; 0.0; 0.4666666666666667 +1377371558; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 174761.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 +1377371858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377372158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377372458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377372758; 1; 2599.99931; 41.59998896; 1.6; 2097152.0; 369097.3333333333; 161.0; 14.266666666666667; 0.0; 0.2 +1377373058; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 426419.2; 0.0; 7.2; 0.2; 0.13333333333333333 +1377373358; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 208315.46666666667; 31.8; 3.4; 0.06666666666666667; 0.0 +1377373658; 1; 2599.99931; 0.0; 0.0; 2097152.0; 178954.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377373958; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377374259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377374559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377374859; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377375159; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.8; 0.0; 0.0 +1377375459; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377375759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377376059; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377376359; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377376659; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377376959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377377259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377377559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377377859; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377378159; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96467.2; 0.6666666666666666; 1.5333333333333334; 0.0; 0.0 +1377378459; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 100661.33333333333; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377378759; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159381.86666666667; 0.0; 0.8; 0.0; 0.0 +1377379059; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377379359; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 75495.2; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 +1377379659; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377379959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1377380259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377380559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377380859; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377381159; 1; 2599.99931; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.8; 0.0; 0.0 +1377381459; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377381759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377382059; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99262.66666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377382359; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 184547.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377382659; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377382959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377383259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377383559; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 +1377383859; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377384159; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377384459; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377384759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377385059; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377385360; 1; 2599.99931; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 0.6; 0.0; 0.0 +1377385660; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138411.2; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377385960; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377386260; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377386560; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377386860; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8; 0.0; 0.0 +1377387160; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 0.8; 0.0; 0.0 +1377387460; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377387760; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377388060; 1; 2599.99931; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.0; 0.0; 0.0 +1377388360; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377388660; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377388960; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1377389260; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 130021.86666666667; 0.0; 2.8; 0.0; 0.4666666666666667 +1377389560; 1; 2599.99931; 0.0; 0.0; 2097152.0; 178954.13333333333; 0.0; 0.8; 0.0; 0.0 +1377389860; 1; 2599.99931; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 +1377390160; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377390460; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377390760; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 61513.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1377391060; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377391360; 1; 2599.99931; 57.19998482000001; 2.2; 2097152.0; 357911.73333333334; 161.0; 21.733333333333334; 0.06666666666666667; 0.3333333333333333 +1377391660; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 665494.4; 0.0; 2.2666666666666666; 0.0; 0.0 +1377391961; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 247461.06666666668; 44.6; 15.8; 0.3333333333333333; 0.2 +1377392261; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 178954.66666666666; 0.0; 2.466666666666667; 0.0; 0.0 +1377392561; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1377392861; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.33333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377393161; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 174760.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377393461; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1377393761; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.0; 0.0 +1377394061; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1377394361; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377394661; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1377394961; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377395261; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1377395561; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1377395861; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377396161; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377396461; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 120235.46666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377396761; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 162178.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377397061; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377397361; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.2; 0.0; 0.0 +1377397661; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377397961; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377398261; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377398561; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 148197.06666666668; 0.0; 7.2; 0.2; 0.13333333333333333 +1377398861; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377399161; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377399461; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377399761; 1; 2599.99931; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377400061; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 71300.8; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1377400362; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377400662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377400962; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 11.733333333333333; 0.0; 0.0 +1377401262; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377401562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377401862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377402162; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377402462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377402762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377403062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377403362; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377403662; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 148197.33333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377403962; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 205519.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377404262; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1377404562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377404862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377405162; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377405462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377405762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1377406062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377406362; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377406662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377406962; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377407262; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 83884.0; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1377407562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.06666666666666667; 1.0666666666666667; 0.0; 0.0 +1377407862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377408162; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377408462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377408762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377409062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377409362; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377409662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377409962; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1377410262; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377410562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377410862; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 159382.4; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.6 +1377411162; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377411462; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1377411763; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377412063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377412363; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1377412663; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 2.066666666666667; 0.0; 0.0 +1377412963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1377413263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377413563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 61513.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377413863; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377414163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377414463; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1377414763; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 176158.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377415063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377415363; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377415663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377415963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377416263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377416563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1377416863; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1377417163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377417463; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377417763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377418063; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 90874.66666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377418363; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377418663; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377418963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104855.2; 0.0; 0.8; 0.0; 0.0 +1377419263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377419564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377419864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377420164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377420464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377420764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1377421064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377421364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377421664; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 125827.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377421964; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 205519.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377422264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377422564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.8; 0.0; 0.0 +1377422864; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377423164; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377423464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377424064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377424364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.6; 0.0; 0.0 +1377424663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377424963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377425263; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.06666666666666667; 2.933333333333333; 0.0; 0.4666666666666667 +1377425563; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377425863; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377426163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377426463; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1377426763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377427063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377427363; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377427663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377427963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377428263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377428563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8; 0.0; 0.0 +1377428863; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 81087.73333333334; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 +1377429163; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377429463; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377429763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377430063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377430363; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377430664; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377430964; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377431264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.2; 0.0; 0.0 +1377431564; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377431864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377432164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1377432464; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377432764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1377433064; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 156585.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377433364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377433664; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377433964; 1; 2599.99931; 0.0; 0.0; 2097152.0; 166372.26666666666; 0.0; 0.8; 0.0; 0.0 +1377434264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125826.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377434564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377434864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377435164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1377435464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377435764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377436064; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377436364; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 195731.46666666667; 0.0; 1.2; 0.0; 0.0 +1377436664; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377436964; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377437264; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 +1377437564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377437864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377438164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377438464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377438764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377439064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377439364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377439664; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138411.2; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1377439964; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 157984.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377440264; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377440564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377440864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377441164; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.06666666666666667; 0.06666666666666667 +1377441464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 0.8; 0.0; 0.0 +1377441764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1377442064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377442364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377442665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377442965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377443265; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1377443565; 1; 2599.99931; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377443865; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377444165; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1377444465; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1377444765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.0; 11.533333333333333; 0.0; 0.0 +1377445065; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377445365; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377445665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377445965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377446265; 1; 2599.99931; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377446565; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377446865; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 144002.4; 0.0; 1.9333333333333333; 0.0; 0.4666666666666667 +1377447165; 1; 2599.99931; 62.39998344000001; 2.4; 2097152.0; 454381.6; 161.0; 21.733333333333334; 0.0; 0.4 +1377447465; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 671087.2; 0.0; 2.533333333333333; 0.0; 0.0 +1377447765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 264238.93333333335; 31.8; 3.3333333333333335; 0.0; 0.0 +1377448065; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 150993.33333333334; 0.0; 2.2666666666666666; 0.0; 0.0 +1377448365; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1377448665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1377448965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1377449265; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159382.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377449565; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1377449865; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377450165; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 130021.86666666667; 12.733333333333333; 13.333333333333334; 0.3333333333333333; 0.13333333333333333 +1377450465; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 233481.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1377450765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 194334.66666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1377451065; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377451365; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1377451665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377451965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377452265; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377452566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377452866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1377453166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377453466; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377453766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377454066; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.4; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1377454366; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 171964.53333333333; 0.0; 0.8; 0.0; 0.0 +1377454666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377454966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377455266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377455566; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377455866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377456166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377456466; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377456766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377457066; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 141207.46666666667; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377457366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377457666; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377457966; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 174760.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377458266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377458566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377458866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377459166; 1; 2599.99931; 36.39999034; 1.4; 2097152.0; 297793.6; 161.0; 14.333333333333334; 0.0; 0.13333333333333333 +1377459466; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 466963.2; 0.0; 1.0; 0.0; 0.0 +1377459766; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 211110.66666666666; 31.8; 3.8; 0.0; 0.0 +1377460066; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 169169.06666666668; 0.0; 1.0; 0.0; 0.0 +1377460366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377460666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377460966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1377461266; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 120234.66666666667; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1377461566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 173362.4; 0.0; 0.8; 0.0; 0.0 +1377461866; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377462166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377462466; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 76893.33333333333; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 +1377462766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377463066; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377463366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377463666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377463966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377464266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377464566; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 +1377464866; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 2.2; 0.0; 0.4666666666666667 +1377465167; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1377465467; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377465767; 1; 2599.99931; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377466067; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1377466367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377466667; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377466967; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377467267; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104855.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377467567; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377467867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377468167; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377468467; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377468767; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 144002.13333333333; 0.0; 0.6; 0.0; 0.0 +1377469067; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1377469367; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 137013.06666666668; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377469667; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377469967; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.4; 0.06666666666666667; 0.06666666666666667 +1377470267; 1; 2599.99931; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 +1377470567; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377470867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377471167; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377471467; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377471767; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377472067; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128624.26666666666; 0.2; 2.8; 0.0; 0.4666666666666667 +1377472367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377472667; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377472967; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377473267; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377473567; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377473867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377474167; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.0; 0.0; 0.0 +1377474467; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1377474767; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1377475067; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377475367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377475667; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96466.93333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377475967; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 176158.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377476267; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377476567; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377476867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377477168; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1377477468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377477768; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377478068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377478368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377478668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377478968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377479268; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377479568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377479868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377480168; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377480468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377480768; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377481068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377481368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377481668; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377481968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377482268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377482568; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377482868; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377483168; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 145401.86666666667; 0.0; 1.0; 0.0; 0.0 +1377483468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377483768; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377484068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377484368; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377484668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377484968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377485268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377485568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 160780.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377485868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377486168; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 85282.13333333333; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 +1377486468; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.2; 0.0; 0.4666666666666667 +1377486768; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 190139.73333333334; 0.0; 0.8; 0.0; 0.0 +1377487068; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377487368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111845.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377487668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377487968; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377488269; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377488569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377488869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1377489169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377489469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377489769; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1377490068; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1377490368; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 180353.6; 0.0; 1.0; 0.0; 0.0 +1377490668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.8; 0.0; 0.0 +1377490968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377491268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377491568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377491868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377492168; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377492468; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.0; 0.0 +1377492768; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377493068; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377493368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377493668; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377493968; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 176157.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377494268; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377494569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377494869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377495169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377495469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377495769; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377496069; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377496369; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377496669; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377496969; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1377497269; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107651.46666666666; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377497569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377497869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377498169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377498469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377498769; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 61513.86666666667; 0.06666666666666667; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1377499069; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 58717.6; 0.0; 1.8; 0.0; 0.0 +1377499369; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.5333333333333334; 0.0; 0.0 +1377499669; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 6.8; 0.2; 0.13333333333333333 +1377499969; 1; 2599.99931; 60.666650566666675; 2.3333333333333335; 2097152.0; 359311.4666666667; 161.0; 21.733333333333334; 0.06666666666666667; 0.4 +1377500269; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 654309.6; 0.0; 2.6; 0.0; 0.0 +1377500569; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 310376.8; 31.8; 3.4; 0.0; 0.0 +1377500869; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 192935.2; 0.0; 3.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377501169; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 192936.0; 0.0; 1.8666666666666667; 0.0; 0.0 +1377501470; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377501770; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377502070; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377502370; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377502670; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1377502970; 1; 2599.99931; 36.39999034; 1.4; 2097152.0; 92272.8; 0.0; 1.2; 104.86666666666666; 0.0 +1377503270; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377503570; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377503870; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.4; 0.0 +1377504170; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377504470; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99262.66666666667; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377504770; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 0.8; 0.0; 0.0 +1377505070; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1377505370; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1377505670; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377505970; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377506270; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377506570; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377506870; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377507170; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377507470; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377507770; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1377508070; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 142605.6; 0.13333333333333333; 2.466666666666667; 0.0; 0.4666666666666667 +1377508370; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 142605.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377508670; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377508970; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377509270; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377509570; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1377509870; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377510170; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377510470; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377510771; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377511071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377511371; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 152391.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377511671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.06666666666666667; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1377511971; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 156586.13333333333; 12.733333333333333; 12.933333333333334; 0.4666666666666667; 0.2 +1377512271; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377512571; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1377512871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377513171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377513471; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.4; 0.0; 0.0 +1377513771; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377514071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377515571; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377515871; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1377516171; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377516471; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377516771; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 3.1333333333333333; 0.0 +1377517071; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377517371; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377517671; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377517971; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377518271; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1377518571; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1377518871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377519171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 169168.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377519472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377519772; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377520072; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377520372; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377520672; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377520972; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377521272; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377521572; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 134216.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377521872; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377522172; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.6; 0.0; 0.0 +1377522472; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377522771; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 204121.06666666668; 0.0; 0.8; 0.0; 0.0 +1377523071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377523371; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377523671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377523971; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377524271; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.6666666666666667; 0.0; 0.0 +1377524571; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 100661.6; 0.0; 7.4; 0.6; 0.2 +1377524871; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377525171; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377525471; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1377525771; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377526071; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1377526371; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377526671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377526971; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377527271; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377527571; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1377527871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377528171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377528472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377528772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.5333333333333333; 0.0 +1377529072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377529372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377529672; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 150992.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377529972; 1; 2599.99931; 0.0; 0.0; 2097152.0; 171965.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377530272; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377530572; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 6.6; 0.2; 0.13333333333333333 +1377530872; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377531172; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377531472; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377531772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 150994.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377532072; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 12.066666666666666; 0.06666666666666667; 0.0 +1377532372; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 1.8; 0.0 +1377532672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 2.2666666666666666; 0.0 +1377532972; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377533272; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 121633.6; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1377533572; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377533872; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377534172; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 4.2; 0.0 +1377534472; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377534772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377535072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377535372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377535672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377535972; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1377536272; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377536572; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377536872; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.46666666666; 0.13333333333333333; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377537172; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 155188.0; 0.0; 7.2; 0.2; 0.13333333333333333 +1377537472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377537772; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377538072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377538372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 2.2666666666666666; 0.0 +1377538672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377538972; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377539272; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377539572; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 +1377539873; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 142604.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377540173; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377540473; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377540773; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 169169.33333333334; 0.0; 0.8; 0.0; 0.0 +1377541073; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377541373; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377541673; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377541973; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 111846.13333333333; 0.0; 0.8; 0.6; 0.0 +1377542273; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 +1377542573; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8; 3.2; 0.0 +1377542873; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1377543173; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377543473; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 173363.2; 0.0; 6.8; 0.2; 0.13333333333333333 +1377543773; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377544073; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377544373; 1; 2599.99931; 0.0; 0.0; 2097152.0; 156585.33333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377544673; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377544973; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8; 0.0; 0.0 +1377545273; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377545573; 1; 2599.99931; 50.26665332666667; 1.9333333333333333; 2097152.0; 233481.6; 161.2; 14.6; 0.06666666666666667; 0.2 +1377545873; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 486537.06666666665; 0.0; 1.2666666666666666; 0.0; 0.0 +1377546173; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 208314.66666666666; 31.8; 3.6666666666666665; 0.0; 0.0 +1377546473; 1; 2599.99931; 0.0; 0.0; 2097152.0; 201324.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377546773; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377547073; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377547373; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377547673; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377547973; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 190140.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377548273; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377548573; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 1.8666666666666667; 0.0 +1377548873; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 +1377549173; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1377549473; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377549774; 1; 2599.99931; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1377550074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377550374; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377550674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377550974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377551274; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 132817.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377551574; 1; 2599.99931; 60.666650566666675; 2.3333333333333335; 2097152.0; 423622.93333333335; 161.0; 21.6; 0.5333333333333333; 0.4 +1377551874; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 608172.0; 0.0; 2.533333333333333; 0.0; 0.0 +1377552174; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 232082.13333333333; 31.8; 3.533333333333333; 0.0; 0.0 +1377552474; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 149595.2; 0.0; 2.533333333333333; 0.0; 0.0 +1377552774; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 116041.06666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377553074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377553374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377553674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.33333333333; 0.0; 1.2; 0.0; 0.0 +1377553974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377554274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377554574; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 1.5333333333333334; 0.0 +1377554874; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 2.4; 0.0; 0.4666666666666667 +1377555174; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.0; 0.0; 1.2; 0.06666666666666667; 0.0 +1377555474; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377555774; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377556074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377556374; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.06666666666666667; 1.8; 0.13333333333333333; 0.06666666666666667 +1377556674; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377556974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377557274; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377557574; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377557874; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.9333333333333333; 0.0; 0.0 +1377558174; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377558474; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106253.6; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377558774; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 157984.0; 0.0; 0.8; 0.0; 0.0 +1377559074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377559374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377559674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377559974; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377560274; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377560574; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377560874; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1377561174; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377561474; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377561774; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1377562074; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.73333333334; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377562374; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 148197.06666666668; 0.0; 0.7333333333333333; 0.0; 0.0 +1377562674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377562974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377563274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377563574; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1377563874; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377564174; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377564474; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377564774; 1; 2599.99931; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377565074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377565374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377565674; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 123031.2; 0.06666666666666667; 2.0; 0.06666666666666667; 0.4666666666666667 +1377565974; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 177557.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1377566274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377566574; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377566874; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377567175; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377567475; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377567775; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377568075; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377568375; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377568675; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377568975; 1; 2599.99931; 0.0; 0.0; 2097152.0; 148198.13333333333; 0.0; 1.2; 0.0; 0.0 +1377569275; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102059.73333333334; 0.2; 2.066666666666667; 0.0; 0.4666666666666667 +1377569575; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 164974.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1377569875; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377570175; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377570475; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377570775; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377571075; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377571375; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377571675; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 96466.93333333333; 0.0; 1.0; 0.0; 0.0 +1377571975; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377572275; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377572575; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377572875; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 162177.86666666667; 12.8; 14.466666666666667; 0.4; 0.6 +1377573175; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 152391.73333333334; 0.0; 1.4; 0.0; 0.0 +1377573475; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377573776; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377574076; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377574376; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377574676; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377574976; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377575276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377575576; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128624.26666666666; 0.0; 11.8; 0.0; 0.0 +1377575876; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377576176; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1377576476; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102058.66666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377576776; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 170566.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1377577076; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1377577376; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1377577676; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377577976; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377578276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377578576; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377578876; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 97865.33333333333; 0.0; 7.066666666666666; 0.4; 0.13333333333333333 +1377579176; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 148196.53333333333; 0.0; 0.8; 0.0; 0.0 +1377579476; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377579776; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377580076; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113243.73333333334; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377580376; 1; 2599.99931; 0.0; 0.0; 2097152.0; 198528.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377580676; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377580976; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377581276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377581576; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377581876; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377582176; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377582476; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377582776; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377583077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107651.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377583377; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 65708.26666666666; 0.06666666666666667; 1.2; 0.0; 0.0 +1377583677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 92272.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377583977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377584277; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377584577; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377584877; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1377585177; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.8666666666666667; 0.26666666666666666; 0.06666666666666667 +1377585477; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 145401.06666666668; 0.0; 1.5333333333333334; 0.0; 0.0 +1377585777; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377586077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377586377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377586677; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1377586977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377587277; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.0; 0.0; 2.2; 0.2; 0.4666666666666667 +1377587577; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 170566.13333333333; 0.0; 0.6; 0.26666666666666666; 0.0 +1377587877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 +1377588177; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159382.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377588477; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 132818.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1377588776; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 148198.13333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1377589076; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377589376; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1377589676; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1377589976; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 5.2; 0.0 +1377590277; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 118837.33333333333; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1377590577; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377590877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.8; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377591177; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 181751.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377591477; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.6; 0.13333333333333333; 0.0 +1377591777; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377592077; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1377592377; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377592677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377592977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 149595.46666666667; 0.0; 0.6; 0.0; 0.0 +1377593277; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377593577; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377593877; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377594177; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1377594477; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.2; 2.066666666666667; 0.13333333333333333; 0.4666666666666667 +1377594777; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.5333333333333333; 0.0 +1377595077; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.6; 9.4; 0.0 +1377595377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377595677; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377595977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377596277; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 6.8; 0.3333333333333333; 0.13333333333333333 +1377596577; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377596877; 1; 2599.99931; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377597177; 1; 2599.99931; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.8; 0.0; 0.0 +1377597477; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377597777; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377598077; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 2.4; 0.0; 0.5333333333333333 +1377598377; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 137012.26666666666; 0.06666666666666667; 0.9333333333333333; 1.2666666666666666; 0.0 +1377598677; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1377598977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 +1377599277; 1; 2599.99931; 64.13331631333334; 2.466666666666667; 2097152.0; 603977.0666666667; 161.0; 22.8; 0.0; 0.4 +1377599577; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 394262.4; 0.0; 4.8; 0.0; 0.0 +1377599877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 190140.0; 31.8; 3.533333333333333; 0.0; 0.0 +1377600177; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 156586.13333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.0 +1377600477; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.5333333333333334; 0.0; 0.0 +1377600777; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377601077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377601377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377601677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 2.0; 0.0; 0.4666666666666667 +1377601977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377602278; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 113244.8; 0.0; 1.8666666666666667; 0.0; 0.0 +1377602578; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377602878; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377603178; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377603478; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377603778; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377604078; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1377604378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 1.1333333333333333; 0.0 +1377604678; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 2.6666666666666665; 0.0 +1377604978; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377605278; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121632.8; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1377605578; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 187343.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377605878; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377606178; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377606478; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377606778; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377607078; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377607378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377607678; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 74097.06666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1377607978; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377608278; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.7333333333333333; 0.0 +1377608578; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377608878; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 138410.4; 0.06666666666666667; 2.2666666666666666; 80.73333333333333; 0.4666666666666667 +1377609178; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 170566.66666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377609478; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138410.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377609778; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377610078; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377610378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377610678; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377610978; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377611278; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377611578; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377611878; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377612178; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 142604.8; 0.0; 0.8; 10.6; 0.0 +1377612478; 1; 2599.998991; 40.44442874888888; 1.5555555555555554; 2097152.0; 130486.66666666667; 0.0; 3.875; 0.125; 0.875 +1377612778; 1; 2599.998991; 19.066659267333332; 0.7333333333333333; 2097152.0; 201324.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377613078; 1; 2599.998991; 17.33332660666667; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377613378; 1; 2599.999334; 25.99999334; 1.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1377613678; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377613978; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.13333333333333333; 0.13333333333333333 +1377614279; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377614579; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1377614879; 1; 2599.999602; 34.666661360000006; 1.3333333333333335; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1377615179; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377615479; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377615779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377616079; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 150993.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 +1377616379; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 184547.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1377616679; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377616979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377617279; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377617579; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377617879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1377618179; 1; 2599.999602; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377618479; 1; 2599.999602; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.2; 0.0; 0.0 +1377618779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377619079; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377619379; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 11.733333333333333; 0.0; 0.0 +1377619679; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1377619979; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 153789.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377620279; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377620579; 1; 2599.999602; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377620879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377621179; 1; 2599.999602; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377621479; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 90874.66666666667; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1377621779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377622079; 1; 2599.999602; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377622379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377622679; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377622979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377623279; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 121633.6; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377623579; 1; 2599.999602; 0.0; 0.0; 2097152.0; 171964.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377623879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377624179; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1377624479; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377624779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377625079; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377625379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377625679; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 150994.4; 0.0; 0.9333333333333333; 0.6; 0.0 +1377625979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8; 0.0; 0.0 +1377626279; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377626579; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377626879; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377627179; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1377627479; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159381.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377627779; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 113244.8; 0.0; 7.266666666666667; 0.26666666666666666; 0.2 +1377628079; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377628379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377628679; 1; 2599.999602; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377628979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377629279; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377629580; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377629880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377630180; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377630480; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1377630780; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377631080; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377631380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377631680; 1; 2599.999602; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377631980; 1; 2599.999602; 39.866660564; 1.5333333333333334; 2097152.0; 181751.73333333334; 161.06666666666666; 14.266666666666667; 0.13333333333333333; 0.2 +1377632280; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 536869.6; 0.0; 1.2; 0.0; 0.0 +1377632580; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 184548.0; 31.8; 3.8; 0.0; 0.0 +1377632880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 213908.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377633180; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1377633480; 1; 2599.999602; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377633780; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377634080; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 131419.46666666667; 0.06666666666666667; 2.933333333333333; 0.0; 0.5333333333333333 +1377634380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 176159.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377634680; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 171964.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1377634980; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.0; 0.0; 0.0 +1377635280; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1377635580; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377635880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377636180; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377636480; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377636780; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377637080; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377637380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377637680; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377637980; 1; 2599.999602; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 1.0; 0.0; 0.0 +1377638280; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377638581; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 +1377638881; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377639181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377639481; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377639781; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377640081; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377640381; 1; 2599.999602; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1377640681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377640981; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 81087.73333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377641281; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377641581; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 171963.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377641881; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377642181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377642481; 1; 2599.999602; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377642781; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 109050.4; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1377643081; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377643381; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377643681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377643981; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1377644281; 1; 2599.999602; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377644581; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377644881; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1377645181; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 152392.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377645481; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1377645781; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377646081; 1; 2599.999602; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377646381; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 1.0; 0.0; 0.0 +1377646681; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377646981; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 7.733333333333333; 0.2; 0.13333333333333333 +1377647281; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1377647581; 1; 2599.999602; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377647881; 1; 2599.999602; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377648181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377648481; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 102059.73333333334; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377648781; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 160779.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377649081; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 1.1333333333333333; 0.0 +1377649381; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377649681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377649982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 +1377650282; 1; 2599.999602; 60.66665738; 2.3333333333333335; 2097152.0; 592792.2666666667; 161.06666666666666; 21.8; 0.06666666666666667; 0.4 +1377650582; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 596986.9333333333; 0.0; 2.8666666666666667; 0.06666666666666667; 0.0 +1377650882; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 241868.8; 31.8; 3.533333333333333; 0.13333333333333333; 0.0 +1377651182; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 171964.53333333333; 0.0; 2.2666666666666666; 0.06666666666666667; 0.0 +1377651482; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 +1377651782; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377652082; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 82485.33333333333; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1377652382; 1; 2599.999602; 0.0; 0.0; 2097152.0; 137012.53333333333; 0.0; 0.8; 0.0; 0.0 +1377652682; 1; 2599.999602; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377652982; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1377653282; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377653582; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 121633.06666666667; 0.06666666666666667; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377653882; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377654182; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.2; 0.0 +1377654482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1377654782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377655082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1377655382; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377655682; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 145401.33333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377655982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 144003.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377656282; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377656582; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377656882; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159381.6; 0.0; 0.6; 0.0; 0.0 +1377657182; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377657482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377657782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1377658082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377658382; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377658682; 1; 2599.999602; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377658982; 1; 2599.999602; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377659282; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377659582; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 135614.13333333333; 0.0; 1.0; 0.0; 0.0 +1377659882; 1; 2599.999602; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1377660182; 1; 2599.999602; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377660482; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 135614.93333333332; 0.0; 6.733333333333333; 0.26666666666666666; 0.2 +1377660782; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377661082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377661382; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377661682; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1377661982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6; 3.8666666666666667; 0.0 +1377662282; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 125828.0; 0.06666666666666667; 1.6666666666666667; 0.06666666666666667; 0.0 +1377662582; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377662882; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 116040.0; 0.13333333333333333; 13.133333333333333; 0.06666666666666667; 0.4666666666666667 +1377663182; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 166372.0; 0.0; 0.8; 0.0; 0.0 +1377663482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 1.0; 0.0 +1377663782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.6; 0.0; 0.0 +1377664082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377664382; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377664683; 1; 2599.999602; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1377664983; 1; 2599.999602; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377665283; 1; 2599.999602; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377665583; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377665883; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377666183; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377666483; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 127225.06666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1377666783; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 209713.33333333334; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377667083; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377667383; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377667683; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377667983; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377668283; 1; 2599.999602; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.9333333333333333; 0.8666666666666667; 0.0 +1377668583; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109049.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377668883; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.7333333333333333; 0.0 +1377669183; 1; 2599.999602; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377669483; 1; 2599.999602; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377669783; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.3333333333333333; 0.0 +1377670083; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 81087.73333333334; 0.0; 2.7333333333333334; 0.0; 0.4666666666666667 +1377670383; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377670683; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377670983; 1; 2599.999602; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377671283; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.2; 0.0 +1377671583; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 2.1333333333333333; 0.13333333333333333; 0.13333333333333333 +1377671883; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.5333333333333334; 0.3333333333333333; 0.0 +1377672183; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 137013.06666666668; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377672483; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142604.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377672783; 1; 2599.9993; 25.999993; 1.0; 2097152.0; 62912.0; 0.0; 1.125; 0.0; 0.0 +1377673083; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377673383; 1; 2599.9993; 12.133330066666666; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 7.0; 0.26666666666666666; 0.2 +1377673683; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 123030.93333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377673983; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377674283; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377674583; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377674883; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377675183; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377675483; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.06666666666666667; 0.0 +1377675783; 1; 2599.9993; 0.0; 0.0; 2097152.0; 61513.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377676083; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1377676383; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377676684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377676984; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377677284; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 135614.13333333333; 0.2; 2.4; 0.0; 0.5333333333333333 +1377677584; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377677884; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377678184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377678484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377678784; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377679084; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377679384; 1; 2599.9993; 17.33332866666667; 0.6666666666666667; 2097152.0; 74097.06666666667; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377679684; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 150993.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377679984; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377680284; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377680584; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377680884; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 120234.66666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377681184; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377681484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377681784; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377682084; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377682384; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377682684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377682984; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 123030.66666666667; 0.0; 1.8666666666666667; 0.0; 0.06666666666666667 +1377683284; 1; 2599.9993; 24.266660133333332; 0.9333333333333332; 2097152.0; 184548.0; 0.0; 3.6666666666666665; 0.0; 0.0 +1377683584; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.8666666666666667; 0.0; 0.0 +1377683884; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1377684184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377684484; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377684784; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 153789.86666666667; 0.0; 7.0; 0.2; 0.13333333333333333 +1377685084; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377685384; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377685684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377685984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377686284; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1377686584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377686884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377687184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377687484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377687784; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377688084; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 100661.6; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1377688384; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377688684; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377688984; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377689284; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377689584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377689884; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377690184; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377690484; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377690784; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 157983.46666666667; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 +1377691084; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 130020.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377691384; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1377691684; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 109050.4; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377691984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377692284; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377692584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377692884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377693184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377693484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377693784; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377694084; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377694384; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377694684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377694984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377695284; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 120234.93333333333; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377695584; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 170567.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377695884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.13333333333333333; 0.0 +1377696184; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377696484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.2; 0.0 +1377696785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1377697085; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 124429.06666666667; 12.933333333333334; 13.133333333333333; 0.4666666666666667; 0.13333333333333333 +1377697385; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1377697685; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1377697985; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377698285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377698585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377698885; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 121633.6; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1377699185; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155188.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377699485; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377699785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377700085; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377700385; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 149595.46666666667; 0.06666666666666667; 1.4666666666666666; 0.13333333333333333; 0.06666666666666667 +1377700685; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377700985; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377701285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377701585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377701885; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377702185; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377702485; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 107652.26666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377702785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377703085; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377703385; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377703685; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377703985; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 123031.73333333334; 0.0; 6.8; 0.2; 0.13333333333333333 +1377704285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377704585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377704885; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377705185; 1; 2599.9993; 74.53331326666667; 2.8666666666666667; 2097152.0; 657105.6; 161.33333333333334; 22.2; 0.26666666666666666; 0.4 +1377705485; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 374688.26666666666; 0.0; 5.133333333333334; 1.2666666666666666; 0.0 +1377705785; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 218101.33333333334; 31.8; 3.4; 0.0; 0.0 +1377706085; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 160780.53333333333; 0.0; 3.8; 0.0; 0.5333333333333333 +1377706385; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.3333333333333333; 0.0; 0.0 +1377706685; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 139809.33333333334; 0.0; 11.533333333333333; 0.0; 0.0 +1377706986; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377707286; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1377707586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377707886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1377708186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377708486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377708786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1377709086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377709386; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 102059.73333333334; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 +1377709686; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 152392.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377709986; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1377710286; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377710586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377710886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377711186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377711486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377711786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377712086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377712386; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377712686; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1377712986; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377713286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 110448.26666666666; 0.2; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1377713586; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142604.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377713886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377714186; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 111846.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377714486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377714786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377715086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377715386; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377715686; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130021.6; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377715987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377716287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1377716587; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1377716887; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377717187; 1; 2599.9993; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377717487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377717787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377718087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377718387; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 88078.4; 161.73333333333332; 13.333333333333334; 0.0; 0.06666666666666667 +1377718687; 1; 2599.9993; 38.13332306666666; 1.4666666666666666; 2097152.0; 517296.0; 0.0; 2.2666666666666666; 0.0; 0.06666666666666667 +1377718987; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 223694.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1377719286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 197129.33333333334; 31.8; 3.8666666666666667; 0.0; 0.0 +1377719586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 0.8; 0.0; 0.0 +1377719886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377720186; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 132818.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1377720486; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 141206.66666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377720786; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 169168.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377721086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377721386; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377721686; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1377721986; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377722286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 104856.0; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377722586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377722886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377723186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377723486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377723787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377724087; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 88078.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1377724387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 148196.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377724687; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377724987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377725287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 162177.33333333334; 0.0; 0.8; 0.0; 0.0 +1377725587; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377725887; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1377726187; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377726487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377726787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377727087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377727387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377727687; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127225.86666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377727987; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 170566.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377728287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377728587; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 128624.26666666666; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1377728887; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377729187; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.06666666666666667 +1377729487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377729787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377730087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138409.86666666667; 0.0; 0.8; 0.0; 0.0 +1377730387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377730687; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377730987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377731288; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.4666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377731588; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377731888; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377732188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377732488; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377732788; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377733088; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 67106.4; 0.0; 1.0; 0.0; 0.0 +1377733388; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377733688; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377733988; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377734288; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377734588; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377734888; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 111846.66666666667; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377735188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 171964.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377735488; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 146799.2; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1377735788; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1377736088; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377736388; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130022.4; 0.0; 1.4; 0.0; 0.0 +1377736688; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377736988; 1; 2599.9993; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377737288; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377737588; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377738188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 +1377738489; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106253.33333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377738789; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 149594.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377739089; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377739389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377739689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377739989; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377740289; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377740589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377740889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377741189; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 144002.66666666666; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1377741489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377741789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377742089; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377742389; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377742689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377742989; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377743289; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377743589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377743889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377744189; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377744489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377744789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377745089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377745389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377745689; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 131420.53333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377745989; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 171964.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377746289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377746589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377746889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377747189; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377747489; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.2; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 +1377747789; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377748089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377748389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1377748690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377748990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377749290; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377749590; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377749890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377750190; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.0; 11.933333333333334; 0.0; 0.0 +1377750490; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377750790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377751090; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377751390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377751690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377751990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377752289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377752589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377752889; 1; 2599.9993; 12.133330066666666; 0.4666666666666666; 2097152.0; 142604.53333333333; 0.0; 8.8; 0.26666666666666666; 0.6666666666666666 +1377753189; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 171965.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377753489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377753789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377754089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377754389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377754689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8; 0.0; 0.0 +1377754989; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377755289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377755589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377755890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377756190; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377756490; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 103456.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377756790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 159381.6; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 +1377757090; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377757390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377757690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377757990; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.9333333333333333; 0.06666666666666667; 0.06666666666666667 +1377758290; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.6; 0.0; 0.0 +1377758590; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1377758890; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 149594.66666666666; 12.733333333333333; 12.866666666666667; 0.26666666666666666; 0.13333333333333333 +1377759190; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.4; 0.0; 0.0 +1377759490; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377759790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377760090; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1377760390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 176158.4; 0.0; 0.8; 0.0; 0.0 +1377760690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8; 0.0; 0.0 +1377760990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377761290; 1; 2599.9993; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.0; 0.0; 0.0 +1377761590; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1377761890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377762190; 1; 2599.9993; 57.19998460000001; 2.2; 2097152.0; 634736.5333333333; 161.06666666666666; 22.533333333333335; 0.06666666666666667; 0.4 +1377762490; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 507508.8; 0.0; 2.7333333333333334; 0.0; 0.0 +1377762790; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 260044.8; 31.8; 3.8666666666666667; 0.0; 0.0 +1377763090; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 159382.4; 0.0; 2.2; 0.0; 0.0 +1377763390; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.0; 0.0 +1377763690; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377763990; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 163576.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377764290; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377764590; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377764890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377765191; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377765491; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1377765791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377766091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1377766391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377766691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1377766991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377767291; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 180353.06666666668; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377767591; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 216704.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377767891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377768191; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377768491; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377768791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377769091; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377769391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1377769691; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 57319.46666666667; 0.0; 1.2; 0.0; 0.0 +1377769991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 +1377770291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377770591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377770891; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1377771191; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1377771491; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377771791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377772091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.06666666666666667; 6.666666666666667; 0.2; 0.13333333333333333 +1377772391; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1377772691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377772991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.0; 0.0; 0.8; 0.0; 0.0 +1377773291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.13333333333; 0.0; 1.0; 0.0; 0.0 +1377773591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377773891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377774191; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1377774491; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.0; 2.2; 0.0; 0.4666666666666667 +1377774791; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 197130.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377775091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1377775391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377775691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377775991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377776291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377776591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377776892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 +1377777192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377777492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377777792; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377778092; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377778392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1377778692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377778992; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377779292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377779592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377779892; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377780192; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377780492; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1377780792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377781092; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.6; 4.066666666666666; 0.0 +1377781392; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.6; 0.0; 0.0 +1377781692; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377781992; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 166372.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377782292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1377782592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.0; 0.0 +1377782892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377783192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377783492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377783792; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377784092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377784392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377784692; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106254.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1377784992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1377785292; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377785591; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 159381.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377785891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377786192; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377786492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1377786792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 1.4; 0.06666666666666667; 0.13333333333333333 +1377787092; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377787392; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1377787692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377787992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377788292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377788592; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.06666666666666667; 1.0; 0.0; 0.0 +1377788892; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.26666666666666666; 0.4666666666666667 +1377789192; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 162177.86666666667; 0.0; 0.8; 0.0; 0.0 +1377789492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377789792; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377790092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377790392; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124429.06666666667; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377790692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377790992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377791292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377791592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377791892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377792192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377792492; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.93333333333; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377792792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 146798.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377793092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377793392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377793692; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377793992; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377794292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377794592; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377794892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.0; 0.0 +1377795192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377795492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377795793; 1; 2599.9993; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377796093; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377796393; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 159381.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377796693; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377796993; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377797293; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377797593; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377797893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377798193; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377798493; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377798793; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377799093; 1; 2599.9993; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377799393; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377799693; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 81087.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377799993; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377800293; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377800593; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377800893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 169168.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377801193; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377801493; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377801793; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377802093; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377802393; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377802693; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377802993; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377803293; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 99263.46666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377803593; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 160779.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377803893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377804194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377804494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377804794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.8; 0.0; 0.0 +1377805094; 1; 2599.9993; 39.866655933333334; 1.5333333333333334; 2097152.0; 436205.86666666664; 161.0; 14.2; 0.0; 0.2 +1377805394; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 257248.26666666666; 0.0; 1.4; 0.0; 0.0 +1377805694; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 184547.73333333334; 31.8; 3.7333333333333334; 0.0; 0.0 +1377805994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155187.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377806294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377806594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 +1377806894; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377807194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 153789.06666666668; 0.0; 0.5333333333333333; 0.0; 0.0 +1377807494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 169169.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377807794; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 131420.26666666666; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 +1377808094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130021.86666666667; 0.0; 0.6; 0.0; 0.0 +1377808394; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377808694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377808994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377809294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1377809594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.0; 0.0 +1377809894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1377810194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 +1377810494; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124429.06666666667; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1377810794; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 180353.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377811094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377811394; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1377811694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 +1377811994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377812294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377812594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 163576.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377812894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377813194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377813494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377813794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377814094; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 92272.8; 0.0; 8.0; 0.3333333333333333; 0.6666666666666666 +1377814395; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1377814695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377814995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377815295; 1; 2599.9993; 17.33332866666667; 0.6666666666666667; 2097152.0; 160780.53333333333; 161.0; 20.6; 0.06666666666666667; 0.4 +1377815595; 1; 2599.9993; 48.533320266666664; 1.8666666666666665; 2097152.0; 781536.8; 0.0; 4.2; 0.06666666666666667; 0.13333333333333333 +1377815895; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 367698.93333333335; 31.8; 3.0; 0.0; 0.0 +1377816195; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 219500.0; 0.0; 2.6; 0.0; 0.0 +1377816495; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 +1377816795; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377817095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377817395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377817694; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.66666666667; 0.2; 2.7333333333333334; 0.0; 0.4666666666666667 +1377817994; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 157982.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377818294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377818594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377818894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377819194; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.2; 1.0; 0.0; 0.0 +1377819494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377819794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377820094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 1.2; 0.0; 0.0 +1377820394; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 170566.66666666666; 12.733333333333333; 16.8; 0.4; 0.13333333333333333 +1377820694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1377820994; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377821294; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.13333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377821594; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 157983.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377821894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377822194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377822494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377822794; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 146800.0; 0.0; 1.4; 0.0; 0.0 +1377823094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377823394; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377823694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377823994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377824294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377824595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377824895; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 117438.93333333333; 0.0; 3.2; 0.06666666666666667; 0.4666666666666667 +1377825195; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 145400.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377825495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377825795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377826095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377826395; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 7.2; 0.2; 0.13333333333333333 +1377826695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377826995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377827295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377827595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377827895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377828195; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377828495; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130021.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377828795; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 167771.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377829095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377829395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377829695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377829995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377830295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377830595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377830895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377831195; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377831495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377831795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1377832095; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 125826.93333333333; 0.06666666666666667; 8.6; 0.2; 0.6 +1377832395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377832695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377832995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377833295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377833595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 159382.13333333333; 0.0; 0.8; 0.0; 0.0 +1377833895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377834195; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377834495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1377834795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377835095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1377835395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377835695; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 103457.86666666667; 0.0; 2.2; 0.0; 0.4666666666666667 +1377835996; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377836296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377836596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377836896; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377837196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377837496; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 11.733333333333333; 0.0; 0.0 +1377837796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377838096; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127226.13333333333; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377838396; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377838696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377838996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377839296; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 89476.53333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1377839596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377839896; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377840196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377840496; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377840796; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.86666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377841096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1377841396; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377841696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377841996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377842296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377842596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377842896; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 113244.8; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377843196; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 159382.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377843496; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1377843796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377844096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106253.6; 0.0; 0.8; 0.0; 0.0 +1377844396; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 141205.86666666667; 0.0; 1.9333333333333333; 0.06666666666666667; 0.13333333333333333 +1377844696; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130022.4; 0.0; 1.4666666666666666; 0.0; 0.0 +1377844997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377845297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377845597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377845897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377846197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377846497; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377846797; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377847097; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377847397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377847697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377847997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377848297; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1377848597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1377848897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1377849197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377849497; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1377849797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377850097; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377850397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 +1377850696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.06666666666666667; 0.0 +1377850996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377851296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377851596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377851896; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377852196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377852496; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377852796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377853096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 +1377853396; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377853696; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377853996; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 159383.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377854297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100660.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377854597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377854897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377855197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377855497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377855797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.13333333333333333; 0.0 +1377856097; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 144003.73333333334; 0.2; 7.133333333333334; 0.2; 0.13333333333333333 +1377856397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1377856697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.3333333333333333; 0.0 +1377856997; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1377857297; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127225.06666666667; 0.0; 1.8666666666666667; 0.0; 0.4666666666666667 +1377857597; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377857897; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377858197; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377858497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377858797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377859097; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377859397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377859697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377859997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377860297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 +1377860597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377860897; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 125827.46666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377861197; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 192935.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377861497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1377861797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377862097; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 6.866666666666666; 0.4; 0.13333333333333333 +1377862397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377862698; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1377862998; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1377863298; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377863598; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377863898; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377864198; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377864498; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 128624.26666666666; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377864798; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 156586.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377865098; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377865398; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377865698; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.2; 0.0 +1377865998; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377866298; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377866598; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377866898; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 3.066666666666667; 0.0 +1377867198; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377867498; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377867798; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.2; 0.0 +1377868098; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 181750.93333333332; 0.06666666666666667; 8.533333333333333; 0.4; 0.6 +1377868398; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 208315.2; 0.0; 1.0; 0.13333333333333333; 0.0 +1377868698; 1; 2599.9993; 60.66665033333334; 2.3333333333333335; 2097152.0; 227889.33333333334; 161.06666666666666; 21.933333333333334; 0.06666666666666667; 0.4 +1377868998; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 673882.4; 0.0; 2.466666666666667; 0.06666666666666667; 0.0 +1377869298; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 285210.13333333336; 31.8; 4.466666666666667; 0.06666666666666667; 0.0 +1377869598; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 208314.4; 0.0; 2.2666666666666666; 0.0; 0.0 +1377869898; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 149596.26666666666; 0.0; 1.6; 0.0; 0.0 +1377870198; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377870498; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.26666666666666666; 0.0 +1377870798; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 139808.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377871098; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377871398; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377871698; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377871998; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 174760.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377872299; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377872599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377872899; 1; 2599.9993; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377873199; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.4; 0.06666666666666667; 0.06666666666666667 +1377873499; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377873799; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1377874099; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377874399; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377874699; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 6.666666666666667; 0.0 +1377874999; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 6.0; 0.3333333333333333; 0.13333333333333333 +1377875299; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 150993.86666666667; 0.0; 3.2; 0.0; 0.5333333333333333 +1377875599; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 160780.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377875899; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 96467.2; 0.0; 0.8; 0.13333333333333333; 0.0 +1377876199; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377876499; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.4; 0.0 +1377876799; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377877099; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377877399; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377877699; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377877999; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377878299; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377878599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377878899; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 95068.53333333334; 0.06666666666666667; 2.7333333333333334; 0.13333333333333333; 0.4666666666666667 +1377879199; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124428.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377879499; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377879799; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377880100; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377880400; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377880700; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377881000; 1; 2599.9993; 15.599995799999999; 0.6; 2097152.0; 128624.26666666666; 12.8; 23.933333333333334; 0.3333333333333333; 0.2 +1377881300; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377881600; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1377881900; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377882200; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377882500; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 79689.6; 0.06666666666666667; 2.6; 0.2; 0.4666666666666667 +1377882800; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1377883100; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 109050.4; 0.0; 1.0; 0.13333333333333333; 0.0 +1377883399; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.06666666666666667; 0.0 +1377883699; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377883999; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377884299; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1377884599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377884899; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1377885199; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377885499; 1; 2599.9993; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377885799; 1; 2599.999602; 11.99999816307692; 0.4615384615384615; 2097152.0; 96789.84615384616; 0.0; 0.8333333333333334; 0.0; 0.0 +1377886099; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 162178.4; 0.06666666666666667; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377886400; 1; 2599.999602; 0.0; 0.0; 2097152.0; 163575.46666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377886700; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 162178.66666666666; 0.0; 7.0; 0.26666666666666666; 0.2 +1377887000; 1; 2599.999602; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377887300; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377887600; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 119836.0; 0.0; 0.8461538461538461; 0.07692307692307693; 0.0 +1377887900; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377888200; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377888500; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377888800; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.5333333333333333; 0.0 +1377889100; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377889400; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377889700; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377890000; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 157984.26666666666; 0.0; 0.8; 0.0; 0.0 +1377890300; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377890600; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377890900; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377891200; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377891500; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 462770.4; 161.06666666666666; 14.533333333333333; 0.06666666666666667; 0.2 +1377891800; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 276821.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1377892100; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 212510.13333333333; 31.8; 4.0; 0.0; 0.0 +1377892400; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150994.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377892700; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377893000; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 124429.86666666667; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 +1377893300; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142604.26666666666; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 +1377893600; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1377893900; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377894200; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377894500; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.4666666666666667; 0.0 +1377894800; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377895100; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 1.0666666666666667; 0.0 +1377895400; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377895700; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377896000; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377896300; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377896600; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377896901; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 141207.46666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1377897201; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1377897501; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377897801; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377898101; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377898401; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 79689.6; 0.0; 0.8; 0.2; 0.0 +1377898701; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377899001; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377899301; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377899601; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377899901; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377900201; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377900501; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.13333333333; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1377900801; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 159381.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377901101; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118836.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377901401; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106253.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377901701; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1377902001; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.06666666666666667; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 +1377902301; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377902601; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377902901; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377903201; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377903502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377903802; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377904102; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 156585.6; 0.26666666666666666; 2.0; 0.06666666666666667; 0.4666666666666667 +1377904402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 176159.46666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377904702; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377905002; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1377905302; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139808.53333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1377905602; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377905902; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377906202; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377906502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1377906802; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377907102; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377907402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377907702; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 125827.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1377908002; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 169168.0; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377908302; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377908602; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377908902; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377909202; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1377909502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377909802; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 +1377910102; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1377910402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377910702; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377911002; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377911302; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 139808.0; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377911602; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152391.2; 0.06666666666666667; 0.7333333333333333; 0.0; 0.0 +1377911902; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 123031.46666666666; 0.0; 7.2; 0.2; 0.13333333333333333 +1377912202; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377912502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377912802; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377913102; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377913402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377913702; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377914003; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 1.6; 0.0; 0.0 +1377914303; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377914603; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377914903; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1377915203; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1377915503; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377915803; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1377916102; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1377916402; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377916702; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377917002; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377917302; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377917602; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377917902; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377918202; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120234.4; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1377918502; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377918802; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377919102; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 5.133333333333334; 0.0 +1377919402; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377919702; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377920002; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1377920302; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377920602; 1; 2599.999343; 67.59998291800001; 2.6; 2097152.0; 336940.0; 161.0; 21.8; 0.06666666666666667; 0.4 +1377920903; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 634736.0; 0.0; 2.7333333333333334; 0.0; 0.0 +1377921203; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 292201.3333333333; 31.8; 3.4; 0.06666666666666667; 0.0 +1377921503; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 205517.86666666667; 0.0; 2.3333333333333335; 0.0; 0.0 +1377921803; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.6; 0.0; 1.5333333333333334; 0.0; 0.0 +1377922103; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139808.53333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377922403; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 166372.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377922703; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.6; 0.0; 0.0 +1377923003; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377923303; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1377923603; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377923903; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.6; 0.0; 0.0 +1377924203; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377924503; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 61513.86666666667; 0.0; 1.0; 0.0; 0.0 +1377924803; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 71300.8; 0.0; 11.666666666666666; 0.0; 0.0 +1377925103; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 6.2; 0.2; 0.13333333333333333 +1377925403; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.7333333333333334; 0.0; 0.0 +1377925703; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.6; 0.06666666666666667; 2.533333333333333; 0.13333333333333333; 0.5333333333333333 +1377926003; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 226490.13333333333; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377926303; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377926603; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377926903; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377927203; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377927503; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377927803; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377928103; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377928403; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377928703; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377929003; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1377929303; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134215.73333333334; 0.06666666666666667; 2.2666666666666666; 0.2; 0.5333333333333333 +1377929604; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377929904; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377930204; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377930504; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377930804; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 8.133333333333333; 0.26666666666666666; 0.2 +1377931104; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.4; 0.0; 0.0 +1377931404; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377931704; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377932004; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377932304; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 +1377932604; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377932904; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377933204; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377933504; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377933804; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377934104; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377934404; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377934704; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377935004; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1377935304; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1377935604; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377935904; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377936204; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377936504; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130021.6; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377936804; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 152390.93333333332; 0.0; 6.8; 0.2; 0.13333333333333333 +1377937104; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.06666666666666667; 1.5333333333333334; 0.06666666666666667; 0.0 +1377937404; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377937704; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377938004; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377938304; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377938604; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377938905; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377939205; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 1.2; 0.0 +1377939505; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121632.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377939805; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377940105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 135613.6; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377940405; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 176160.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377940705; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377941005; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377941305; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377941605; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377941905; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377942205; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377942505; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 142604.8; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.2 +1377942805; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377943105; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377943405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377943705; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 103457.86666666667; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1377944005; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377944305; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377944605; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377944905; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377945205; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377945505; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 0.8; 0.0; 0.0 +1377945805; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377946105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377946405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377946706; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1377947006; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377947306; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377947606; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 188741.6; 0.0; 0.8; 0.0; 0.0 +1377947906; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 117439.2; 0.0; 1.0; 3.066666666666667; 0.0 +1377948206; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 64310.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377948506; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377948805; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377949105; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 152391.73333333334; 0.0; 7.466666666666667; 0.26666666666666666; 0.13333333333333333 +1377949405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1377949705; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 118836.26666666666; 0.0; 1.0; 0.0; 0.0 +1377950005; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130021.33333333333; 0.0; 0.6; 0.0; 0.0 +1377950305; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377950605; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1377950905; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 125828.0; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1377951205; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 +1377951505; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377951805; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377952105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109049.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1377952405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377952705; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377953005; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377953306; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377953606; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377953906; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377954206; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377954506; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142604.0; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377954806; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 167770.4; 0.0; 1.0; 0.0; 0.0 +1377955106; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377955406; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377955706; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377956006; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 118837.33333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377956306; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 178954.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377956606; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377956906; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377957206; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377957506; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377957806; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377958106; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.33333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377958406; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 173363.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377958706; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377959006; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377959306; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377959606; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.13333333333333333 +1377959906; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377960206; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377960506; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377960806; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377961106; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377961406; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377961706; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1377962006; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141206.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377962307; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377962607; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 +1377962907; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 +1377963207; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377963507; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377963807; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377964107; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377964407; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121632.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377964707; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377965007; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 50328.8; 0.0; 0.8; 0.0; 0.0 +1377965307; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.86666666667; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1377965607; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 171964.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377965907; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377966207; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377966507; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377966807; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377967107; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377967407; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377967707; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377968007; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 142604.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377968307; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 0.0; 17.666666666666668; 0.2; 0.13333333333333333 +1377968607; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377968907; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377969207; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1377969507; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377969807; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377970107; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377970407; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377970707; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377971007; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377971307; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 75495.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377971607; 1; 2599.999343; 67.59998291800001; 2.6; 2097152.0; 232082.93333333332; 161.0; 21.866666666666667; 0.13333333333333333; 0.3333333333333333 +1377971907; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 727010.4; 0.0; 2.466666666666667; 0.0; 0.0 +1377972207; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 279618.4; 31.8; 3.6; 1.1333333333333333; 0.0 +1377972507; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 191537.6; 0.0; 3.6; 0.06666666666666667; 0.4666666666666667 +1377972807; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 164974.93333333332; 0.0; 1.6; 0.0; 0.0 +1377973107; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1377973407; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1377973707; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1377974008; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377974308; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377974608; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377974908; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377975208; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377975508; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377975808; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377976108; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 149595.46666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1377976408; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 181751.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377976708; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377977008; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377977308; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1377977608; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377977908; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 387272.0; 161.06666666666666; 14.6; 0.0; 0.2 +1377978208; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 315969.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377978508; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 155188.0; 31.8; 3.8666666666666667; 0.0; 0.0 +1377978808; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377979108; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377979408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377979708; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130021.06666666667; 0.06666666666666667; 3.0; 0.06666666666666667; 0.4666666666666667 +1377980008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377980308; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 7.2; 0.2; 0.13333333333333333 +1377980608; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377980908; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377981208; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377981508; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377981808; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1377982108; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377982408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377982708; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377983008; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377983308; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.86666666667; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377983608; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377983908; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377984208; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377984508; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377984808; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377985108; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377985408; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377985708; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 149596.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377986008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 155188.26666666666; 0.0; 0.8; 0.0; 0.0 +1377986308; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 131420.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377986608; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377986908; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.7333333333333333 +1377987208; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377987508; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 148197.33333333334; 169.66666666666666; 179.2; 0.0; 0.0 +1377987808; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 243268.0; 0.0; 1.2; 0.0; 0.0 +1377988108; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 145401.33333333334; 0.0; 1.0; 0.0; 0.0 +1377988408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 +1377988708; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377989008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1377989309; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377989609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 1.0; 0.0; 0.0 +1377989909; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377990209; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377990509; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377990809; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377991109; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377991409; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377991709; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377992009; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377992309; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377992609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377992909; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377993209; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377993509; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377993809; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377994109; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 164974.66666666666; 0.0; 8.6; 0.26666666666666666; 0.6 +1377994409; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 185944.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377994709; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377995009; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86679.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377995309; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377995609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1377995909; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377996209; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377996509; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377996809; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377997109; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 +1377997409; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1377997709; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1377998009; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 +1377998310; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1377998610; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377998910; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1377999210; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 1.0; 0.0; 0.0 +1377999510; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377999810; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.06666666666666667; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378000110; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1378000410; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378000710; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378001010; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1378001310; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 124428.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1378001610; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 177556.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378001910; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110447.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378002210; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1378002510; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 163576.53333333333; 0.0; 0.6; 0.0; 0.0 +1378002810; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.13333333333; 0.0; 1.5333333333333334; 0.13333333333333333; 0.0 +1378003110; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1378003410; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378003710; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378004010; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 145400.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378004310; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378004610; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1378004910; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127225.06666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1378005210; 1; 2599.999343; 327.599917218; 12.6; 2097152.0; 534072.8; 34.2; 753.7333333333333; 149.46666666666667; 32.13333333333333 +1378005510; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 322958.93333333335; 0.0; 1.4; 0.0; 0.0 +1378005810; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378006110; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378006410; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1378006711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 12.733333333333333; 13.133333333333333; 0.3333333333333333; 0.2 +1378007011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378007311; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1378007611; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378007911; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378008211; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378008511; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.13333333333333333; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378008811; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 199926.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378009111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 137012.26666666666; 0.0; 1.0; 0.0; 0.0 +1378009411; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378009711; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378010011; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378010311; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1378010611; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378010911; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378011211; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378011511; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1378011811; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378012111; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 113243.46666666666; 0.13333333333333333; 13.533333333333333; 0.0; 0.4666666666666667 +1378012411; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174761.06666666668; 0.0; 6.133333333333334; 0.2; 0.13333333333333333 +1378012711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 156586.93333333332; 0.0; 1.9333333333333333; 0.0; 0.0 +1378013011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1378013311; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378013611; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378013912; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378014211; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 +1378014511; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378014811; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378015111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378015411; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378015711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378016011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 167771.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378016311; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378016611; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378016911; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378017211; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 2.6; 0.06666666666666667; 0.13333333333333333 +1378017511; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 159381.6; 0.0; 1.8666666666666667; 0.0; 0.0 +1378017811; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378018111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378018411; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1378018711; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 6.066666666666666; 0.2; 0.13333333333333333 +1378019011; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 2.066666666666667; 0.0; 0.0 +1378019312; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1378019612; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 +1378019912; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378020212; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378020512; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378020812; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378021112; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.3333333333333333; 0.0 +1378021412; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378021712; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.2; 0.0 +1378022012; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141206.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378022312; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378022612; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378022912; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.2; 2.4; 0.06666666666666667; 0.5333333333333333 +1378023212; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378023512; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 0.13333333333333333; 0.0 +1378023812; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378024112; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378024412; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.8; 0.13333333333333333; 0.0 +1378024712; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378025012; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378025312; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 6.266666666666667; 0.3333333333333333; 0.2 +1378025612; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 192936.0; 0.0; 2.1333333333333333; 0.0; 0.0 +1378025912; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378026212; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378026512; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 149596.26666666666; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378026812; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 171964.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378027112; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378027412; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378027713; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378028013; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378028313; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 156586.13333333333; 0.0; 1.2; 0.0; 0.0 +1378028613; 1; 2599.999343; 69.33331581333334; 2.666666666666667; 2097152.0; 422225.06666666665; 161.0; 21.933333333333334; 0.06666666666666667; 0.4 +1378028913; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 603977.6; 0.0; 2.6; 0.06666666666666667; 0.0 +1378029213; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 226489.6; 31.8; 3.6; 0.0; 0.0 +1378029513; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 184548.0; 0.8; 2.6; 0.0; 0.0 +1378029813; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1378030113; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 2.3333333333333335; 1.4666666666666666; 0.5333333333333333 +1378030413; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 174761.33333333334; 0.0; 1.0; 0.0; 0.0 +1378030713; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378031013; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159381.6; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378031313; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378031613; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378031913; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378032213; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378032513; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378032813; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378033113; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1378033413; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378033713; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378034013; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170566.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378034313; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378034613; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.06666666666666667; 1.4; 0.13333333333333333; 0.0 +1378034913; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.0 +1378035214; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378035514; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378035814; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 131419.73333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378036114; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378036414; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378036714; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1378037014; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378037314; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378037614; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1378037914; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378038214; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378038514; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378038814; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378039114; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1378039414; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378039714; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1378040014; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 60115.73333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378040314; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1378040614; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378040914; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128623.73333333334; 0.0; 2.4; 0.13333333333333333; 0.5333333333333333 +1378041214; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 1.0; 0.0; 0.0 +1378041514; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378041814; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1378042114; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.33333333333; 0.0; 7.4; 0.2; 0.13333333333333333 +1378042414; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378042715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378043015; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378043315; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1378043615; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378043915; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378044215; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378044515; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.06666666667; 0.06666666666666667; 2.533333333333333; 0.13333333333333333; 0.4666666666666667 +1378044815; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 159382.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378045115; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378045415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378045715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378046015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1378046315; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1378046615; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378046915; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378047215; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 149594.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378047515; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.8666666666666667; 0.0; 0.0 +1378047815; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378048115; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 176157.86666666667; 0.0; 8.333333333333334; 0.26666666666666666; 0.6 +1378048415; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378048715; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378049015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378049315; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378049615; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 164974.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378049915; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378050215; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378050515; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.4; 0.0; 0.0 +1378050815; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378051115; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378051415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 164975.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378051715; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150992.8; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378052015; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378052315; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 +1378052615; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378052915; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378053215; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378053515; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378053815; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378054115; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378054415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378054715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 72698.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378055015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125827.2; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378055315; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 167770.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378055615; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144002.93333333332; 0.0; 12.0; 0.0; 0.0 +1378055916; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378056216; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378056516; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378056816; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378057116; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378057416; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378057716; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378058016; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378058316; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378058616; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1378058916; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 176159.2; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1378059216; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 222296.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378059516; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1378059816; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378060116; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1378060416; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378060716; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.06666666666666667; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378061016; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 160779.73333333334; 0.06666666666666667; 1.9333333333333333; 0.0; 0.0 +1378061316; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378061616; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378061916; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378062216; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 1.4; 1.3333333333333333; 0.0; 0.0 +1378062516; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378062816; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378063116; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378063416; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1378063716; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378064017; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 163576.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378064317; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 303386.4; 161.66666666666666; 14.466666666666667; 0.0; 0.2 +1378064617; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 373291.2; 0.0; 1.4; 0.0; 0.0 +1378064917; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 204120.53333333333; 31.8; 4.0; 0.0; 0.0 +1378065217; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 188741.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378065517; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378065817; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378066117; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378066417; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378066717; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378067017; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378067317; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 150993.6; 12.866666666666667; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1378067617; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 184547.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378067917; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378068217; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378068517; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1378068817; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1378069117; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1378069417; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378069717; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.2; 3.2; 0.06666666666666667; 0.4666666666666667 +1378070017; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.06666666666666667; 0.8; 0.0; 0.0 +1378070317; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378070617; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378070917; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378071217; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1378071517; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.6; 0.0; 1.2; 0.0; 0.0 +1378071817; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378072117; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378072418; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 +1378072718; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 6.8; 0.2; 0.13333333333333333 +1378073018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 173362.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378073318; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144003.46666666667; 0.0; 2.4; 0.2; 0.4666666666666667 +1378073618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 153789.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378073918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378074218; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378074518; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378074818; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.06666666667; 0.0; 1.4; 0.06666666666666667; 0.13333333333333333 +1378075118; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378075418; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1378075718; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 +1378076018; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378076318; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378076618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.2; 1.4; 0.0; 0.0 +1378076918; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139807.73333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378077218; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 223694.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378077518; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378077818; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378078118; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378078418; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 141207.46666666667; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 +1378078718; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378079018; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378079318; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1378079618; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378079918; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378080218; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378080518; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 155188.0; 0.06666666666666667; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 +1378080818; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 149594.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378081118; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378081418; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378081718; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378082018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.6; 1.7333333333333334; 0.0; 0.0 +1378082318; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378082618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378082918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378083218; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378083518; 1; 2599.999343; 51.99998686; 2.0; 2097152.0; 160779.73333333334; 161.0; 22.066666666666666; 0.2; 0.3333333333333333 +1378083818; 1; 2599.999343; 36.399990802; 1.4; 2097152.0; 598384.8; 0.0; 2.7333333333333334; 0.0; 0.0 +1378084118; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 282414.6666666667; 32.6; 5.066666666666666; 0.06666666666666667; 0.5333333333333333 +1378084418; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 209713.33333333334; 0.0; 2.6; 0.0; 0.0 +1378084718; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153790.66666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378085018; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378085318; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1378085618; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1378085918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378086218; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378086518; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378086818; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378087118; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378087418; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378087718; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 167770.4; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378088018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 192936.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378088319; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157985.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378088619; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150994.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378088919; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1378089219; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378089519; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378089819; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1378090119; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378090419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 142605.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1378090719; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1378091019; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378091319; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1378091619; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170567.46666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378091919; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.7333333333333334; 0.0; 0.0 +1378092219; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 71300.8; 0.0; 1.0; 0.13333333333333333; 0.0 +1378092519; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378092819; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378093119; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378093419; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 64310.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378093719; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378094019; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378094319; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1378094619; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1378094919; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.33333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378095219; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153788.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378095519; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378095819; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378096119; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.2; 0.0 +1378096419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1378096719; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378097019; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1378097319; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 65708.26666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378097619; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378097919; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378098219; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378098519; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 141207.46666666667; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378098819; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378099119; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 11.866666666666667; 0.0; 0.0 +1378099419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378099719; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378100019; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378100319; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144003.73333333334; 0.0; 0.8; 0.0; 0.0 +1378100620; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378100920; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378101220; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378101520; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1378101820; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378102120; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1378102420; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 +1378102720; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378103020; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378103320; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378103620; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 103457.86666666667; 0.06666666666666667; 2.6; 0.2; 0.13333333333333333 +1378103920; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1378104220; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.2666666666666666; 0.0; 0.0 +1378104520; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.26666666666666666; 7.466666666666667; 0.26666666666666666; 0.13333333333333333 +1378104820; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378105120; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378105420; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1378105720; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 164974.4; 0.0; 2.3333333333333335; 0.13333333333333333; 0.5333333333333333 +1378106020; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 188742.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378106320; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1378106620; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.2; 0.0 +1378106920; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1378107220; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 +1378107520; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378107820; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 +1378108120; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 1.4; 0.06666666666666667; 0.0 +1378108420; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.4; 0.06666666666666667; 0.0 +1378108720; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378109020; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118836.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378109320; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135613.86666666667; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378109620; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 137012.53333333333; 0.0; 1.0; 0.0; 0.0 +1378109921; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378110221; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378110521; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378110820; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378111120; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1378111420; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378111720; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378112020; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378112320; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378112621; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378112921; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.0; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1378113221; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.0; 0.0 +1378113521; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378113821; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378114121; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378114421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378114721; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378115021; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378115321; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.4; 0.0; 0.0 +1378115621; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378115921; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 0.8; 0.0; 0.0 +1378116221; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378116521; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378116821; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 170566.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1378117121; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378117421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378117721; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378118021; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378118321; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1378118621; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378118921; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378119221; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378119521; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134215.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378119821; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378120121; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141206.66666666666; 0.0; 2.4; 0.2; 0.5333333333333333 +1378120421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1378120721; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378121021; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378121321; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1378121622; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378121922; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378122222; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378122522; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1378122822; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378123122; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 148197.33333333334; 0.0; 0.8; 0.0; 0.0 +1378123422; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 167770.13333333333; 0.0; 7.2; 0.2; 0.13333333333333333 +1378123722; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152392.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378124022; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 173362.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378124322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378124622; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378124922; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1378125222; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378125522; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378125822; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1378126122; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378126422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378126722; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378127022; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378127322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170567.2; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378127622; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1378127922; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1378128222; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378128522; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378128822; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1378129122; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139809.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378129422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378129722; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378130022; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378130322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.2 +1378130622; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.06666666666666667; 1.5333333333333334; 0.0; 0.0 +1378130922; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.13333333333333333; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378131222; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378131522; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378131822; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378132122; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378132422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.06666666666666667 +1378132722; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378133023; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378133323; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378133623; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378133923; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378134223; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144003.73333333334; 0.0; 1.0; 0.0; 0.0 +1378134523; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 169168.8; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378134823; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 180353.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378135123; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378135423; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378135723; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378136023; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378136323; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.8; 0.0; 0.0 +1378136623; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378136923; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 +1378137223; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378137523; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378137823; 1; 2599.999343; 51.99998686; 2.0; 2097152.0; 152391.46666666667; 161.0; 21.866666666666667; 0.13333333333333333; 0.4 +1378138123; 1; 2599.999343; 43.333322383333325; 1.6666666666666665; 2097152.0; 713029.6; 0.8; 4.333333333333333; 0.06666666666666667; 0.5333333333333333 +1378138423; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 360708.0; 31.8; 3.533333333333333; 0.13333333333333333; 0.0 +1378138723; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 222296.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.0 +1378139023; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 1.8; 0.0; 0.0 +1378139323; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378139623; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378139923; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378140223; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378140523; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378140824; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378141124; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378141424; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378141724; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 125828.0; 0.6; 2.4; 0.06666666666666667; 0.5333333333333333 +1378142024; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 155187.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378142324; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378142624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378142924; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 138410.4; 0.0; 12.0; 0.0; 0.0 +1378143224; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.53333333333; 0.0; 7.133333333333334; 0.7333333333333333; 0.13333333333333333 +1378143524; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 213906.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378143824; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378144124; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 67106.4; 0.0; 1.0; 0.0; 0.0 +1378144424; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 67106.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378144724; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378145024; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378145324; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 155187.2; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378145624; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378145924; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378146224; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378146524; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378146824; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378147124; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378147424; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378147724; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378148024; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378148324; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1378148624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378148924; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378149224; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 152390.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378149524; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 6.933333333333334; 0.3333333333333333; 0.13333333333333333 +1378149824; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378150124; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378150424; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378150724; 1; 2599.999343; 53.733319755333326; 2.0666666666666664; 2097152.0; 247462.4; 161.73333333333332; 14.333333333333334; 0.0; 0.2 +1378151024; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 364902.4; 0.0; 1.4666666666666666; 0.0; 0.0 +1378151324; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 167771.2; 31.8; 4.0; 0.0; 0.0 +1378151624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 176159.2; 0.0; 0.8; 0.0; 0.0 +1378151924; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378152224; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378152525; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.0; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 +1378152825; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 153789.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378153125; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378153425; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378153725; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378154025; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378154325; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378154625; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378154925; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378155225; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378155525; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378155825; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378156125; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.86666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378156425; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378156725; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378157025; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378157325; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378157625; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378157925; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378158225; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1378158525; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378158825; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378159125; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378159425; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 132818.13333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1378159725; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 166371.46666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378160025; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378160325; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1378160625; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378160925; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378161225; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.06666666666666667; 1.8; 0.06666666666666667; 0.13333333333333333 +1378161525; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378161825; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378162125; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378162425; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 7.2; 0.26666666666666666; 0.13333333333333333 +1378162725; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378163025; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 171964.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378163325; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 170566.66666666666; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1378163625; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378163926; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378164226; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 61513.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378164526; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378164826; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378165126; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107651.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378165426; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378165726; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378166026; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378166326; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378166626; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378166926; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 102059.73333333334; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378167226; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378167526; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378167826; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.33333333333; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378168126; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378168426; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.5333333333333333; 1.4666666666666666; 0.0; 0.0 +1378168726; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378169026; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378169326; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378169627; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378169927; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378170227; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378170527; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 131420.0; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378170827; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 146798.93333333332; 0.0; 1.0; 0.0; 0.0 +1378171127; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378171427; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 162178.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378171727; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.6; 0.0; 0.0 +1378172027; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378172327; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378172627; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378172927; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1378173227; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378173527; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378173827; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 159381.86666666667; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378174127; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 137011.46666666667; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378174427; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 160780.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378174727; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378175027; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378175327; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378175627; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378175927; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378176227; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 78291.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378176527; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378176827; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378177127; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378177427; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378177727; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378178027; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 184546.13333333333; 0.0; 1.0; 0.0; 0.0 +1378178327; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378178627; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378178927; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378179227; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378179527; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144003.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378179828; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106253.86666666667; 0.0; 1.0; 0.0; 0.0 +1378180128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 7.8; 0.2; 0.13333333333333333 +1378180428; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378180728; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.6; 0.0; 0.0 +1378181028; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378181328; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378181628; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 +1378181928; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378182228; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1378182528; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378182828; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378183128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378183428; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378183728; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378184028; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378184328; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378184628; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1378184928; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 145401.33333333334; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378185228; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 177556.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378185528; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1378185828; 1; 2599.999343; 69.33331581333334; 2.666666666666667; 2097152.0; 619357.0666666667; 161.0; 22.0; 0.06666666666666667; 0.4 +1378186128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 404049.3333333333; 0.0; 2.7333333333333334; 0.0; 0.0 +1378186428; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 234879.73333333334; 31.8; 14.466666666666667; 0.0; 0.0 +1378186728; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 190140.0; 0.0; 8.866666666666667; 0.2; 0.13333333333333333 +1378187028; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 178955.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1378187328; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.2; 0.0; 0.0 +1378187628; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1378187928; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378188228; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157985.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378188529; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 116041.06666666667; 0.4; 2.8; 0.06666666666666667; 0.5333333333333333 +1378188829; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378189129; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378189429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378189729; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378190029; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 146799.73333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.06666666666666667 +1378190329; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 138410.66666666666; 0.0; 1.7333333333333334; 0.0; 0.0 +1378190629; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378190929; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 153789.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378191229; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378191529; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378191829; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1378192129; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 139808.26666666666; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378192429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 145401.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378192729; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 157984.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378193029; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378193329; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378193629; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378193929; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 135614.13333333333; 12.733333333333333; 13.666666666666666; 0.3333333333333333; 0.13333333333333333 +1378194229; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.6; 0.13333333333333333; 0.0 +1378194529; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.2; 0.06666666666666667; 0.0 +1378194829; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378195129; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.06666666666666667; 0.0 +1378195429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378195729; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1378196029; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378196329; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1378196629; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378196929; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378197229; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378197529; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378197829; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378198129; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.0; 0.0 +1378198429; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378198730; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378199030; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1378199330; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 146800.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378199630; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378199930; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378200230; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378200530; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378200830; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378201130; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378201430; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378201730; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378202030; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378202330; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378202630; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378202930; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378203230; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378203530; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378203830; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378204130; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378204430; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378204730; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378205030; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378205330; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1378205630; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378205930; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378206230; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378206530; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.26666666666; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378206831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 141206.93333333332; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378207131; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 1.3333333333333333; 6.133333333333334; 0.0; 0.0 +1378207431; 1; 2599.999343; 32.93332501133333; 1.2666666666666666; 2097152.0; 171964.8; 21.6; 7.2; 0.06666666666666667; 0.0 +1378207731; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378208031; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141207.46666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378208331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378208631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378208931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1378209231; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378209531; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378209831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378210131; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150992.8; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1378210431; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174761.06666666668; 0.0; 1.0; 0.0; 0.0 +1378210731; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.2; 0.13333333333333333; 0.0 +1378211031; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378211331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378211631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378211931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 146799.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378212231; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378212531; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378212831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.13333333333; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 +1378213131; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378213431; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378213731; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 137012.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378214031; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.6; 0.0; 1.0; 0.0; 0.0 +1378214331; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378214631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378214931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378215231; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378215531; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378215831; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378216131; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378216431; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378216731; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1378217031; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.26666666666; 0.0; 1.0; 0.0; 0.0 +1378217331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 152392.0; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378217631; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 162178.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378217932; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378218232; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378218532; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378218832; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1378219132; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 6.466666666666667; 0.2; 0.13333333333333333 +1378219432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.6666666666666667; 0.0; 0.0 +1378219732; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378220032; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378220332; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378220632; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378220932; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118836.53333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 +1378221232; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 176159.2; 0.0; 1.0; 0.2; 0.0 +1378221532; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378221832; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378222132; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378222432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378222732; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378223032; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378223332; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378223632; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 +1378223932; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378224232; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378224532; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.26666666666666666; 2.8; 0.06666666666666667; 0.4666666666666667 +1378224832; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.4666666666666667; 0.0 +1378225132; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378225432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1378225732; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 5.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378226032; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 2.4; 0.3333333333333333; 0.0 +1378226332; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378226632; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378226932; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1378227232; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378227533; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378227833; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378228133; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1378228433; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.4; 0.0; 1.0; 0.0; 0.0 +1378228733; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.4; 0.0; 0.0 +1378229033; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378229333; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378229633; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378229933; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378230233; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 12.066666666666666; 0.0; 0.0 +1378230533; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378230833; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378231133; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378231433; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378231733; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378232033; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 164974.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378232333; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378232633; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378232933; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1378233233; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378233533; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378233833; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378234133; 1; 2599.999343; 71.06664870866665; 2.733333333333333; 2097152.0; 789924.8; 161.06666666666666; 22.2; 0.06666666666666667; 0.4 +1378234433; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 331348.0; 0.0; 2.933333333333333; 0.0; 0.0 +1378234733; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 188741.6; 31.8; 3.466666666666667; 0.0; 0.0 +1378235033; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.6; 0.8; 2.3333333333333335; 0.06666666666666667; 0.0 +1378235333; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 188741.6; 0.06666666666666667; 3.466666666666667; 0.13333333333333333; 0.5333333333333333 +1378235633; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159382.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378235933; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378236233; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378236533; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378236834; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378237134; 1; 2599.999343; 46.799988174; 1.8; 2097152.0; 208315.73333333334; 161.8; 14.8; 0.0; 0.13333333333333333 +1378237434; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 469760.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1378237734; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 191538.4; 31.8; 4.066666666666666; 0.0; 0.0 +1378238034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 213908.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378238334; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378238634; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1378238934; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 146798.4; 0.0; 2.066666666666667; 0.06666666666666667; 0.5333333333333333 +1378239234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378239534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378239834; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378240134; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378240434; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 +1378240734; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378241034; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378241334; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378241634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378241934; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378242234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378242534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 2.6; 0.0; 0.5333333333333333 +1378242834; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378243134; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.0; 0.0; 0.8; 0.0; 0.0 +1378243434; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378243734; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378244034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378244334; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378244634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 7.2; 0.2; 0.13333333333333333 +1378244934; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378245234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378245534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1378245834; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378246134; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378246434; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1378246734; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378247034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378247334; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378247634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132817.86666666667; 0.06666666666666667; 1.5333333333333334; 0.0; 0.06666666666666667 +1378247935; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378248235; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378248535; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378248835; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378249135; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378249435; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378249735; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.33333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378250035; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378250335; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378250635; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378250935; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1378251235; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 148198.13333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1378251536; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1378251836; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378252136; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.6; 0.0; 0.0 +1378252436; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1378252736; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378253036; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378253336; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378253636; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163576.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378253936; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150994.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378254236; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378254536; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378254836; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 114642.93333333333; 0.5333333333333333; 1.4666666666666666; 0.0; 0.0 +1378255136; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378255436; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378255736; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378256036; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378256336; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1378256636; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378256936; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 176159.2; 0.2; 2.533333333333333; 0.0; 0.5333333333333333 +1378257236; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150992.8; 0.06666666666666667; 1.0; 0.0; 0.0 +1378257536; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1378257836; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 12.8; 13.0; 0.4; 0.13333333333333333 +1378258136; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378258436; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 152391.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378258736; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378259036; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1378259336; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378259636; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378259936; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378260236; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378260537; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157983.46666666667; 0.0; 2.6; 0.0; 0.5333333333333333 +1378260837; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378261137; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 166373.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378261437; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378261737; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378262037; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378262337; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378262637; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378262937; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378263237; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.0; 1.2; 0.0; 0.0 +1378263537; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110447.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378263837; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378264137; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 2.2; 0.0; 0.4666666666666667 +1378264437; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1378264737; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163577.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378265037; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378265337; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378265637; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1378265937; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378266237; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378266537; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378266837; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378267137; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378267437; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 1.4666666666666666; 1.4; 0.0; 0.0 +1378267737; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 141206.66666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378268037; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378268338; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378268638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378268938; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378269238; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378269538; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1378269838; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1378270138; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378270438; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378270738; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1378271038; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378271338; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 166372.26666666666; 0.06666666666666667; 2.6; 0.0; 0.5333333333333333 +1378271638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 139809.33333333334; 0.0; 7.0; 0.26666666666666666; 0.2 +1378271938; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 146800.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378272238; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378272538; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378272838; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378273138; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 +1378273438; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378273738; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 11.666666666666666; 0.06666666666666667; 0.0 +1378274038; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378274338; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378274638; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378274938; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378275238; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378275538; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378275838; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378276138; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378276438; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.13333333333333333 +1378276738; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.5333333333333334; 0.0; 0.0 +1378277038; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1378277338; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378277638; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 6.933333333333334; 0.4666666666666667; 0.13333333333333333 +1378277938; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378278238; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378278538; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 156586.93333333332; 0.0; 2.6; 0.0; 0.5333333333333333 +1378278838; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 156584.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378279138; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1378279438; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124428.8; 0.0; 1.0; 0.0; 0.0 +1378279738; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378280038; 1; 2599.999343; 32.93332501133333; 1.2666666666666666; 2097152.0; 164974.66666666666; 161.13333333333333; 20.4; 0.06666666666666667; 0.4 +1378280338; 1; 2599.999343; 53.733319755333326; 2.0666666666666664; 2097152.0; 759166.4; 0.0; 3.6666666666666665; 0.0; 0.0 +1378280638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 314570.4; 31.8; 3.7333333333333334; 0.0; 0.0 +1378280938; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 204119.46666666667; 0.0; 2.8; 0.0; 0.0 +1378281238; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 183149.06666666668; 0.0; 2.066666666666667; 0.0; 0.0 +1378281538; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 148197.86666666667; 0.0; 1.0; 0.0; 0.0 +1378281838; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.13333333333333333; 0.0 +1378282138; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163575.73333333334; 0.06666666666666667; 2.533333333333333; 0.0; 0.5333333333333333 +1378282438; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.66666666666; 0.0; 1.2; 0.0; 0.0 +1378282739; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378283039; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378283339; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378283639; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378283939; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378284239; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378284539; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 +1378284839; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116040.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378285139; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378285439; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378285739; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378286039; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.06666666668; 0.0; 1.0; 0.0; 0.0 +1378286339; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.06666666668; 0.0; 1.0; 0.0; 0.0 +1378286639; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1378286939; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378287239; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378287539; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378287839; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378288139; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 137013.06666666668; 20.4; 2.3333333333333335; 0.0; 0.06666666666666667 +1378288439; 1; 2599.999343; 29.466659220666667; 1.1333333333333333; 2097152.0; 135614.93333333332; 0.0; 3.933333333333333; 0.0; 0.0 +1378288739; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1378289039; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 152390.93333333332; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378289340; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 +1378289640; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 166372.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378289940; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1378290240; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 160780.53333333333; 0.0; 1.0; 0.0; 0.0 +1378290540; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378290840; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378291140; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378291440; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378291740; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378292040; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378292340; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378292640; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378292940; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.06666666667; 0.13333333333333333; 2.6666666666666665; 0.06666666666666667; 0.5333333333333333 +1378293240; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 174760.8; 0.0; 1.0; 0.0; 0.0 +1378293540; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378293840; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378294140; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378294440; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378294740; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378295040; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378295340; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1378295640; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378295940; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1378296240; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 156585.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378296540; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 191538.13333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378296840; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 194334.66666666666; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1378297140; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 181751.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378297441; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378297741; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378298041; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378298341; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378298641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378298941; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378299241; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378299541; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378299841; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 160780.0; 0.0; 1.0; 0.0; 0.0 +1378300141; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 162177.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378300441; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 1.2; 0.0; 0.0 +1378300741; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378301041; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 148198.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378301341; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378301641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.9333333333333333; 1.7333333333333334; 0.0; 0.0 +1378301941; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378302241; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378302541; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378302841; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378303141; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378303441; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 7.466666666666667; 0.2; 0.13333333333333333 +1378303741; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 160780.0; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378304041; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 174760.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378304341; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378304642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378304942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378305242; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 177557.06666666668; 0.2; 1.2; 0.06666666666666667; 0.13333333333333333 +1378305542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378305842; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378306142; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1378306442; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378306742; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378307042; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 149595.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378307342; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 138410.13333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378307641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378307941; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378308241; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378308541; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378308841; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378309141; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378309441; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.2; 0.0 +1378309741; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 148198.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378310041; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378310341; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 7.133333333333334; 0.4; 0.13333333333333333 +1378310641; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378310941; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 2.466666666666667; 0.8666666666666667; 0.5333333333333333 +1378311241; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 +1378311541; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1378311842; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378312142; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378312442; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378312742; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378313042; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378313342; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378313642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378313942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378314242; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.8666666666666667; 0.0; 0.0 +1378314542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378314842; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174760.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378315142; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378315442; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378315742; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 86680.26666666666; 12.733333333333333; 13.533333333333333; 0.4666666666666667; 0.2 +1378316042; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1378316342; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378316642; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378316942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.8666666666666667; 0.0 +1378317242; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104855.2; 0.0; 11.866666666666667; 0.2; 0.0 +1378317542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378317842; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.4666666666666666; 0.0; 0.0 +1378318142; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.13333333333; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1378318442; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 138410.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378318742; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378319042; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378319342; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378319642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378319942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 148197.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378320243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378320543; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378320843; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378321143; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1378321443; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378321743; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378322043; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 178955.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378322343; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378322643; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 148197.33333333334; 0.0; 1.2; 0.0; 0.0 +1378322943; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378323243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378323543; 1; 2599.999343; 39.866656592666665; 1.5333333333333334; 2097152.0; 160779.73333333334; 161.0; 14.4; 0.0; 0.2 +1378323843; 1; 2599.999343; 27.733326325333334; 1.0666666666666667; 2097152.0; 443195.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1378324143; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 184547.2; 31.8; 4.066666666666666; 0.0; 0.0 +1378324443; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 192936.26666666666; 0.0; 1.0; 0.0; 0.0 +1378324743; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378325043; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378325343; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121632.8; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378325643; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.2; 0.0; 0.0 +1378325943; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378326243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378326543; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378326843; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1378327143; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378327443; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378327743; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378328043; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378328343; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1378328643; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378328943; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159381.6; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378329244; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 190139.46666666667; 0.0; 7.933333333333334; 0.2; 0.13333333333333333 +1378329544; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153790.13333333333; 0.0; 1.2; 0.0; 0.0 +1378329844; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378330144; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378330444; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378330744; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 149595.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378331044; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378331344; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378331644; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378331944; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378332244; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378332544; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127225.86666666667; 0.06666666666666667; 2.8; 0.06666666666666667; 0.5333333333333333 +1378332844; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.33333333333; 0.0; 1.0; 0.0; 0.0 +1378333144; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378333444; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1378333744; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378334044; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 +1378334344; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378334644; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 7.2; 0.2; 0.13333333333333333 +1378334944; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 145401.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378335244; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 169169.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1378335544; 1; 2599.999343; 65.86665002266666; 2.533333333333333; 2097152.0; 485139.4666666667; 161.0; 21.333333333333332; 0.06666666666666667; 0.4 +1378335844; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 588599.4666666667; 1.0666666666666667; 3.066666666666667; 0.0; 0.0 +1378336144; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 306181.86666666664; 32.666666666666664; 5.6; 0.06666666666666667; 0.4666666666666667 +1378336444; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 236276.53333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1378336744; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 169169.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1378337045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 +1378337345; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 3.8; 1.4; 0.0; 0.0 +1378337645; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 156586.13333333333; 0.4; 3.2666666666666666; 0.0; 0.0 +1378337945; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378338245; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378338545; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378338845; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378339145; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378339445; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378339745; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378340045; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378340345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128623.46666666666; 0.0; 0.8; 0.0; 0.0 +1378340645; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1378340945; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378341245; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.6; 7.333333333333333; 0.2; 0.13333333333333333 +1378341545; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378341845; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378342145; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378342445; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1378342745; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378343045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378343345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 153789.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378343645; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378343945; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 152391.73333333334; 0.0; 1.0; 0.0; 0.0 +1378344245; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378344545; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378344845; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 1.4666666666666666; 0.0; 0.0 +1378345145; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378345445; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1378345745; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378346045; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378346345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378346645; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378346945; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378347245; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163576.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378347545; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 7.466666666666667; 0.3333333333333333; 0.13333333333333333 +1378347845; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123030.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378348145; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378348445; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378348745; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378349045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378349345; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378349645; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378349945; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378350245; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378350545; 1; 2599.999601; 25.99999601; 1.0; 2097152.0; 167772.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378350845; 1; 2599.999601; 19.066663740666666; 0.7333333333333333; 2097152.0; 167772.0; 0.0; 1.1333333333333333; 0.2; 0.0 +1378351145; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378351445; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378351745; 1; 2599.999601; 12.133331471333332; 0.4666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378352046; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 103457.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378352346; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 109049.86666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378352646; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378352946; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1378353246; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378353546; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378353846; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.06666666666666667; 6.533333333333333; 0.26666666666666666; 0.13333333333333333 +1378354146; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 180353.6; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378354446; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378354746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 1.0; 0.0; 0.0 +1378355046; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378355346; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378355646; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378355946; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 +1378356246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 +1378356546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378356846; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378357146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378357446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378357746; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378358046; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378358346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378358646; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378358947; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1378359247; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378359547; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378359847; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378360147; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378360447; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378360747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378361047; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 123031.73333333334; 0.0; 11.866666666666667; 0.0; 0.0 +1378361347; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 155186.93333333332; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378361647; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 171965.6; 0.0; 0.8666666666666667; 4.4; 0.0 +1378361947; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 162177.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378362247; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 1.2; 0.26666666666666666; 0.0 +1378362547; 1; 2599.999601; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378362847; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 173362.13333333333; 0.06666666666666667; 2.8666666666666667; 0.13333333333333333; 0.13333333333333333 +1378363147; 1; 2599.999601; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 1.7333333333333334; 0.0; 0.0 +1378363447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378363747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378364047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378364347; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378364647; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378364947; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 149595.46666666667; 0.26666666666666666; 2.4; 0.06666666666666667; 0.5333333333333333 +1378365247; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 180352.8; 0.0; 1.0; 0.0; 0.0 +1378365547; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 134216.8; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378365847; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378366147; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378366447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378366747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378367047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 155188.0; 0.0; 1.7333333333333334; 0.0; 0.0 +1378367347; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.2; 0.0 +1378367647; 1; 2599.999601; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.0; 0.0; 0.0 +1378367947; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378368247; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378368547; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 146799.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378368848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378369148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378369448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378369748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378370048; 1; 2599.999601; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378370348; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378370648; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378370948; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378371248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378371548; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378371848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378372148; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 141206.66666666666; 0.0; 8.2; 0.26666666666666666; 0.6666666666666666 +1378372448; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 1.2; 0.0; 0.0 +1378372748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150994.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378373047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378373347; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378373647; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378373947; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378374247; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378374547; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378374847; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378375147; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378375447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1378375747; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 117439.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378376047; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378376347; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378376648; 1; 2599.999601; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378376948; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378377248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378377548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378377848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378378148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378378448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378378748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378379048; 1; 2599.999601; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378379348; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 142605.6; 13.0; 18.6; 0.3333333333333333; 0.6 +1378379648; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 130021.6; 0.0; 1.2; 0.0; 0.0 +1378379948; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378380248; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378380548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109049.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378380848; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 54523.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378381148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1378381448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 +1378381748; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378382048; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378382348; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1378382648; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378382948; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 155187.2; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1378383248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378383548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378383848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378384149; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378384449; 1; 2599.998989; 51.999979780000004; 2.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378384749; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378385049; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378385349; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378385649; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 139809.33333333334; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1378385949; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378386249; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378386549; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.6; 0.0; 2.533333333333333; 0.13333333333333333; 0.5333333333333333 +1378386849; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 159381.86666666667; 0.0; 0.8; 0.0; 0.0 +1378387149; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1378387449; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378387749; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378388049; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378388349; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378388649; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378388949; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378389249; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378389549; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1378389849; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378390149; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 138410.4; 0.2; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378390449; 1; 2599.998989; 74.53330435133334; 2.8666666666666667; 2097152.0; 250258.93333333332; 161.0; 21.8; 0.06666666666666667; 0.3333333333333333 +1378390749; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 717224.5333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.0 +1378391049; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 359310.13333333336; 31.8; 3.6; 0.0; 0.0 +1378391949; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 145401.86666666667; 0.0; 1.0; 0.0; 0.0 +1378392249; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 6.4; 0.2; 0.13333333333333333 +1378392549; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378392849; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.2; 0.0 +1378393149; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378393449; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378393749; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 181751.46666666667; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1378394050; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 149595.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1378394350; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 +1378394650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 145401.06666666668; 0.0; 1.2; 0.0; 0.0 +1378394950; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1378395250; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1378395550; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378395850; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378396150; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378396450; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378396750; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378397050; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378397350; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 131420.53333333333; 0.0; 2.7333333333333334; 0.13333333333333333; 0.5333333333333333 +1378397650; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 149595.46666666667; 0.0; 0.8; 0.0; 0.0 +1378397950; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378398250; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378398550; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378398850; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378399150; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 120234.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378399450; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378399750; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 1.0; 0.13333333333333333; 0.0 +1378400050; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378400350; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378400650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378400950; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125827.2; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378401250; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 150994.4; 0.0; 1.0; 0.0; 0.0 +1378401550; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1378401850; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378402150; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378402450; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378402750; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378403050; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378403350; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.7333333333333334; 0.0; 0.0 +1378403650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378403951; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378404251; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 117439.2; 0.0; 1.6; 0.0; 0.0 +1378404551; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 146798.4; 0.0; 13.0; 0.06666666666666667; 0.4666666666666667 +1378404851; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 178954.66666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378405151; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 163575.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378405451; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378405750; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138411.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378406050; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378406350; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378406650; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378406950; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378407250; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378407550; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378407850; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378408150; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 164974.13333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378408450; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 146799.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378408751; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378409051; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378409351; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378409651; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378409951; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378410251; 1; 2599.998989; 51.999979780000004; 2.0; 2097152.0; 591395.2; 161.73333333333332; 14.2; 0.0; 0.2 +1378410551; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 272627.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1378410851; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159383.2; 31.8; 3.533333333333333; 0.0; 0.0 +1378411151; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1378411451; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 4.466666666666667; 0.0 +1378411751; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 159382.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378412051; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 +1378412351; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378412651; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378412951; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378413251; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 159382.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378413551; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378413851; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378414151; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378414451; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 113244.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378414751; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378415051; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378415351; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.13333333333333333; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1378415651; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378415951; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378416251; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378416551; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378416851; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378417152; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378417452; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378417752; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 78291.46666666666; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1378418052; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378418352; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 71300.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378418652; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378418952; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.06666666666666667; 2.1333333333333333; 0.0; 0.4666666666666667 +1378419252; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378419552; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378419852; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378420152; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378420452; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 1.6; 0.06666666666666667; 0.13333333333333333 +1378420752; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378421052; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378421352; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378421652; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378421952; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378422252; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378422552; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144002.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1378422852; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378423152; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378423452; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378423752; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378424052; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378424352; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378424653; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.06666666666666667; 6.333333333333333; 0.2; 0.13333333333333333 +1378424953; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 2.1333333333333333; 0.0; 0.0 +1378425253; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378425553; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378425853; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378426153; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378426453; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 132817.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378426753; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378427053; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378427353; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378427653; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 146799.2; 0.5333333333333333; 1.4; 0.0; 0.0 +1378427953; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 116041.06666666667; 0.0; 1.4; 0.0; 0.0 +1378428253; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378428553; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378428853; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378429153; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 150994.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378429453; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 138410.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378429753; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378430053; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 162178.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378430353; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378430653; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378430953; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378431253; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378431553; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378431853; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378432153; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378432453; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378432753; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378433054; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1378433354; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 118836.8; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378433654; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.66666666666; 0.0; 1.6666666666666667; 0.0; 0.0 +1378433954; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 167770.4; 0.0; 1.2; 0.0; 0.0 +1378434254; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1378434554; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378434854; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378435154; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378435454; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378435754; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378436054; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1378436354; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378436654; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378436954; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 157983.73333333334; 0.4; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1378437254; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 208316.0; 12.733333333333333; 13.2; 0.3333333333333333; 0.13333333333333333 +1378437554; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378437854; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378438154; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378438454; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378438754; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378439053; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378439354; 1; 2599.998989; 69.33330637333334; 2.666666666666667; 2097152.0; 310376.8; 161.0; 22.266666666666666; 0.06666666666666667; 0.3333333333333333 +1378439654; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 666892.2666666667; 0.0; 2.466666666666667; 0.0; 0.0 +1378439954; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 279618.4; 31.8; 3.533333333333333; 0.0; 0.0 +1378440254; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 194334.66666666666; 0.8; 2.533333333333333; 0.0; 0.0 +1378440554; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 187343.46666666667; 0.0; 3.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378440854; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 195732.8; 0.0; 1.0; 0.0; 0.0 +1378441154; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378441454; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378441754; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378442054; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378442354; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 121632.8; 0.0; 1.0; 0.0; 0.0 +1378442654; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 +1378442954; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378443254; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 153789.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378443554; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378443854; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 1.0; 0.0; 0.0 +1378444154; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 187343.73333333334; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1378444454; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159382.13333333333; 0.0; 1.0; 0.0; 0.0 +1378444754; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 156586.13333333333; 0.0; 1.0; 0.0; 0.0 +1378445054; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378445354; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378445654; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378445954; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1378446254; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378446554; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378446855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 1.0; 0.0; 0.0 +1378447155; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1378447455; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378447755; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.06666666666666667; 3.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378448055; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378448355; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132817.86666666667; 0.0; 11.933333333333334; 0.0; 0.0 +1378448655; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1378448955; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378449255; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 120235.46666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.13333333333333333 +1378449555; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 164974.93333333332; 0.0; 1.7333333333333334; 0.0; 0.0 +1378449855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1378450155; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.8666666666666667; 0.0; 0.0 +1378450455; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1378450755; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378451055; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137012.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378451355; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.66666666666; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378451655; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378451955; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378452255; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378452555; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378452855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127225.06666666667; 0.0; 1.2; 0.0; 0.0 +1378453155; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378453455; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1378453755; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1378454055; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378454355; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378454655; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378454955; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1378455255; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378455555; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378455855; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378456155; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378456456; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378456756; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378457056; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378457356; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378457656; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138410.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378457956; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378458256; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378458556; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 155186.93333333332; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378458856; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 157983.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378459156; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127225.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378459456; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378459756; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378460056; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378460356; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378460656; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378460956; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378461256; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378461556; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378461856; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378462156; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 132818.4; 0.06666666666666667; 2.2; 0.06666666666666667; 0.5333333333333333 +1378462456; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 152391.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378462756; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378463056; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378463356; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378463657; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378463957; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 +1378464257; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1378464557; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378464857; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378465157; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378465457; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.13333333333333333; 0.0 +1378465757; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 142605.33333333334; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1378466057; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 176159.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378466357; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378466657; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378466957; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378467257; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378467557; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378467857; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378468157; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1378468457; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.2; 0.13333333333333333 +1378468757; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378469057; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378469657; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 180352.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378470257; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378470557; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.2; 0.0 +1378470857; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1378471157; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1378472057; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378472657; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 +1378472957; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 137012.0; 0.06666666666666667; 2.6666666666666665; 0.13333333333333333; 0.4666666666666667 +1378473257; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130021.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378473557; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 1.2666666666666666; 0.2; 0.0 +1378473857; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378474157; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.2; 0.0 +1378474457; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.26666666666666666; 0.0 +1378474757; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 +1378475057; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378475358; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1378475658; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.2; 0.0 +1378475958; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.13333333333333333; 0.0 +1378476258; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378476558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 160779.46666666667; 0.06666666666666667; 2.533333333333333; 0.2; 0.5333333333333333 +1378476858; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 162178.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378477158; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378477458; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1378477758; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1378478058; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.06666666666666667; 1.2; 0.06666666666666667; 0.13333333333333333 +1378478358; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.2; 0.0; 0.0 +1378478658; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.2; 0.0 +1378478958; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 106253.33333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1378479258; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378479558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 1.2; 0.0 +1378479858; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378480158; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 128623.2; 0.0; 2.2; 0.26666666666666666; 0.5333333333333333 +1378480458; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118836.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1378480758; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378481058; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378481358; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378481658; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378481958; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378482258; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 2.466666666666667; 0.26666666666666666; 0.13333333333333333 +1378482558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 142604.8; 0.0; 5.933333333333334; 0.0; 0.0 +1378482858; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378483158; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1378483459; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378483759; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 113244.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378484059; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378484359; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378484659; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378484959; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378485259; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378485559; 1; 2599.998989; 64.13330839533334; 2.466666666666667; 2097152.0; 350922.4; 161.06666666666666; 22.0; 2.1333333333333333; 0.4 +1378485859; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 706038.4; 0.0; 2.8; 0.0; 0.0 +1378486159; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 290803.2; 31.8; 3.7333333333333334; 0.0; 0.0 +1378486459; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 198527.73333333334; 0.26666666666666666; 2.2666666666666666; 0.0; 0.0 +1378486759; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.6; 0.13333333333333333; 0.0 +1378487059; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378487359; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 128623.46666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378487659; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 156586.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378487959; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378488259; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 171964.8; 0.0; 6.866666666666666; 0.5333333333333333; 0.13333333333333333 +1378488559; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378488859; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378489159; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378489459; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378489759; 1; 2599.998989; 0.0; 0.0; 2097152.0; 163576.53333333333; 0.0; 0.9333333333333333; 0.2; 0.0 +1378490059; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 152390.66666666666; 0.0; 1.0; 0.2; 0.0 +1378490359; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.13333333333333333; 0.0 +1378490659; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378490959; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 118837.06666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378491259; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 137012.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378491559; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378491859; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 11.8; 0.0; 0.0 +1378492159; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.06666666667; 0.0; 0.8; 0.0; 0.0 +1378492459; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.6666666666666667; 0.0; 0.0 +1378492759; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1378493059; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 1.0; 0.0; 0.0 +1378493360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378493660; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128623.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378493960; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378494260; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 104856.0; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 +1378494560; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 183149.6; 0.06666666666666667; 2.4; 0.0; 0.5333333333333333 +1378494860; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 164974.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1378495160; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378495460; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1378495760; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378496060; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378496360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378496660; 1; 2599.998989; 41.599983824; 1.6; 2097152.0; 450186.93333333335; 161.8; 14.733333333333333; 0.0; 0.2 +1378496960; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 205519.46666666667; 0.0; 1.6; 0.0; 0.0 +1378497260; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 194333.33333333334; 31.8; 3.6; 0.0; 0.0 +1378497560; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378497860; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378498160; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 127225.06666666667; 0.0; 2.533333333333333; 0.0; 0.5333333333333333 +1378498460; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 156585.6; 0.0; 1.0; 0.0; 0.0 +1378498760; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1378499060; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378499360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378499660; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 162177.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378499960; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 12.733333333333333; 12.866666666666667; 0.4; 0.13333333333333333 +1378500260; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1378500560; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378500860; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378501160; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378501460; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378501760; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 156585.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378502060; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 208314.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378502360; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 139809.33333333334; 0.0; 1.0; 0.0; 0.0 +1378502660; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378502960; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378503260; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378503560; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378503860; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378504160; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106253.86666666667; 0.0; 0.8; 0.0; 0.0 +1378504460; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378504760; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378505060; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 1.0; 0.0; 0.0 +1378505360; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 170566.4; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1378505660; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 183149.33333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378505960; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378506260; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.0; 0.06666666666666667; 7.0; 0.3333333333333333; 0.13333333333333333 +1378506560; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378506860; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 134216.0; 0.06666666666666667; 1.5333333333333334; 0.4666666666666667; 0.06666666666666667 +1378507160; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378507460; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378507761; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378508061; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1378508361; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378508661; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378508961; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 146799.2; 0.06666666666666667; 2.2; 0.0; 0.4666666666666667 +1378509261; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378509561; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378509861; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378510161; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378510461; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378510761; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378511061; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378511361; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378511661; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378511961; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378512261; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 138409.6; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378512561; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 138410.4; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378512861; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378513161; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378513461; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378513761; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378514061; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 124429.06666666667; 0.5333333333333333; 1.3333333333333333; 0.13333333333333333; 0.0 +1378514361; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378514661; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.4666666666666667; 0.0 +1378514961; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378515261; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378515561; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 55921.333333333336; 0.0; 0.9333333333333333; 0.0; 0.0 +1378515861; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378516161; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 146798.93333333332; 0.0; 2.6; 0.0; 0.5333333333333333 +1378516461; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 167770.66666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378516761; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 135613.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378517061; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 71300.8; 0.0; 1.0; 0.0; 0.0 +1378517361; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1378517661; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378517961; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1378518261; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 78291.46666666666; 0.2; 6.4; 0.2; 0.13333333333333333 +1378518561; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 163577.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 +1378518861; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378519161; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1378519461; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378519761; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378520061; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 159381.06666666668; 0.0; 0.8; 0.0; 0.0 +1378520361; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1378520662; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378520962; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 10.266666666666667; 0.0 +1378521262; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378521562; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1378521862; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378522162; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378522462; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378522762; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378523062; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378523362; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124428.8; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1378523662; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 1.0; 0.0; 0.0 +1378523962; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378524262; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378524562; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 8.2; 0.0 +1378524862; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378525162; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1378525462; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 65708.26666666666; 0.0; 1.4; 0.0; 0.0 +1378525762; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 139809.33333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1378526062; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378526362; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378526662; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 74097.06666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378527862; 1; 2599.998989; 16.714279215; 0.6428571428571429; 2097152.0; 107852.0; 0.0; 1.0714285714285714; 0.07692307692307693; 0.0 +1378528762; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.4; 0.0 +1378529062; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.0; 5.066666666666666; 0.0 +1378529362; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378529662; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378529963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1378530263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378530563; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.93333333332; 0.06666666666666667; 8.333333333333334; 0.26666666666666666; 0.6 +1378530863; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378531163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 +1378531463; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378531763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378532063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1378532363; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378532663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.06666666666666667; 0.0 +1378532963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378533263; 1; 2599.998989; 60.66664307666668; 2.3333333333333335; 2097152.0; 406845.3333333333; 161.06666666666666; 21.533333333333335; 0.06666666666666667; 0.4 +1378533563; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 562034.4; 0.0; 2.533333333333333; 0.06666666666666667; 0.0 +1378533863; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 293599.2; 31.8; 4.333333333333333; 0.06666666666666667; 0.0 +1378534163; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 251656.0; 0.8; 3.933333333333333; 0.06666666666666667; 0.4666666666666667 +1378534463; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 167770.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1378534763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378535063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378535363; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1378535663; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 13.4; 0.13333333333333333; 0.13333333333333333 +1378535963; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134215.2; 0.0; 1.4666666666666666; 0.13333333333333333; 0.0 +1378536263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1378536563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378536863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1378537163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378537463; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1378537763; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378538063; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378538363; 1; 2599.998989; 0.0; 0.0; 2097152.0; 159383.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378538663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378538963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378539263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378539563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378539863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 2.066666666666667; 0.06666666666666667; 0.0 +1378540163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378540463; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378540763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378541063; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.06666666666666667; 1.8666666666666667; 0.0; 0.0 +1378541363; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125827.2; 0.13333333333333333; 2.533333333333333; 0.0; 0.4666666666666667 +1378541663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378541963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378542263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378542563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378542863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378543163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0; 1.8666666666666667; 0.0 +1378543463; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378543763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378544063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378544364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378544664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378544964; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 146799.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378545264; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 149596.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378545564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378545864; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1378546164; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378546464; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378546764; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146798.93333333332; 0.0; 1.4; 0.0; 0.0 +1378547064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378547364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378547664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378547964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1378548264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378548564; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378548864; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1378549164; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378549464; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1378549764; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138410.4; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378550064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378550364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378550664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378550964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378551264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378551564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378551864; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378552164; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138409.86666666667; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1378552464; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 213907.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378552764; 1; 2599.998989; 0.0; 0.0; 2097152.0; 155187.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378553064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378553364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1378553664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378553964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378554264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378554564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378554865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378555165; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378555465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378555765; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.2; 0.06666666666666667; 8.733333333333333; 0.26666666666666666; 0.6 +1378556065; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.6; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378556365; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1378556665; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378556965; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 4.2; 0.0 +1378557265; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378557565; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1378557865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378558165; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378558465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 160779.46666666667; 0.0; 0.8; 0.0; 0.0 +1378558765; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 1.0; 0.0; 0.0 +1378559065; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 1.0; 0.0; 0.0 +1378559365; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 116040.53333333334; 0.0; 2.4; 0.0; 0.4666666666666667 +1378559665; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 148197.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378559965; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378560265; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1378560565; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1378560865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378561165; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 146800.0; 12.733333333333333; 13.133333333333333; 0.3333333333333333; 0.2 +1378561465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 156585.33333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378561765; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378562065; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378562366; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378562666; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118836.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378562966; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 2.466666666666667; 0.13333333333333333; 0.4666666666666667 +1378563266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378563566; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378563866; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378564166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378564466; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132817.86666666667; 0.0; 1.9333333333333333; 0.06666666666666667; 0.13333333333333333 +1378564766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378565066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378565366; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378565666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378565966; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104855.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378566266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378566566; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 145401.06666666668; 0.06666666666666667; 8.266666666666667; 0.2; 0.6 +1378566866; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 173363.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378567166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378567466; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378567766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378568066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378568366; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378568666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378568966; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1378569266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378569566; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378569866; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1378570166; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 152391.2; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378570466; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148197.6; 0.06666666666666667; 1.2; 0.0; 0.0 +1378570766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378571066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378571366; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378571666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.13333333333333333; 0.0 +1378571966; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378572266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378572566; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378572866; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378573166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 +1378573466; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378573766; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 141206.13333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1378574066; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 141206.4; 0.0; 1.0; 0.0; 0.0 +1378574367; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.4; 0.0; 0.0 +1378574667; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378574967; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378575267; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.26666666666; 0.0; 1.0; 0.0; 0.0 +1378575567; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378575867; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378576167; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378576467; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378576767; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378577067; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378577367; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 139808.53333333333; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378577667; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378577967; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.2; 7.0; 0.2; 0.13333333333333333 +1378578267; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378578567; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378578867; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378579167; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 107652.26666666666; 0.0; 11.933333333333334; 0.0; 0.0 +1378579467; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378579767; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378580067; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378580367; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1378580667; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378580967; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 128624.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378581267; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 170566.66666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378581567; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378581867; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378582167; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378582467; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378582767; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378583067; 1; 2599.998989; 38.133318505333335; 1.4666666666666666; 2097152.0; 436206.4; 161.73333333333332; 14.8; 0.0; 0.2 +1378583368; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 304784.5333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378583668; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 152390.93333333332; 31.8; 8.6; 0.2; 0.13333333333333333 +1378583968; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 188741.33333333334; 0.0; 2.3333333333333335; 0.0; 0.0 +1378584268; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378584568; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 128624.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378584868; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 150993.06666666668; 0.0; 0.8; 0.0; 0.0 +1378585168; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1378585468; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378585768; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378586068; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378586368; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378586668; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378586968; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378587268; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378587568; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378587868; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378588168; 1; 2599.998989; 25.999989890000002; 1.0; 2097152.0; 142604.53333333333; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1378588468; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 145401.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378588768; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378589068; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378589368; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378589668; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139809.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378589968; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 137012.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378590268; 1; 2599.998989; 67.599973714; 2.6; 2097152.0; 595589.6; 161.06666666666666; 22.133333333333333; 0.06666666666666667; 0.4 +1378590568; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 433409.6; 0.0; 2.4; 0.0; 0.0 +1378590868; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 239072.8; 31.8; 3.933333333333333; 0.0; 0.0 +1378591168; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 192936.26666666666; 0.8666666666666667; 2.533333333333333; 0.0; 0.0 +1378591468; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 132818.66666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1378591768; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 146799.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378592068; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378592368; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 +1378592668; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378592968; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378593269; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 134216.0; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 +1378593569; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378593869; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1378594169; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378594469; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378594769; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1378595069; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137012.8; 0.0; 1.2; 0.0; 0.0 +1378595369; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 171964.8; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378595669; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 195731.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378595969; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378596269; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378596569; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 6.0; 0.2; 0.13333333333333333 +1378596869; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 127226.13333333333; 0.0; 2.2; 0.0; 0.0 +1378597169; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378597469; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378597769; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378598069; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1378598369; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378598669; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1378598969; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 162176.8; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1378599269; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 153790.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378599569; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378599869; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378600169; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378600469; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 130022.4; 0.5333333333333333; 1.3333333333333333; 0.06666666666666667; 0.0 +1378600769; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.0; 0.0 +1378601069; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378601369; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378601669; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378601970; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378602269; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378602569; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 155188.0; 0.2; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378602869; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 141207.46666666667; 0.0; 0.8; 0.0; 0.0 +1378603169; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 141206.93333333332; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378603469; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378603769; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378604069; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137012.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378604369; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378604669; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378604969; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378605269; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378605569; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378605869; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1378606169; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 141207.46666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1378606469; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.26666666666; 0.0; 0.8; 0.0; 0.0 +1378606769; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1378607069; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153790.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378607369; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378607669; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378607970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.8; 0.0; 0.0 +1378608270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1378608570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1378608870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378609170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378609470; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 121633.6; 0.8666666666666667; 1.3333333333333333; 0.06666666666666667; 0.0 +1378609770; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138411.2; 0.0; 2.2; 0.0; 0.4666666666666667 +1378610070; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155187.2; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378610370; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378610670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1378610970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378611270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378611570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378611870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1378612170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378612470; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378612770; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378613070; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378613370; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.86666666667; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378613670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378613970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378614270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378614570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378614870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378615170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378615470; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378615770; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378616070; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 +1378616370; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 146799.2; 0.06666666666666667; 7.266666666666667; 0.2; 0.13333333333333333 +1378616670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378616970; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 120235.46666666666; 0.0; 2.2; 0.0; 0.4666666666666667 +1378617270; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 167770.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378617570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378617871; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 92272.0; 0.0; 0.8666666666666667; 7.6; 0.0 +1378618171; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378618471; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378618771; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378619071; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378619371; 1; 2599.998989; 0.0; 0.0; 2097152.0; 149596.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378619671; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 1.0; 0.0; 0.0 +1378619971; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378620271; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378620571; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378620871; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 213908.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378621171; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378621471; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378621771; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378622071; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130021.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.06666666666666667 +1378622371; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.4666666666666666; 0.0; 0.0 +1378622671; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 11.866666666666667; 0.06666666666666667; 0.0 +1378622971; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 12.733333333333333; 13.666666666666666; 0.26666666666666666; 0.13333333333333333 +1378623271; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378623571; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378623871; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1378624171; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 96467.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378624472; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378624772; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.2; 0.0 +1378625072; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1378625372; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378625672; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378625972; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1378626272; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.6; 0.0; 0.0 +1378626572; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378626872; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378627172; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378627472; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378627772; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 153789.6; 0.2; 2.4; 0.06666666666666667; 0.4666666666666667 +1378628072; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 184548.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378628372; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378628672; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378628972; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378629272; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378629572; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378629872; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1378630172; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378630472; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378630772; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378631073; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378631373; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 134216.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378631673; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378631973; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378632273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378632573; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378632873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378633173; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1378633473; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1378633773; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378634073; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378634373; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378634673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1378634973; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 170566.4; 0.0; 8.4; 0.2; 0.6666666666666666 +1378635273; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 170566.4; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.0 +1378635573; 1; 2599.998989; 0.0; 0.0; 2097152.0; 171964.53333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378635873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378636173; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378636473; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378636773; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378637073; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378637373; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378637673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378637973; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378638273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378638573; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.2; 2.533333333333333; 0.0; 0.4666666666666667 +1378638873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378639173; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378639473; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378639773; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378640073; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378640373; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378640673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.4; 0.0; 0.0 +1378640973; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 120234.66666666667; 0.06666666666666667; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 +1378641273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 166373.06666666668; 0.0; 1.0; 0.0; 0.0 +1378641573; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1378641873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378642173; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 167770.66666666666; 0.0; 2.7333333333333334; 0.0; 0.4666666666666667 +1378642473; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 183149.6; 0.0; 0.8; 0.0; 0.0 +1378642774; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378643074; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378643374; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 173362.93333333332; 161.0; 21.866666666666667; 0.06666666666666667; 0.4 +1378643674; 1; 2599.998989; 55.46664509866667; 2.1333333333333333; 2097152.0; 708835.7333333333; 0.0; 2.8666666666666667; 0.06666666666666667; 0.0 +1378643974; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 318765.3333333333; 31.8; 3.6666666666666665; 0.0; 0.0 +1378644274; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 183148.53333333333; 0.8; 2.2; 0.0; 0.0 +1378644574; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 150992.53333333333; 0.0; 1.6; 0.0; 0.0 +1378644874; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378645174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378645474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152390.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378645774; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 153790.13333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378646074; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 162177.6; 0.0; 1.0; 0.0; 0.0 +1378646374; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1378646674; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378646974; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378647274; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378647574; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 148197.33333333334; 1.0; 1.7333333333333334; 0.0; 0.0 +1378647874; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1378648174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378648474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378648774; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378649074; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378649374; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378649674; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 176159.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378649974; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378650274; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378650574; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1378650874; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155188.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1378651174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378651474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378651775; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378652075; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1378652375; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378652675; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 104856.0; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1378652975; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 149595.46666666667; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378653275; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1378653575; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378653875; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378654175; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378654475; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1378654775; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378655075; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378655375; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378655675; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378655975; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146798.13333333333; 0.0; 1.0; 0.0; 0.0 +1378656275; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378656575; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 2.2; 0.0; 0.5333333333333333 +1378656875; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 +1378657175; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378657475; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1378657775; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378658076; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378658376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378658676; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378658976; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 0.8; 0.0; 0.0 +1378659276; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378659576; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378659876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378660176; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148196.8; 0.0; 2.8; 0.0; 0.4666666666666667 +1378660476; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152391.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378660776; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378661076; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378661376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378661676; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378661976; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378662276; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378662576; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378662876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378663176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1378663476; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378663776; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 148197.6; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378664076; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 138410.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378664376; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378664676; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378664976; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378665276; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 150994.4; 0.0; 6.733333333333333; 0.26666666666666666; 0.2 +1378665576; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 +1378665876; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132817.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378666176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378666476; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 11.8; 0.0; 0.0 +1378666776; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378667076; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 120234.93333333333; 0.0; 1.2; 0.0; 0.0 +1378667377; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 117439.2; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1378667677; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378667976; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378668276; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378668576; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.2; 0.0; 0.0 +1378668876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378669176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378669476; 1; 2599.998989; 39.86665116466667; 1.5333333333333334; 2097152.0; 321561.6; 161.73333333333332; 14.733333333333333; 0.0; 0.2 +1378669776; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 339736.26666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378670076; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 162178.66666666666; 31.8; 3.7333333333333334; 0.0; 0.0 +1378670376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 +1378670676; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1378670976; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142604.53333333333; 0.06666666666666667; 2.7333333333333334; 0.0; 0.5333333333333333 +1378671276; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378671576; 1; 2599.998989; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378671876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378672176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378672477; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378672777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1378673077; 1; 2599.998989; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378673377; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378673677; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378673977; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1378674277; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378674577; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 128624.26666666666; 0.13333333333333333; 2.533333333333333; 0.0; 0.4666666666666667 +1378674877; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1378675177; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378675477; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378675777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378676077; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378676377; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.06666666666666667; 1.5333333333333334; 0.2; 0.13333333333333333 +1378676677; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 6.666666666666667; 0.0; 0.0 +1378676977; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378677277; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1378677577; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378677877; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 83884.0; 0.26666666666666666; 1.1333333333333333; 0.0; 0.0 +1378678177; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 138410.13333333333; 0.0; 2.533333333333333; 0.0; 0.5333333333333333 +1378678477; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124428.53333333334; 0.0; 1.0; 0.0; 0.0 +1378678777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378679077; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378679377; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 +1378679677; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.8; 0.06666666666666667; 0.13333333333333333 +1378679977; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 166373.06666666668; 0.0; 0.8; 0.0; 0.0 +1378680277; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378680577; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1378680877; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378681178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378681478; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.2; 1.0666666666666667; 0.0; 0.0 +1378681778; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 137013.06666666668; 0.0; 2.4; 0.0; 0.4666666666666667 +1378682078; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1378682378; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378682678; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.13333333333; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1378682978; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 145400.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378683278; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378683578; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378683878; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1378684178; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1378684478; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378684778; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378685078; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378685378; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 184547.73333333334; 0.06666666666666667; 2.466666666666667; 0.0; 0.5333333333333333 +1378685678; 1; 2599.998989; 0.0; 0.0; 2097152.0; 213908.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378685978; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378686278; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378686578; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378686878; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 164974.4; 0.6; 1.2666666666666666; 0.0; 0.0 +1378687178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 164973.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378687478; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378687778; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378688078; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378688378; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378688678; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378688978; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 149596.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378689278; 1; 2599.998989; 0.0; 0.0; 2097152.0; 162177.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378689578; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 7.2; 0.2; 0.13333333333333333 +1378689878; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378690178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378690478; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378690778; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378691079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378691379; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 +1378691679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378691979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378692279; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378692579; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 131419.73333333334; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378692879; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155188.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378693179; 1; 2599.998989; 0.0; 0.0; 2097152.0; 148196.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378693479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378693779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378694079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378694379; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378694679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378694979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378695279; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1378695579; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378695879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378696179; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 2.8; 0.0; 0.4666666666666667 +1378696479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378696779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378697079; 1; 2599.998989; 64.13330839533334; 2.466666666666667; 2097152.0; 426419.2; 161.2; 21.733333333333334; 0.06666666666666667; 0.4 +1378697379; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 539665.0666666667; 0.0; 2.8; 0.0; 0.0 +1378697679; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 246063.46666666667; 31.8; 3.6666666666666665; 0.0; 0.0 +1378697979; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 159382.4; 0.8; 2.6666666666666665; 0.0; 0.0 +1378698279; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.8666666666666667; 0.0; 0.0 +1378698579; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378698879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378699180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 1.0; 0.0; 0.0 +1378699480; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378699780; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.53333333333; 6.8; 2.533333333333333; 0.0; 0.4666666666666667 +1378700080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118836.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378700380; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378700679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378700979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378701279; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 142605.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.2 +1378701579; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378701879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378702179; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0; 0.0; 0.0 +1378702479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378702779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378703079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378703379; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 183149.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1378703680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 160780.53333333333; 0.0; 1.0; 0.0; 0.0 +1378703980; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378704280; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 111846.66666666667; 1.0; 2.0; 0.0; 0.0 +1378704580; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378704880; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378705180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378705480; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378705780; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378706080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378706380; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378706680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378706980; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 1.9333333333333333; 0.0; 0.4666666666666667 +1378707280; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 6.333333333333333; 0.26666666666666666; 0.13333333333333333 +1378707580; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 148196.53333333333; 0.0; 1.5333333333333334; 0.0; 0.0 +1378707880; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378708180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378708480; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.8; 0.06666666666666667; 0.06666666666666667 +1378708780; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.53333333333; 0.0; 1.8; 0.0; 0.0 +1378709080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0; 0.0; 0.0 +1378709380; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378709680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378709980; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 11.933333333333334; 0.0; 0.0 +1378710280; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378710580; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 135613.33333333334; 0.26666666666666666; 2.3333333333333335; 0.0; 0.4666666666666667 +1378710880; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 156585.6; 0.0; 1.0; 0.0; 0.0 +1378711180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378711481; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378711781; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135613.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378712081; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378712381; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378712681; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.9333333333333333; 0.0; 0.0 +1378712981; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378713281; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378713581; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378713881; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378714181; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 174760.8; 0.0; 8.6; 0.2; 0.6666666666666666 +1378714481; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155187.46666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378714781; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1378715081; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1378715381; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1378715681; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378715981; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378716281; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378716581; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378716881; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378717181; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378717481; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378717782; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.0; 0.0; 2.4; 0.0; 0.4666666666666667 +1378718082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152391.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378718382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378718682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378718982; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378719282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378719582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1378719882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378720182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378720482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378720782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1378721082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378721382; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 145400.8; 0.0; 8.733333333333333; 0.2; 0.6 +1378721682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153788.53333333333; 0.0; 0.8; 0.0; 0.0 +1378721982; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378722282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378722582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378722882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378723182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378723482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378723782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378724082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378724382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 1.0; 0.0; 0.0 +1378724682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378724982; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378725282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1378725582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378725882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378726182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.26666666666666666; 0.0 +1378726482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.0; 0.0 +1378726782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378727082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.4; 0.0; 0.0 +1378727382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378727682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.26666666666; 0.0; 0.8; 0.13333333333333333; 0.0 +1378727983; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 208314.93333333332; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1378728283; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378728583; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 156585.06666666668; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378728883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153790.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378729183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378729483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378729783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1378730083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1378730383; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378730683; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378730983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378731283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378731583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 +1378731883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378732183; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 162178.4; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1378732483; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378732783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378733083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378733383; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 7.2; 0.26666666666666666; 0.2 +1378733683; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378733983; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378734283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1378734583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378734883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378735183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378735483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.3333333333333333; 0.0 +1378735783; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 180352.8; 0.13333333333333333; 2.6; 0.0; 0.4666666666666667 +1378736083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378736383; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378736683; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378736983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378737283; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1378737583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378737883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378738183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 1.0; 0.0; 0.0 +1378738483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1378738783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378739083; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 6.266666666666667; 0.2; 0.13333333333333333 +1378739383; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 181750.93333333332; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1378739683; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 157983.46666666667; 0.0; 1.0; 0.0; 0.0 +1378739983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167771.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378740283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.6666666666666666; 0.0 +1378740583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378740883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378741183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378741483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 +1378741783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378742084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378742384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378742684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378742984; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138410.4; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378743284; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378743584; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378743884; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378744184; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378744484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 +1378744784; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378745084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1378745384; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 12.733333333333333; 12.133333333333333; 0.4; 0.2 +1378745684; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 2.4; 0.0; 0.0 +1378745984; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1378746284; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 1.4666666666666666; 1.2; 0.0; 0.0 +1378746584; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378746884; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378747184; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378747484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378747784; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378748084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378748384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378748684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378748984; 1; 2599.998989; 65.86664105466667; 2.533333333333333; 2097152.0; 468361.86666666664; 161.06666666666666; 21.733333333333334; 0.06666666666666667; 0.4 +1378749284; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 441797.6; 0.0; 2.8; 0.0; 0.0 +1378749584; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 248859.73333333334; 31.8; 3.7333333333333334; 0.0; 0.0 +1378749884; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 183149.06666666668; 0.8; 2.533333333333333; 0.0; 0.0 +1378750184; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 188742.4; 0.0; 3.466666666666667; 0.0; 0.4666666666666667 +1378750484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378750784; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1378751084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378751384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378751684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378751984; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 160779.73333333334; 0.06666666666666667; 7.4; 0.2; 0.13333333333333333 +1378752284; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378752585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378752885; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378753185; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378753485; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378753785; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144003.73333333334; 0.0; 13.0; 0.0; 0.4666666666666667 +1378754085; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378754385; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378754685; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378754985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378755285; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 +1378755585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378755885; 1; 2599.998989; 39.86665116466667; 1.5333333333333334; 2097152.0; 293599.2; 161.73333333333332; 14.8; 0.0; 0.2 +1378756185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 378883.4666666667; 0.0; 1.4; 0.0; 0.0 +1378756485; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 155188.53333333333; 31.8; 3.533333333333333; 0.0; 0.0 +1378756785; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152390.93333333332; 0.0; 1.2; 0.0; 0.0 +1378757085; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378757385; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 156584.8; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378757685; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 139809.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378757985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378758285; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378758585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 1.2666666666666666; 0.0 +1378758885; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.13333333333; 0.13333333333333333; 7.066666666666666; 0.2; 0.13333333333333333 +1378759185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.4; 0.0; 1.9333333333333333; 0.0; 0.0 +1378759485; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378759785; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1378760085; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378760385; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378760685; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378760985; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 139808.0; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1378761285; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378761585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378761885; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378762185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378762485; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378762785; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378763086; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378763386; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378763686; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378763986; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378764286; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378764586; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.6; 0.0; 0.5333333333333333 +1378764886; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1378765186; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378765486; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378765786; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378766086; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 125827.46666666666; 0.06666666666666667; 1.6666666666666667; 0.06666666666666667; 0.13333333333333333 +1378766385; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116040.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378766685; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378766985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378767285; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378767585; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378767885; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378768185; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 163576.8; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378768486; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378768786; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378769086; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378769386; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378769686; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378769986; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 +1378770286; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 131419.73333333334; 0.0; 1.2; 0.0; 0.0 +1378770586; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378770886; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378771186; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378771486; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 +1378771786; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 156585.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378772086; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 169168.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378772386; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378772686; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378772986; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378773286; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 113244.8; 0.5333333333333333; 1.3333333333333333; 0.0; 0.0 +1378773586; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378773886; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378774186; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378774486; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378774786; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1378775086; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378775386; 1; 2599.998989; 25.999989890000002; 1.0; 2097152.0; 118837.33333333333; 0.0; 2.2; 0.0; 0.5333333333333333 +1378775686; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 146800.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378775986; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378776286; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378776586; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378776886; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 141207.46666666667; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378777186; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378777486; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378777787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378778087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378778387; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378778687; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378778987; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.06666666667; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1378779287; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378779587; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378779887; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378780187; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378780487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378780787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378781087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378781387; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378781687; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1378781987; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1378782287; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378782587; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 176158.66666666666; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1378782887; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 194334.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1378783187; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 153790.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378783487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378783787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378784087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378784387; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378784687; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.6; 0.0; 0.0 +1378784987; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378785287; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378785587; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378785887; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378786187; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 145400.26666666666; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1378786487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 164973.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378786787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378787088; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378787388; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378787688; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378787988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378788288; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 7.2; 0.2; 0.13333333333333333 +1378788588; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.0; 0.0 +1378788888; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1378789188; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378789488; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378789788; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 132817.86666666667; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378790088; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1378790388; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378790688; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378790988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378791288; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378791588; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378791888; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378792188; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378792488; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378792788; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378793088; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1378793388; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378793688; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378793988; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378794288; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.0; 1.4; 0.0; 0.0 +1378794588; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378794889; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.06666666666666667; 8.4; 0.26666666666666666; 0.2 +1378795189; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.8; 0.0; 0.0 +1378795489; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378795789; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378796089; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 156586.93333333332; 0.0; 1.0; 0.0; 0.0 +1378796389; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1378796689; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378796989; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 137012.0; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1378797289; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 145400.53333333333; 0.0; 11.866666666666667; 0.0; 0.0 +1378797589; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378797889; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378798189; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378798489; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378798789; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378799089; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378799388; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378799688; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378799988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378800289; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.2; 0.0; 0.8; 0.0; 0.0 +1378800589; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1378800889; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 150993.6; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378801189; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378801489; 1; 2599.998989; 72.799971692; 2.8; 2097152.0; 661300.2666666667; 161.2; 22.2; 0.06666666666666667; 0.4 +1378801789; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 500518.13333333336; 0.0; 18.933333333333334; 0.0; 0.0 +1378802089; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 237674.66666666666; 31.8; 3.6; 0.0; 0.0 +1378802389; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 148197.6; 5.066666666666666; 2.4; 0.0; 0.0 +1378802689; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.8; 0.0; 0.0 +1378802989; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378803289; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1378803589; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1378803889; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 67106.4; 0.0; 1.8666666666666667; 0.0; 0.0 +1378804189; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 148196.8; 3.8666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378804489; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 174761.06666666668; 0.0; 0.7333333333333333; 0.0; 0.0 +1378804789; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378805089; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378805389; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 69902.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378805689; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378805989; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378806289; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378806589; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378806889; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378807189; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 149596.26666666666; 0.0; 1.0; 0.0; 0.0 +1378807489; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 164974.13333333333; 12.933333333333334; 13.266666666666667; 0.3333333333333333; 0.2 +1378807789; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 155186.93333333332; 0.0; 2.4; 0.13333333333333333; 0.4666666666666667 +1378808089; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 146799.46666666667; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378808389; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378808689; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 1.0; 1.6; 0.06666666666666667; 0.0 +1378808990; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 164974.66666666666; 0.0; 1.0; 0.0; 0.0 +1378809290; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137012.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378809590; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378809890; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378810190; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378810490; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378810790; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378811090; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378811390; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127226.13333333333; 0.0; 2.4; 0.0; 0.5333333333333333 +1378811690; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 141206.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378811990; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378812290; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378812590; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378812890; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 144003.46666666667; 0.0; 1.0; 0.0; 0.0 +1378813190; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 135614.13333333333; 0.0; 2.3333333333333335; 0.2; 0.13333333333333333 +1378813490; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 164974.4; 0.0; 6.2; 0.0; 0.0 +1378813790; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378814090; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378814390; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378814690; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 1.4; 1.2666666666666666; 0.0; 0.0 +1378814990; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 160779.46666666667; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1378815290; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 153789.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378815590; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378815890; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378816190; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378816490; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378816790; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378817090; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378817390; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378817690; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378817990; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378818290; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378818590; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125828.0; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1378818890; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378819190; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.2; 6.333333333333333; 0.0 +1378819490; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 7.066666666666666; 0.4; 0.13333333333333333 +1378819791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 176159.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378820091; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378820391; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378820691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 104856.0; 0.0; 1.2; 0.13333333333333333; 0.0 +1378820991; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378821291; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378821591; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378821891; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378822191; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 128624.26666666666; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1378822491; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378822791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155188.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378823091; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378823391; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378823691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.0; 1.2; 0.06666666666666667; 0.13333333333333333 +1378823991; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378824291; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.3333333333333333; 0.0 +1378824591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378824891; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378825191; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 155188.0; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378825491; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378825791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 171964.53333333333; 0.0; 2.0; 0.13333333333333333; 0.4666666666666667 +1378826091; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.06666666666666667; 1.4; 0.0; 0.0 +1378826391; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378826691; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378826991; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378827291; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378827591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 +1378827891; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378828191; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 145400.8; 0.0; 1.0; 0.0; 0.0 +1378828491; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378828791; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.2; 0.0 +1378829091; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378829391; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 117439.2; 0.13333333333333333; 2.4; 0.06666666666666667; 0.4666666666666667 +1378829691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378829991; 1; 2599.998989; 0.0; 0.0; 2097152.0; 176159.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378830291; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378830591; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378830892; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378831192; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378831492; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378831791; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378832091; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378832391; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132817.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378832691; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1378832991; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1378833291; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378833591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378833891; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378834191; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1378834492; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378834792; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378835092; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378835392; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378835692; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1378835992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 159383.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378836292; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 1.6; 0.0; 0.0 +1378836592; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 180352.8; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 +1378836892; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 159383.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378837192; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 138410.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378837492; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 104856.0; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378837792; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378838092; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1378838392; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378838692; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378838992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378839292; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.4666666666666667; 0.0 +1378839592; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378839892; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1378840192; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 170566.93333333332; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 +1378840492; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1378840792; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378841092; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 11.8; 0.0; 0.0 +1378841392; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1378841692; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378841992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378842293; 1; 2599.998989; 41.599983824; 1.6; 2097152.0; 251656.8; 161.93333333333334; 14.8; 1.4; 0.2 +1378842593; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 418030.4; 0.0; 1.6; 0.0; 0.0 +1378842893; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 198528.53333333333; 31.8; 3.7333333333333334; 0.0; 0.0 +1378843193; 1; 2599.998989; 0.0; 0.0; 2097152.0; 199927.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378843493; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 157984.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378843793; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 194334.13333333333; 0.0; 2.4; 0.0; 0.4666666666666667 +1378844093; 1; 2599.998989; 0.0; 0.0; 2097152.0; 171965.33333333334; 0.0; 1.0; 0.0; 0.0 +1378844393; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127225.6; 0.0; 7.2; 0.4666666666666667; 0.13333333333333333 +1378844693; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.33333333333; 0.0; 1.0; 0.0; 0.0 +1378844993; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142605.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378845293; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378845593; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378845893; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.2; 0.0 +1378846193; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378846493; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378846793; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378847093; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378847393; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 130021.6; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378847693; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378847993; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378848293; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378848593; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378848893; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378849193; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378849493; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378849793; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378850093; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378850393; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378850693; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 1.5333333333333334; 0.2; 0.13333333333333333 +1378850993; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 146799.2; 0.0; 8.0; 0.06666666666666667; 0.4666666666666667 +1378851293; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378851593; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378851893; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378852193; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378852493; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.06666666666666667; 1.8; 0.06666666666666667; 0.13333333333333333 +1378852794; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378853094; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 248860.8; 169.66666666666666; 179.86666666666667; 0.0; 0.0 +1378853394; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 167770.93333333332; 0.0; 1.0; 0.0; 0.0 +1378853694; 1; 2599.998989; 69.33330637333334; 2.666666666666667; 2097152.0; 640328.5333333333; 161.06666666666666; 22.0; 0.0; 0.4 +1378853994; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 408243.73333333334; 0.0; 2.7333333333333334; 0.0; 0.0 +1378854294; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 233480.26666666666; 31.8; 3.6; 0.0; 0.0 +1378854594; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 152391.73333333334; 13.333333333333334; 3.7333333333333334; 0.0; 0.4666666666666667 +1378854894; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 145401.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 +1378855194; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 123031.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378855494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 103457.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378855794; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1378856094; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 131419.73333333334; 0.06666666666666667; 1.4; 0.0; 0.0 +1378856394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.2; 0.0; 0.0 +1378856694; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 144003.73333333334; 0.0; 7.666666666666667; 0.2; 0.13333333333333333 +1378856994; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 159382.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378857294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378857594; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378857894; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378858194; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 157984.0; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1378858494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.06666666666666667; 0.0 +1378858794; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378859094; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378859394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1378859694; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.5333333333333333; 1.3333333333333333; 0.0; 0.0 +1378859994; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378860294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378860594; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378860894; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378861194; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378861494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 141206.93333333332; 0.0; 1.0; 0.0; 0.0 +1378861794; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 183149.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378862094; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 152392.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378862394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378862694; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378862994; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 124429.86666666667; 0.0; 7.066666666666666; 0.26666666666666666; 0.06666666666666667 +1378863294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378863595; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378863895; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378864195; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378864494; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378864794; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 128623.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378865094; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378865394; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 114642.93333333333; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378865694; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378865994; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1378866294; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378866594; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378866894; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1378867194; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378867494; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378867794; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1378868094; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378868394; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 1.2666666666666666; 0.0 +1378868694; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 137012.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378868994; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 178955.2; 12.8; 14.2; 0.3333333333333333; 0.7333333333333333 +1378869294; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 201325.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 +1378869594; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 171964.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378869894; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.0; 0.0; 0.8; 0.0; 0.0 +1378870194; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378870494; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1378870794; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378871094; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378871394; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378871695; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378871995; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378872295; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378872595; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 157983.2; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378872895; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378873195; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378873495; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378873795; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378874095; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1378874395; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378874695; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378874995; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1378875295; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.6; 0.0; 0.8; 0.0; 0.0 +1378875595; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 7.2; 0.26666666666666666; 0.2 +1378875895; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378876195; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1378876495; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 157984.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378876795; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378877095; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378877395; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378877695; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378877995; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378878295; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378878595; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378878895; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378879195; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378879495; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378879795; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 157983.73333333334; 0.06666666666666667; 2.066666666666667; 0.0; 0.4666666666666667 +1378880095; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378880396; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378880696; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378880996; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 148197.6; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1378881296; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.4; 0.0; 0.06666666666666667 +1378881596; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 2.1333333333333333; 0.0; 0.0 +1378881896; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378882196; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378882496; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378882796; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378883096; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 1.4666666666666666; 1.4; 0.0; 0.0 +1378883396; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 195732.26666666666; 0.0; 2.2666666666666666; 0.0; 0.5333333333333333 +1378883696; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 199926.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378883996; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378884296; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378884596; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 11.8; 1.7333333333333334; 0.0 +1378884896; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378885196; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378885496; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.8; 0.0; 0.0 +1378885796; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378886096; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378886396; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378886696; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378886996; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 157983.2; 0.13333333333333333; 9.266666666666667; 0.26666666666666666; 0.6 +1378887296; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 178955.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378887596; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.9333333333333333; 0.0 +1378887896; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378888196; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378888496; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1378888796; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378889096; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378889396; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109049.86666666667; 0.0; 1.0; 0.0; 0.0 +1378889696; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378889997; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378890297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378890597; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 156585.33333333334; 0.2; 2.4; 0.0; 0.4666666666666667 +1378890897; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378891197; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378891497; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 2.0; 0.0 +1378891797; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378892097; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378892397; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378892697; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 8.066666666666666; 0.2; 0.13333333333333333 +1378892997; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378893297; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 146799.2; 20.4; 2.1333333333333333; 0.0; 0.06666666666666667 +1378893597; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 149596.26666666666; 0.0; 4.066666666666666; 0.0; 0.0 +1378893897; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 183149.86666666667; 0.0; 2.8; 0.0; 0.0 +1378894197; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148197.06666666668; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 +1378894497; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378894797; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378895097; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378895397; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378895697; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378895997; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378896297; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378896597; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378896897; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1378897197; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378897497; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378897797; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 166372.26666666666; 0.0; 2.4; 0.0; 0.5333333333333333 +1378898097; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 173362.93333333332; 0.0; 1.2; 0.0; 0.0 +1378898397; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1378898697; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 7.2; 0.2; 0.13333333333333333 +1378898997; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378899297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378899597; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378899897; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 160780.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378900197; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 1.0666666666666667; 1.4; 0.0 +1378900497; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378900797; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378901097; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1378901397; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130022.4; 0.06666666666666667; 2.533333333333333; 0.0; 0.5333333333333333 +1378901697; 1; 2599.998989; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 1.0; 0.0; 0.0 +1378901997; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378902297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1378902598; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378902898; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378903198; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378903498; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378903798; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378904098; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378904398; 1; 2599.998989; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378904698; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378904998; 1; 2599.998989; 77.99996967000001; 3.0; 2097152.0; 450186.6666666667; 161.06666666666666; 107.6; 12.933333333333334; 1.2666666666666666 +1378905298; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 633338.4; 0.0; 45.13333333333333; 0.2; 0.13333333333333333 +1378905598; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 297792.8; 31.8; 3.466666666666667; 0.0; 0.0 +1378905898; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 162177.86666666667; 5.066666666666666; 2.2; 0.0; 0.0 +1378906198; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.8; 0.0; 1.6; 0.0; 0.0 +1378906498; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378906798; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 -- cgit v1.2.3 From 1af7b83695d997381163f2b72c67ed26d5b4891f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 12:16:02 +0200 Subject: fix(capelin): Keep trace order after sampling This change fixes an issue with the workload sampler where the resulting workload entries would not be ordered properly according to their submission time. --- .../main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt | 2 ++ .../kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index fa9fa2fc..b5090119 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -255,6 +255,8 @@ suspend fun processTrace( offset = entry.start - clock.millis() } + // Make sure the trace entries are ordered by submission time + assert(entry.start - offset >= 0) { "Invalid trace order" } delay(max(0, (entry.start - offset) - clock.millis())) launch { chan.send(Unit) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt index 5ad75565..0f49ecd2 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt @@ -53,8 +53,7 @@ public class ParquetTraceReader( this.zip(listOf(workload)) } } - .map { sampleWorkload(it.first, workload, it.second, seed) } - .flatten() + .flatMap { sampleWorkload(it.first, workload, it.second, seed).sortedBy(TraceEntry::start) } .iterator() override fun hasNext(): Boolean = iterator.hasNext() -- cgit v1.2.3 From 97a28129e4638f601864a08f483908907b9026e6 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 14:40:28 +0200 Subject: fix(capelin): Update Bitbrains trace tests This change updates the Bitbrains trace tests with the updated trace that does not hardcode the duration of the trace fragments. --- .../org/opendc/compute/simulator/SimHostTest.kt | 6 +-- .../experiments/capelin/CapelinIntegrationTest.kt | 12 +++--- .../src/test/resources/trace/meta.parquet | Bin 2148 -> 2081 bytes .../src/test/resources/trace/trace.parquet | Bin 1672463 -> 1647189 bytes .../opendc-experiments-radice/build.gradle.kts | 48 +++++++++++++++++++++ 5 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-radice/build.gradle.kts diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 45fdb268..fc96cec8 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -116,9 +116,9 @@ internal class SimHostTest { "workload" to SimTraceWorkload( sequenceOf( SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(duration * 1000L, duration * 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(duration * 2000L, duration * 1000, 0.0, 2), - SimTraceWorkload.Fragment(duration * 3000L, duration * 1000, 2 * 73.0, 2) + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 2 * 3100.0, 2), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 2), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 2 * 73.0, 2) ), offset = 1 ) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 393fb88d..0437a022 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -114,9 +114,9 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(155252275351, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(155086837645, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(725049, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(219751355711, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(206351165081, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(1148906334, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } @@ -151,9 +151,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(29454904468, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(29355293349, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(0, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(37954956986, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(34840774250, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(971076806, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet index ce7a812c..ee76d38f 100644 Binary files a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet and b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet differ diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet index 1d7ce882..9b1cde13 100644 Binary files a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet and b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet differ diff --git a/opendc-experiments/opendc-experiments-radice/build.gradle.kts b/opendc-experiments/opendc-experiments-radice/build.gradle.kts new file mode 100644 index 00000000..c1515165 --- /dev/null +++ b/opendc-experiments/opendc-experiments-radice/build.gradle.kts @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Experiments for the Risk Analysis work" + +/* Build configuration */ +plugins { + `experiment-conventions` + `testing-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcHarness.opendcHarnessApi) + implementation(projects.opendcFormat) + implementation(projects.opendcSimulator.opendcSimulatorCore) + implementation(projects.opendcSimulator.opendcSimulatorCompute) + implementation(projects.opendcSimulator.opendcSimulatorFailures) + implementation(projects.opendcCompute.opendcComputeSimulator) + implementation(projects.opendcTelemetry.opendcTelemetrySdk) + + implementation(libs.kotlin.logging) + implementation(libs.config) + implementation(libs.progressbar) + implementation(libs.clikt) + + implementation(libs.parquet) + testImplementation(libs.log4j.slf4j) +} -- cgit v1.2.3 From 709cd4909ccc1305c7acfdf666156168d66646eb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 21:54:09 +0200 Subject: feat(simulator): Add support for reporting interfered work This change adds support to the simulator for reporting the work lost due to performance interference. --- .../compute/kernel/SimFairShareHypervisor.kt | 4 ++- .../resources/SimResourceDistributorMaxMin.kt | 36 +++++++++++++++++++--- .../simulator/resources/SimResourceSwitchMaxMin.kt | 2 +- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index 17130d34..c31b1f6b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -67,6 +67,7 @@ public class SimFairShareHypervisor( private var lastDemand = 0.0 private var lastActual = 0.0 private var lastOvercommit = 0.0 + private var lastInterference = 0.0 private var lastReport = Long.MIN_VALUE override fun onConverge(timestamp: Long) { @@ -79,7 +80,7 @@ public class SimFairShareHypervisor( (counters.demand - lastDemand).toLong(), (counters.actual - lastActual).toLong(), (counters.overcommit - lastOvercommit).toLong(), - 0L, + (counters.interference - lastInterference).toLong(), lastCpuUsage, lastCpuDemand ) @@ -91,6 +92,7 @@ public class SimFairShareHypervisor( lastDemand = counters.demand lastActual = counters.actual lastOvercommit = counters.overcommit + lastInterference = counters.interference val load = lastCpuDemand / ctx.cpus.sumOf { it.model.frequency } triggerGovernors(load) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index a985986d..6c1e134b 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -22,9 +22,9 @@ package org.opendc.simulator.resources -import org.opendc.simulator.resources.impl.SimResourceCountersImpl import org.opendc.simulator.resources.interference.InterferenceDomain import org.opendc.simulator.resources.interference.InterferenceKey +import kotlin.math.max import kotlin.math.min /** @@ -71,9 +71,23 @@ public class SimResourceDistributorMaxMin( /** * The resource counters of this distributor. */ - public val counters: SimResourceCounters + public val counters: Counters get() = _counters - private val _counters = SimResourceCountersImpl() + private val _counters = object : Counters { + override var demand: Double = 0.0 + override var actual: Double = 0.0 + override var overcommit: Double = 0.0 + override var interference: Double = 0.0 + + override fun reset() { + demand = 0.0 + actual = 0.0 + overcommit = 0.0 + interference = 0.0 + } + + override fun toString(): String = "SimResourceDistributorMaxMin.Counters[demand=$demand,actual=$actual,overcommit=$overcommit,interference=$interference]" + } /* SimResourceDistributor */ override fun newOutput(key: InterferenceKey?): SimResourceCloseableProvider { @@ -110,6 +124,16 @@ public class SimResourceDistributorMaxMin( } } + /** + * Extended [SimResourceCounters] interface for the distributor. + */ + public interface Counters : SimResourceCounters { + /** + * The amount of work lost due to interference. + */ + public val interference: Double + } + /** * Update the counters of the distributor. */ @@ -326,7 +350,11 @@ public class SimResourceDistributorMaxMin( } // Compute the work that was actually granted to the output. - return (totalAllocatedWork - totalRemainingWork) * fraction * perfScore + val potentialConsumedWork = (totalAllocatedWork - totalRemainingWork) * fraction + + _counters.interference += potentialConsumedWork * max(0.0, 1 - perfScore) + + return potentialConsumedWork } /* Comparable */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt index d988b70d..e368609f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt @@ -53,7 +53,7 @@ public class SimResourceSwitchMaxMin( /** * The resource counters to track the execution metrics of all switch resources. */ - override val counters: SimResourceCounters + override val counters: SimResourceDistributorMaxMin.Counters get() = distributor.counters /** -- cgit v1.2.3 From 3721831204c2d350b93ea265731c0970cbd8fce4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 24 Aug 2021 12:55:49 +0200 Subject: feat(compute): Add support for SimHost failure This change adds support for failures in the SimHost implementation. Failing a host will now cause the virtual machine to enter an error state. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 26 ++++-- .../org/opendc/compute/simulator/SimHostTest.kt | 96 ++++++++++++++++++++++ 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 5ea577f3..be771f6d 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -46,6 +46,7 @@ import org.opendc.simulator.resources.SimResourceInterpreter import java.util.* import kotlin.coroutines.CoroutineContext import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException /** * A [Host] that is simulates virtual machines on a physical machine using [SimHypervisor]. @@ -315,10 +316,16 @@ public class SimHost( override suspend fun fail() { _state = HostState.DOWN + for (guest in guests.values) { + guest.fail() + } } override suspend fun recover() { _state = HostState.UP + for (guest in guests.values) { + guest.start() + } } /** @@ -329,7 +336,7 @@ public class SimHost( suspend fun start() { when (state) { - ServerState.TERMINATED -> { + ServerState.TERMINATED, ServerState.ERROR -> { logger.info { "User requested to start server ${server.uid}" } launch() } @@ -356,9 +363,15 @@ public class SimHost( suspend fun terminate() { stop() + machine.close() state = ServerState.DELETED } + suspend fun fail() { + stop() + state = ServerState.ERROR + } + private var job: Job? = null private suspend fun launch() = suspendCancellableCoroutine { cont -> @@ -366,16 +379,19 @@ public class SimHost( val workload = mapper.createWorkload(server) job = scope.launch { - delay(1) // TODO Introduce boot time - init() - cont.resume(Unit) + try { + delay(1) // TODO Introduce boot time + init() + cont.resume(Unit) + } catch (e: Throwable) { + cont.resumeWithException(e) + } try { machine.run(workload, mapOf("driver" to this@SimHost, "server" to server)) exit(null) } catch (cause: Throwable) { exit(cause) } finally { - machine.close() job = null } } diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index fc96cec8..93a2248a 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -185,6 +185,102 @@ internal class SimHostTest { ) } + /** + * Test failure of the host. + */ + @Test + fun testFailure() = runBlockingSimulation { + var requestedWork = 0L + var grantedWork = 0L + + val meterProvider: MeterProvider = SdkMeterProvider + .builder() + .setClock(clock.toOtelClock()) + .build() + + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val host = SimHost( + uid = UUID.randomUUID(), + name = "test", + model = machineModel, + meta = emptyMap(), + coroutineContext, + interpreter, + meterProvider.get("opendc-compute-simulator"), + SimFairShareHypervisorProvider() + ) + val duration = 5 * 60L + val image = MockImage( + UUID.randomUUID(), + "", + emptyMap(), + mapOf( + "workload" to SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), + SimTraceWorkload.Fragment(duration * 1000L, duration * 1000, 2 * 3500.0, 2), + SimTraceWorkload.Fragment(duration * 2000L, duration * 1000, 0.0, 2), + SimTraceWorkload.Fragment(duration * 3000L, duration * 1000, 2 * 183.0, 2) + ), + offset = 1 + ) + ) + ) + val flavor = MockFlavor(2, 0) + val server = MockServer(UUID.randomUUID(), "a", flavor, image) + + // Setup metric reader + val reader = CoroutineMetricReader( + this, listOf(meterProvider as MetricProducer), + object : MetricExporter { + override fun export(metrics: Collection): CompletableResultCode { + val metricsByName = metrics.associateBy { it.name } + metricsByName["cpu.work.total"]?.let { + requestedWork += it.doubleSummaryData.points.first().sum.toLong() + } + metricsByName["cpu.work.granted"]?.let { + grantedWork += it.doubleSummaryData.points.first().sum.toLong() + } + return CompletableResultCode.ofSuccess() + } + + override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() + + override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() + }, + exportInterval = duration * 1000L + ) + + coroutineScope { + host.spawn(server) + delay(5000L) + host.fail() + delay(5000L) + host.recover() + + suspendCancellableCoroutine { cont -> + host.addListener(object : HostListener { + override fun onStateChanged(host: Host, server: Server, newState: ServerState) { + if (newState == ServerState.TERMINATED) { + cont.resume(Unit) + } + } + }) + } + } + + host.close() + // Ensure last cycle is collected + delay(1000L * duration) + + reader.close() + + assertAll( + { assertEquals(2226039, requestedWork, "Total time does not match") }, + { assertEquals(1086039, grantedWork, "Down time does not match") }, + ) + } + private class MockFlavor( override val cpuCount: Int, override val memorySize: Long -- cgit v1.2.3 From 5266ecd476a18f601cb4eb6166f4c8338c440210 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 18 Aug 2021 21:54:55 +0200 Subject: test(capelin): Add tests for interference and failures This change adds tests to the Capelin integration suite for performance interference as well as failures. These test more accurately the experiment setup. --- .../experiments/capelin/ExperimentHelpers.kt | 2 +- .../capelin/monitor/ExperimentMetricExporter.kt | 2 +- .../experiments/capelin/CapelinIntegrationTest.kt | 105 +++++++++++++++++++++ .../resources/bitbrains-perf-interference.json | 21 +++++ 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/resources/bitbrains-perf-interference.json diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index b5090119..d7df4454 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -277,7 +277,7 @@ suspend fun processTrace( override fun onStateChanged(server: Server, newState: ServerState) { monitor.reportVmStateChange(clock.millis(), server, newState) - if (newState == ServerState.TERMINATED || newState == ServerState.ERROR) { + if (newState == ServerState.TERMINATED) { cont.resume(Unit) } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index f520a28c..7fb2f83c 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -74,7 +74,7 @@ public class ExperimentMetricExporter( m.overcommissionedBurst = v.toLong() } - mapDoubleSummary(metrics["cpu.work.interfered"], hostMetrics) { m, v -> + mapDoubleSummary(metrics["cpu.work.interference"], hostMetrics) { m, v -> m.interferedBurst = v.toLong() } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 0437a022..a3300b71 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -39,12 +39,15 @@ import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.monitor.ExperimentMonitor import org.opendc.experiments.capelin.trace.ParquetTraceReader +import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader import org.opendc.format.environment.EnvironmentReader import org.opendc.format.trace.TraceReader +import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation import java.io.File +import java.util.* /** * An integration test suite for the SC20 experiments. @@ -63,6 +66,9 @@ class CapelinIntegrationTest { monitor = TestExperimentReporter() } + /** + * Test a large simulation setup. + */ @Test fun testLarge() = runBlockingSimulation { val failures = false @@ -121,6 +127,9 @@ class CapelinIntegrationTest { ) } + /** + * Test a small simulation setup. + */ @Test fun testSmall() = runBlockingSimulation { val seed = 1 @@ -158,6 +167,102 @@ class CapelinIntegrationTest { ) } + /** + * Test a small simulation setup with interference. + */ + @Test + fun testInterference() = runBlockingSimulation { + val seed = 1 + val chan = Channel(Channel.CONFLATED) + val allocationPolicy = FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) + val traceReader = createTestTraceReader(0.25, seed) + val environmentReader = createTestEnvironmentReader("single") + + val perfInterferenceInput = checkNotNull(CapelinIntegrationTest::class.java.getResourceAsStream("/bitbrains-perf-interference.json")) + val performanceInterferenceModel = + PerformanceInterferenceReader(perfInterferenceInput).use { VmInterferenceModel(it.read(), Random(seed.toLong())) } + + val meterProvider = createMeterProvider(clock) + + withComputeService(clock, meterProvider, environmentReader, allocationPolicy, performanceInterferenceModel) { scheduler -> + withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + processTrace( + clock, + traceReader, + scheduler, + chan, + monitor + ) + } + } + + val metrics = collectMetrics(meterProvider as MetricProducer) + println("Finish SUBMIT=${metrics.submittedVms} FAIL=${metrics.unscheduledVms} QUEUE=${metrics.queuedVms} RUNNING=${metrics.runningVms}") + + // Note that these values have been verified beforehand + assertAll( + { assertEquals(37954956986, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(34840774250, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(971076806, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(13885404, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } + ) + } + + /** + * Test a small simulation setup with failures. + */ + @Test + fun testFailures() = runBlockingSimulation { + val seed = 1 + val chan = Channel(Channel.CONFLATED) + val allocationPolicy = FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) + val traceReader = createTestTraceReader(0.25, seed) + val environmentReader = createTestEnvironmentReader("single") + + val meterProvider = createMeterProvider(clock) + + withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> + val failureDomain = + createFailureDomain( + this, + clock, + seed, + 24.0 * 7, + scheduler, + chan + ) + + withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + processTrace( + clock, + traceReader, + scheduler, + chan, + monitor + ) + } + + failureDomain.cancel() + } + + val metrics = collectMetrics(meterProvider as MetricProducer) + println("Finish SUBMIT=${metrics.submittedVms} FAIL=${metrics.unscheduledVms} QUEUE=${metrics.queuedVms} RUNNING=${metrics.runningVms}") + + // Note that these values have been verified beforehand + assertAll( + { assertEquals(25336984869, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(23668547517, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(368151656, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } + ) + } + /** * Obtain the trace reader for the test. */ diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/bitbrains-perf-interference.json b/opendc-experiments/opendc-experiments-capelin/src/test/resources/bitbrains-perf-interference.json new file mode 100644 index 00000000..51fc6366 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/test/resources/bitbrains-perf-interference.json @@ -0,0 +1,21 @@ +[ + { + "vms": [ + "141", + "379", + "851", + "116" + ], + "minServerLoad": 0.0, + "performanceScore": 0.8830158730158756 + }, + { + "vms": [ + "205", + "116", + "463" + ], + "minServerLoad": 0.0, + "performanceScore": 0.7133055555552751 + } +] -- cgit v1.2.3 From f111081627280d4e7e1d7147c56cdce708e32433 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 14:06:39 +0200 Subject: build: Upgrade to OpenTelemetry 1.5 This change upgrades the OpenTelemetry dependency to version 1.5, which contains various breaking changes in the metrics API. --- gradle/libs.versions.toml | 7 +- .../compute/service/internal/ComputeServiceImpl.kt | 14 ++-- .../opendc-compute-simulator/build.gradle.kts | 1 + .../kotlin/org/opendc/compute/simulator/SimHost.kt | 81 ++++++++++++---------- .../org/opendc/compute/simulator/SimHostTest.kt | 19 +++-- .../opendc-experiments-capelin/build.gradle.kts | 1 + .../experiments/capelin/ExperimentHelpers.kt | 13 ---- .../capelin/monitor/ExperimentMetricExporter.kt | 77 ++++++++++---------- .../capelin/monitor/ExperimentMonitor.kt | 3 +- .../capelin/monitor/ParquetExperimentMonitor.kt | 8 +-- .../experiments/capelin/CapelinIntegrationTest.kt | 34 ++++----- .../opendc/experiments/tf20/core/SimTFDevice.kt | 16 +++-- .../org/opendc/faas/service/FunctionObject.kt | 44 +++++++----- .../faas/service/internal/FaaSServiceImpl.kt | 6 +- .../compute/kernel/SimAbstractHypervisor.kt | 6 ++ .../simulator/compute/kernel/SimHypervisor.kt | 6 ++ .../org/opendc/web/runner/WebExperimentMonitor.kt | 8 +-- .../service/internal/WorkflowServiceImpl.kt | 12 ++-- 18 files changed, 185 insertions(+), 171 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a15fa45d..4f2ec58c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,8 +3,9 @@ junit-jupiter = "5.7.2" junit-platform = "1.7.2" slf4j = "1.7.32" log4j = "2.14.1" -opentelemetry-main = "1.4.1" -opentelemetry-metrics = "1.4.1-alpha" +opentelemetry-main = "1.5.0" +opentelemetry-metrics = "1.5.0-alpha" +opentelemetry-semconv = "1.5.0-alpha" hadoop = "3.3.0" ktor = "1.6.2" jackson = "2.12.4" @@ -23,6 +24,8 @@ opentelemetry-api-main = { module = "io.opentelemetry:opentelemetry-api", versio opentelemetry-sdk-main = { module = "io.opentelemetry:opentelemetry-sdk", version.ref = "opentelemetry-main" } opentelemetry-api-metrics = { module = "io.opentelemetry:opentelemetry-api-metrics", version.ref = "opentelemetry-metrics" } opentelemetry-sdk-metrics = { module = "io.opentelemetry:opentelemetry-sdk-metrics", version.ref = "opentelemetry-metrics" } +opentelemetry-semconv = { module = "io.opentelemetry:opentelemetry-semconv", version.ref = "opentelemetry-semconv" } + # Testing junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" } diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index e7807177..d7a7e8f8 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -106,7 +106,7 @@ internal class ComputeServiceImpl( /** * The number of servers that have been submitted to the service for provisioning. */ - private val _submittedServers = meter.longCounterBuilder("servers.submitted") + private val _submittedServers = meter.counterBuilder("servers.submitted") .setDescription("Number of start requests") .setUnit("1") .build() @@ -114,7 +114,7 @@ internal class ComputeServiceImpl( /** * The number of servers that failed to be scheduled. */ - private val _unscheduledServers = meter.longCounterBuilder("servers.unscheduled") + private val _unscheduledServers = meter.counterBuilder("servers.unscheduled") .setDescription("Number of unscheduled servers") .setUnit("1") .build() @@ -122,7 +122,7 @@ internal class ComputeServiceImpl( /** * The number of servers that are waiting to be provisioned. */ - private val _waitingServers = meter.longUpDownCounterBuilder("servers.waiting") + private val _waitingServers = meter.upDownCounterBuilder("servers.waiting") .setDescription("Number of servers waiting to be provisioned") .setUnit("1") .build() @@ -130,7 +130,7 @@ internal class ComputeServiceImpl( /** * The number of servers that are waiting to be provisioned. */ - private val _runningServers = meter.longUpDownCounterBuilder("servers.active") + private val _runningServers = meter.upDownCounterBuilder("servers.active") .setDescription("Number of servers currently running") .setUnit("1") .build() @@ -138,7 +138,7 @@ internal class ComputeServiceImpl( /** * The number of servers that have finished running. */ - private val _finishedServers = meter.longCounterBuilder("servers.finished") + private val _finishedServers = meter.counterBuilder("servers.finished") .setDescription("Number of servers that finished running") .setUnit("1") .build() @@ -146,7 +146,7 @@ internal class ComputeServiceImpl( /** * The number of hosts registered at the compute service. */ - private val _hostCount = meter.longUpDownCounterBuilder("hosts.total") + private val _hostCount = meter.upDownCounterBuilder("hosts.total") .setDescription("Number of hosts") .setUnit("1") .build() @@ -154,7 +154,7 @@ internal class ComputeServiceImpl( /** * The number of available hosts registered at the compute service. */ - private val _availableHostCount = meter.longUpDownCounterBuilder("hosts.available") + private val _availableHostCount = meter.upDownCounterBuilder("hosts.available") .setDescription("Number of available hosts") .setUnit("1") .build() diff --git a/opendc-compute/opendc-compute-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts index b31a2114..c5a9e668 100644 --- a/opendc-compute/opendc-compute-simulator/build.gradle.kts +++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { api(projects.opendcSimulator.opendcSimulatorCompute) api(projects.opendcSimulator.opendcSimulatorFailures) implementation(projects.opendcUtils) + implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) testImplementation(projects.opendcSimulator.opendcSimulatorCore) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index be771f6d..546584b6 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -22,8 +22,9 @@ package org.opendc.compute.simulator +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter -import io.opentelemetry.api.metrics.common.Labels +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import kotlinx.coroutines.* import mu.KotlinLogging import org.opendc.compute.api.Flavor @@ -107,15 +108,13 @@ public class SimHost( cpuUsage: Double, cpuDemand: Double ) { - - _batch.put(_cpuWork, requestedWork.toDouble()) - _batch.put(_cpuWorkGranted, grantedWork.toDouble()) - _batch.put(_cpuWorkOvercommit, overcommittedWork.toDouble()) - _batch.put(_cpuWorkInterference, interferedWork.toDouble()) - _batch.put(_cpuUsage, cpuUsage) - _batch.put(_cpuDemand, cpuDemand) - _batch.put(_cpuPower, machine.psu.powerDraw) - _batch.record() + _totalWork.add(requestedWork.toDouble()) + _grantedWork.add(grantedWork.toDouble()) + _overcommittedWork.add(overcommittedWork.toDouble()) + _interferedWork.add(interferedWork.toDouble()) + _cpuDemand.record(cpuDemand) + _cpuUsage.record(cpuUsage) + _powerUsage.record(machine.psu.powerDraw) } } ) @@ -135,86 +134,92 @@ public class SimHost( field = value } - override val model: HostModel = HostModel(model.cpus.size, model.memory.map { it.size }.sum()) + override val model: HostModel = HostModel(model.cpus.size, model.memory.sumOf { it.size }) /** - * The number of guests on the host. + * The total number of guests. */ - private val _guests = meter.longUpDownCounterBuilder("guests.total") + private val _guests = meter.upDownCounterBuilder("guests.total") .setDescription("Number of guests") .setUnit("1") .build() - .bind(Labels.of("host", uid.toString())) + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The number of active guests on the host. */ - private val _activeGuests = meter.longUpDownCounterBuilder("guests.active") + private val _activeGuests = meter.upDownCounterBuilder("guests.active") .setDescription("Number of active guests") .setUnit("1") .build() - .bind(Labels.of("host", uid.toString())) + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The CPU usage on the host. + * The CPU demand of the host. */ - private val _cpuUsage = meter.doubleValueRecorderBuilder("cpu.usage") - .setDescription("The amount of CPU resources used by the host") + private val _cpuDemand = meter.histogramBuilder("cpu.demand") + .setDescription("The amount of CPU resources the guests would use if there were no CPU contention or CPU limits") .setUnit("MHz") .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The CPU demand on the host. + * The CPU usage of the host. */ - private val _cpuDemand = meter.doubleValueRecorderBuilder("cpu.demand") - .setDescription("The amount of CPU resources the guests would use if there were no CPU contention or CPU limits") + private val _cpuUsage = meter.histogramBuilder("cpu.usage") + .setDescription("The amount of CPU resources used by the host") .setUnit("MHz") .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The requested work for the CPU. + * The power usage of the host. */ - private val _cpuPower = meter.doubleValueRecorderBuilder("power.usage") + private val _powerUsage = meter.histogramBuilder("power.usage") .setDescription("The amount of power used by the CPU") .setUnit("W") .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The requested work for the CPU. + * The total amount of work supplied to the CPU. */ - private val _cpuWork = meter.doubleValueRecorderBuilder("cpu.work.total") + private val _totalWork = meter.counterBuilder("cpu.work.total") .setDescription("The amount of work supplied to the CPU") .setUnit("1") + .ofDoubles() .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The work actually performed by the CPU. + * The work performed by the CPU. */ - private val _cpuWorkGranted = meter.doubleValueRecorderBuilder("cpu.work.granted") + private val _grantedWork = meter.counterBuilder("cpu.work.granted") .setDescription("The amount of work performed by the CPU") .setUnit("1") + .ofDoubles() .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The work that could not be performed by the CPU due to overcommitting resource. + * The amount not performed by the CPU due to overcommitment. */ - private val _cpuWorkOvercommit = meter.doubleValueRecorderBuilder("cpu.work.overcommit") + private val _overcommittedWork = meter.counterBuilder("cpu.work.overcommit") .setDescription("The amount of work not performed by the CPU due to overcommitment") .setUnit("1") + .ofDoubles() .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** - * The work that could not be performed by the CPU due to interference. + * The amount of work not performed by the CPU due to interference. */ - private val _cpuWorkInterference = meter.doubleValueRecorderBuilder("cpu.work.interference") + private val _interferedWork = meter.counterBuilder("cpu.work.interference") .setDescription("The amount of work not performed by the CPU due to interference") .setUnit("1") + .ofDoubles() .build() - - /** - * The batch recorder used to record multiple metrics atomically. - */ - private val _batch = meter.newBatchRecorder("host", uid.toString()) + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) init { // Launch hypervisor onto machine @@ -273,8 +278,8 @@ public class SimHost( override suspend fun delete(server: Server) { val guest = guests.remove(server) ?: return - guest.terminate() _guests.add(-1) + guest.terminate() } override fun addListener(listener: HostListener) { diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 93a2248a..1ba3a9a1 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -133,17 +133,14 @@ internal class SimHostTest { object : MetricExporter { override fun export(metrics: Collection): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } - val totalWork = metricsByName["cpu.work.total"] - if (totalWork != null) { - requestedWork += totalWork.doubleSummaryData.points.first().sum.toLong() + metricsByName["cpu.work.total"]?.let { + requestedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() } - val grantedWorkCycle = metricsByName["cpu.work.granted"] - if (grantedWorkCycle != null) { - grantedWork += grantedWorkCycle.doubleSummaryData.points.first().sum.toLong() + metricsByName["cpu.work.granted"]?.let { + grantedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() } - val overcommittedWorkCycle = metricsByName["cpu.work.overcommit"] - if (overcommittedWorkCycle != null) { - overcommittedWork += overcommittedWorkCycle.doubleSummaryData.points.first().sum.toLong() + metricsByName["cpu.work.overcommit"]?.let { + overcommittedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() } return CompletableResultCode.ofSuccess() } @@ -236,10 +233,10 @@ internal class SimHostTest { override fun export(metrics: Collection): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } metricsByName["cpu.work.total"]?.let { - requestedWork += it.doubleSummaryData.points.first().sum.toLong() + requestedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() } metricsByName["cpu.work.granted"]?.let { - grantedWork += it.doubleSummaryData.points.first().sum.toLong() + grantedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() } return CompletableResultCode.ofSuccess() } diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 324cae3e..53643aba 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { implementation(projects.opendcSimulator.opendcSimulatorFailures) implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTelemetry.opendcTelemetrySdk) + implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) implementation(libs.config) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index d7df4454..4cffb8d3 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -24,11 +24,7 @@ package org.opendc.experiments.capelin import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory -import io.opentelemetry.sdk.metrics.common.InstrumentType import io.opentelemetry.sdk.metrics.export.MetricProducer -import io.opentelemetry.sdk.metrics.view.InstrumentSelector -import io.opentelemetry.sdk.metrics.view.View import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import mu.KotlinLogging @@ -298,18 +294,9 @@ suspend fun processTrace( * Create a [MeterProvider] instance for the experiment. */ fun createMeterProvider(clock: Clock): MeterProvider { - val powerSelector = InstrumentSelector.builder() - .setInstrumentNameRegex("power\\.usage") - .setInstrumentType(InstrumentType.VALUE_RECORDER) - .build() - val powerView = View.builder() - .setAggregatorFactory(AggregatorFactory.lastValue()) - .build() - return SdkMeterProvider .builder() .setClock(clock.toOtelClock()) - .registerView(powerSelector, powerView) .build() } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index 7fb2f83c..16358817 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -22,10 +22,10 @@ package org.opendc.experiments.capelin.monitor -import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.sdk.common.CompletableResultCode import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import org.opendc.compute.service.driver.Host import java.time.Clock @@ -37,7 +37,7 @@ public class ExperimentMetricExporter( private val clock: Clock, private val hosts: Map ) : MetricExporter { - private val hostKey = AttributeKey.stringKey("host") + private val hostKey = ResourceAttributes.HOST_ID override fun export(metrics: Collection): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } @@ -46,50 +46,31 @@ public class ExperimentMetricExporter( return CompletableResultCode.ofSuccess() } + private var lastHostMetrics: Map = emptyMap() + private val hostMetricsSingleton = HostMetrics() + private fun reportHostMetrics(metrics: Map) { val hostMetrics = mutableMapOf() hosts.mapValuesTo(hostMetrics) { HostMetrics() } - mapDoubleSummary(metrics["cpu.demand"], hostMetrics) { m, v -> - m.cpuDemand = v - } - - mapDoubleSummary(metrics["cpu.usage"], hostMetrics) { m, v -> - m.cpuUsage = v - } - - mapDoubleGauge(metrics["power.usage"], hostMetrics) { m, v -> - m.powerDraw = v - } - - mapDoubleSummary(metrics["cpu.work.total"], hostMetrics) { m, v -> - m.requestedBurst = v.toLong() - } - - mapDoubleSummary(metrics["cpu.work.granted"], hostMetrics) { m, v -> - m.grantedBurst = v.toLong() - } - - mapDoubleSummary(metrics["cpu.work.overcommit"], hostMetrics) { m, v -> - m.overcommissionedBurst = v.toLong() - } - - mapDoubleSummary(metrics["cpu.work.interference"], hostMetrics) { m, v -> - m.interferedBurst = v.toLong() - } - - mapLongSum(metrics["guests.active"], hostMetrics) { m, v -> - m.numberOfDeployedImages = v.toInt() - } + mapDoubleSummary(metrics["cpu.demand"], hostMetrics) { m, v -> m.cpuDemand = v } + mapDoubleSummary(metrics["cpu.usage"], hostMetrics) { m, v -> m.cpuUsage = v } + mapDoubleGauge(metrics["power.usage"], hostMetrics) { m, v -> m.powerDraw = v } + mapDoubleSum(metrics["cpu.work.total"], hostMetrics) { m, v -> m.requestedBurst = v } + mapDoubleSum(metrics["cpu.work.granted"], hostMetrics) { m, v -> m.grantedBurst = v } + mapDoubleSum(metrics["cpu.work.overcommit"], hostMetrics) { m, v -> m.overcommissionedBurst = v } + mapDoubleSum(metrics["cpu.work.interference"], hostMetrics) { m, v -> m.interferedBurst = v } + mapLongSum(metrics["guests.active"], hostMetrics) { m, v -> m.numberOfDeployedImages = v.toInt() } for ((id, hostMetric) in hostMetrics) { + val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) val host = hosts.getValue(id) monitor.reportHostSlice( clock.millis(), - hostMetric.requestedBurst, - hostMetric.grantedBurst, - hostMetric.overcommissionedBurst, - hostMetric.interferedBurst, + (hostMetric.requestedBurst - lastHostMetric.requestedBurst).toLong(), + (hostMetric.grantedBurst - lastHostMetric.grantedBurst).toLong(), + (hostMetric.overcommissionedBurst - lastHostMetric.overcommissionedBurst).toLong(), + (hostMetric.interferedBurst - lastHostMetric.interferedBurst).toLong(), hostMetric.cpuUsage, hostMetric.cpuDemand, hostMetric.powerDraw, @@ -97,6 +78,8 @@ public class ExperimentMetricExporter( host ) } + + lastHostMetrics = hostMetrics } private fun mapDoubleSummary(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { @@ -137,6 +120,18 @@ public class ExperimentMetricExporter( } } + private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { + val points = data?.doubleSumData?.points ?: emptyList() + for (point in points) { + val uid = point.attributes[hostKey] + val hostMetric = hostMetrics[uid] + + if (hostMetric != null) { + block(hostMetric, point.value) + } + } + } + private fun reportProvisionerMetrics(metrics: Map) { val submittedVms = metrics["servers.submitted"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 val queuedVms = metrics["servers.waiting"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 @@ -159,10 +154,10 @@ public class ExperimentMetricExporter( } private class HostMetrics { - var requestedBurst: Long = 0 - var grantedBurst: Long = 0 - var overcommissionedBurst: Long = 0 - var interferedBurst: Long = 0 + var requestedBurst: Double = 0.0 + var grantedBurst: Double = 0.0 + var overcommissionedBurst: Double = 0.0 + var interferedBurst: Double = 0.0 var cpuUsage: Double = 0.0 var cpuDemand: Double = 0.0 var numberOfDeployedImages: Int = 0 diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt index 68631dee..79af88fe 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt @@ -55,8 +55,7 @@ public interface ExperimentMonitor : AutoCloseable { powerDraw: Double, numberOfDeployedImages: Int, host: Host - ) { - } + ) {} /** * This method is invoked for a provisioner event. diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt index bfdf5f3e..d314c6f5 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt @@ -75,10 +75,10 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: 5 * 60 * 1000L, host, numberOfDeployedImages, - requestedBurst, - grantedBurst, - overcommissionedBurst, - interferedBurst, + requestedBurst.toLong(), + grantedBurst.toLong(), + overcommissionedBurst.toLong(), + interferedBurst.toLong(), cpuUsage, cpuDemand, powerDraw, diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index a3300b71..9b98b329 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -120,9 +120,9 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(219751355711, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(206351165081, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(1148906334, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(220346369672, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(206667809431, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(1151611104, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } @@ -160,9 +160,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(37954956986, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(34840774250, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(971076806, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(38051879542, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(34888186396, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(971668973, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } @@ -204,10 +204,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(37954956986, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(34840774250, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(971076806, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, - { assertEquals(13885404, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } + { assertEquals(38051879542, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(34888186396, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(971668973, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(13910799, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } @@ -256,9 +256,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(25336984869, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(23668547517, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(368151656, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(25412073100, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(23695061847, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(368502468, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } @@ -300,10 +300,10 @@ class CapelinIntegrationTest { numberOfDeployedImages: Int, host: Host, ) { - totalRequestedBurst += requestedBurst - totalGrantedBurst += grantedBurst - totalOvercommissionedBurst += overcommissionedBurst - totalInterferedBurst += interferedBurst + totalRequestedBurst += requestedBurst.toLong() + totalGrantedBurst += grantedBurst.toLong() + totalOvercommissionedBurst += overcommissionedBurst.toLong() + totalInterferedBurst += interferedBurst.toLong() } override fun close() {} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index d8f92155..0873aac9 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -22,8 +22,9 @@ package org.opendc.experiments.tf20.core +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter -import io.opentelemetry.api.metrics.common.Labels import kotlinx.coroutines.* import org.opendc.simulator.compute.SimBareMetalMachine import org.opendc.simulator.compute.SimMachine @@ -67,23 +68,28 @@ public class SimTFDevice( SimplePowerDriver(powerModel) ) + /** + * The identifier of a device. + */ + private val deviceId = AttributeKey.stringKey("device.id") + /** * The usage of the device. */ - private val _usage = meter.doubleValueRecorderBuilder("device.usage") + private val _usage = meter.histogramBuilder("device.usage") .setDescription("The amount of device resources used") .setUnit("MHz") .build() - .bind(Labels.of("device", uid.toString())) + .bind(Attributes.of(deviceId, uid.toString())) /** * The power draw of the device. */ - private val _power = meter.doubleValueRecorderBuilder("device.power") + private val _power = meter.histogramBuilder("device.power") .setDescription("The power draw of the device") .setUnit("W") .build() - .bind(Labels.of("device", uid.toString())) + .bind(Attributes.of(deviceId, uid.toString())) /** * The workload that will be run by the device. diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt index 7c7621b8..a1cb1dbf 100644 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt +++ b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt @@ -22,11 +22,12 @@ package org.opendc.faas.service +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.BoundLongCounter +import io.opentelemetry.api.metrics.BoundLongHistogram import io.opentelemetry.api.metrics.BoundLongUpDownCounter -import io.opentelemetry.api.metrics.BoundLongValueRecorder import io.opentelemetry.api.metrics.Meter -import io.opentelemetry.api.metrics.common.Labels import org.opendc.faas.service.deployer.FunctionInstance import java.util.* @@ -41,77 +42,84 @@ public class FunctionObject( labels: Map, meta: Map ) : AutoCloseable { + /** + * The function identifier attached to the metrics. + */ + private val functionId = AttributeKey.stringKey("function") + /** * The total amount of function invocations received by the function. */ - public val invocations: BoundLongCounter = meter.longCounterBuilder("function.invocations.total") + public val invocations: BoundLongCounter = meter.counterBuilder("function.invocations.total") .setDescription("Number of function invocations") .setUnit("1") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The amount of function invocations that could be handled directly. */ - public val timelyInvocations: BoundLongCounter = meter.longCounterBuilder("function.invocations.warm") + public val timelyInvocations: BoundLongCounter = meter.counterBuilder("function.invocations.warm") .setDescription("Number of function invocations handled directly") .setUnit("1") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The amount of function invocations that were delayed due to function deployment. */ - public val delayedInvocations: BoundLongCounter = meter.longCounterBuilder("function.invocations.cold") + public val delayedInvocations: BoundLongCounter = meter.counterBuilder("function.invocations.cold") .setDescription("Number of function invocations that are delayed") .setUnit("1") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The amount of function invocations that failed. */ - public val failedInvocations: BoundLongCounter = meter.longCounterBuilder("function.invocations.failed") + public val failedInvocations: BoundLongCounter = meter.counterBuilder("function.invocations.failed") .setDescription("Number of function invocations that failed") .setUnit("1") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The amount of instances for this function. */ - public val activeInstances: BoundLongUpDownCounter = meter.longUpDownCounterBuilder("function.instances.active") + public val activeInstances: BoundLongUpDownCounter = meter.upDownCounterBuilder("function.instances.active") .setDescription("Number of active function instances") .setUnit("1") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The amount of idle instances for this function. */ - public val idleInstances: BoundLongUpDownCounter = meter.longUpDownCounterBuilder("function.instances.idle") + public val idleInstances: BoundLongUpDownCounter = meter.upDownCounterBuilder("function.instances.idle") .setDescription("Number of idle function instances") .setUnit("1") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The time that the function waited. */ - public val waitTime: BoundLongValueRecorder = meter.longValueRecorderBuilder("function.time.wait") + public val waitTime: BoundLongHistogram = meter.histogramBuilder("function.time.wait") + .ofLongs() .setDescription("Time the function has to wait before being started") .setUnit("ms") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The time that the function was running. */ - public val activeTime: BoundLongValueRecorder = meter.longValueRecorderBuilder("function.time.active") + public val activeTime: BoundLongHistogram = meter.histogramBuilder("function.time.active") + .ofLongs() .setDescription("Time the function was running") .setUnit("ms") .build() - .bind(Labels.of("function", uid.toString())) + .bind(Attributes.of(functionId, uid.toString())) /** * The instances associated with this function. diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt index b169436f..ccf9a5d9 100644 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt +++ b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt @@ -93,7 +93,7 @@ internal class FaaSServiceImpl( /** * The total amount of function invocations received by the service. */ - private val _invocations = meter.longCounterBuilder("service.invocations.total") + private val _invocations = meter.counterBuilder("service.invocations.total") .setDescription("Number of function invocations") .setUnit("1") .build() @@ -101,7 +101,7 @@ internal class FaaSServiceImpl( /** * The amount of function invocations that could be handled directly. */ - private val _timelyInvocations = meter.longCounterBuilder("service.invocations.warm") + private val _timelyInvocations = meter.counterBuilder("service.invocations.warm") .setDescription("Number of function invocations handled directly") .setUnit("1") .build() @@ -109,7 +109,7 @@ internal class FaaSServiceImpl( /** * The amount of function invocations that were delayed due to function deployment. */ - private val _delayedInvocations = meter.longCounterBuilder("service.invocations.cold") + private val _delayedInvocations = meter.counterBuilder("service.invocations.cold") .setDescription("Number of function invocations that are delayed") .setUnit("1") .build() diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index d287312f..6002270a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -59,6 +59,12 @@ public abstract class SimAbstractHypervisor( override val vms: Set get() = _vms + /** + * The resource counters associated with the hypervisor. + */ + public override val counters: SimResourceCounters + get() = switch.counters + /** * The scaling governors attached to the physical CPUs backing this hypervisor. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt index e398ab36..d3996914 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt @@ -25,6 +25,7 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.SimMachine import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.simulator.resources.SimResourceCounters /** * A SimHypervisor facilitates the execution of multiple concurrent [SimWorkload]s, while acting as a single workload @@ -36,6 +37,11 @@ public interface SimHypervisor : SimWorkload { */ public val vms: Set + /** + * The resource counters associated with the hypervisor. + */ + public val counters: SimResourceCounters + /** * Determine whether the specified machine characterized by [model] can fit on this hypervisor at this moment. */ diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt index d4445810..140f067a 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt @@ -45,10 +45,10 @@ public class WebExperimentMonitor : ExperimentMonitor { override fun reportHostSlice( time: Long, - requestedBurst: Long, - grantedBurst: Long, - overcommissionedBurst: Long, - interferedBurst: Long, + requestedBurst: Double, + grantedBurst: Double, + overcommissionedBurst: Double, + interferedBurst: Double, cpuUsage: Double, cpuDemand: Double, powerDraw: Double, diff --git a/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt b/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt index 32191b8f..5329143d 100644 --- a/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt +++ b/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt @@ -155,7 +155,7 @@ public class WorkflowServiceImpl( /** * The number of jobs that have been submitted to the service. */ - private val submittedJobs = meter.longCounterBuilder("jobs.submitted") + private val submittedJobs = meter.counterBuilder("jobs.submitted") .setDescription("Number of submitted jobs") .setUnit("1") .build() @@ -163,7 +163,7 @@ public class WorkflowServiceImpl( /** * The number of jobs that are running. */ - private val runningJobs = meter.longUpDownCounterBuilder("jobs.active") + private val runningJobs = meter.upDownCounterBuilder("jobs.active") .setDescription("Number of jobs running") .setUnit("1") .build() @@ -171,7 +171,7 @@ public class WorkflowServiceImpl( /** * The number of jobs that have finished running. */ - private val finishedJobs = meter.longCounterBuilder("jobs.finished") + private val finishedJobs = meter.counterBuilder("jobs.finished") .setDescription("Number of jobs that finished running") .setUnit("1") .build() @@ -179,7 +179,7 @@ public class WorkflowServiceImpl( /** * The number of tasks that have been submitted to the service. */ - private val submittedTasks = meter.longCounterBuilder("tasks.submitted") + private val submittedTasks = meter.counterBuilder("tasks.submitted") .setDescription("Number of submitted tasks") .setUnit("1") .build() @@ -187,7 +187,7 @@ public class WorkflowServiceImpl( /** * The number of jobs that are running. */ - private val runningTasks = meter.longUpDownCounterBuilder("tasks.active") + private val runningTasks = meter.upDownCounterBuilder("tasks.active") .setDescription("Number of tasks running") .setUnit("1") .build() @@ -195,7 +195,7 @@ public class WorkflowServiceImpl( /** * The number of jobs that have finished running. */ - private val finishedTasks = meter.longCounterBuilder("tasks.finished") + private val finishedTasks = meter.counterBuilder("tasks.finished") .setDescription("Number of tasks that finished running") .setUnit("1") .build() -- cgit v1.2.3 From e6dd553cf77445083f2c7632bd3b4c3611d76d0a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 18:15:07 +0200 Subject: fix(simulator): Eliminate unnecessary double to long conversions This change eliminates unnecessary double to long conversions in the simulator. Previously, we used longs to denote the amount of work. However, in the mean time we have switched to doubles in the lower stack. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 16 ++++----- .../compute/kernel/SimFairShareHypervisor.kt | 8 ++--- .../simulator/compute/kernel/SimHypervisor.kt | 8 ++--- .../simulator/compute/kernel/SimHypervisorTest.kt | 40 +++++++++++----------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 546584b6..dcc525cb 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -101,17 +101,17 @@ public class SimHost( listener = object : SimHypervisor.Listener { override fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Long, - grantedWork: Long, - overcommittedWork: Long, - interferedWork: Long, + requestedWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) { - _totalWork.add(requestedWork.toDouble()) - _grantedWork.add(grantedWork.toDouble()) - _overcommittedWork.add(overcommittedWork.toDouble()) - _interferedWork.add(interferedWork.toDouble()) + _totalWork.add(requestedWork) + _grantedWork.add(grantedWork) + _overcommittedWork.add(overcommittedWork) + _interferedWork.add(interferedWork) _cpuDemand.record(cpuDemand) _cpuUsage.record(cpuUsage) _powerUsage.record(machine.psu.powerDraw) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index c31b1f6b..3b44292d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -77,10 +77,10 @@ public class SimFairShareHypervisor( if (timestamp > lastReport) { listener.onSliceFinish( this@SimFairShareHypervisor, - (counters.demand - lastDemand).toLong(), - (counters.actual - lastActual).toLong(), - (counters.overcommit - lastOvercommit).toLong(), - (counters.interference - lastInterference).toLong(), + counters.demand - lastDemand, + counters.actual - lastActual, + counters.overcommit - lastOvercommit, + counters.interference - lastInterference, lastCpuUsage, lastCpuDemand ) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt index d3996914..af28c346 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt @@ -64,10 +64,10 @@ public interface SimHypervisor : SimWorkload { */ public fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Long, - grantedWork: Long, - overcommittedWork: Long, - interferedWork: Long, + requestedWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index afc4c949..918271d1 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -68,16 +68,16 @@ internal class SimHypervisorTest { @Test fun testOvercommittedSingle() = runBlockingSimulation { val listener = object : SimHypervisor.Listener { - var totalRequestedWork = 0L - var totalGrantedWork = 0L - var totalOvercommittedWork = 0L + var totalRequestedWork = 0.0 + var totalGrantedWork = 0.0 + var totalOvercommittedWork = 0.0 override fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Long, - grantedWork: Long, - overcommittedWork: Long, - interferedWork: Long, + requestedWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) { @@ -117,9 +117,9 @@ internal class SimHypervisorTest { machine.close() assertAll( - { assertEquals(1113300, listener.totalRequestedWork, "Requested Burst does not match") }, - { assertEquals(1023300, listener.totalGrantedWork, "Granted Burst does not match") }, - { assertEquals(90000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, + { assertEquals(1113300.0, listener.totalRequestedWork, "Requested Burst does not match") }, + { assertEquals(1023300.0, listener.totalGrantedWork, "Granted Burst does not match") }, + { assertEquals(90000.0, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), res) { "VM usage is correct" } }, { assertEquals(1200000, clock.millis()) { "Current time is correct" } } ) @@ -131,16 +131,16 @@ internal class SimHypervisorTest { @Test fun testOvercommittedDual() = runBlockingSimulation { val listener = object : SimHypervisor.Listener { - var totalRequestedWork = 0L - var totalGrantedWork = 0L - var totalOvercommittedWork = 0L + var totalRequestedWork = 0.0 + var totalGrantedWork = 0.0 + var totalOvercommittedWork = 0.0 override fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Long, - grantedWork: Long, - overcommittedWork: Long, - interferedWork: Long, + requestedWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) { @@ -196,9 +196,9 @@ internal class SimHypervisorTest { yield() assertAll( - { assertEquals(2073600, listener.totalRequestedWork, "Requested Burst does not match") }, - { assertEquals(1053600, listener.totalGrantedWork, "Granted Burst does not match") }, - { assertEquals(1020000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, + { assertEquals(2073600.0, listener.totalRequestedWork, "Requested Burst does not match") }, + { assertEquals(1053600.0, listener.totalGrantedWork, "Granted Burst does not match") }, + { assertEquals(1020000.0, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, { assertEquals(1200000, clock.millis()) } ) } -- cgit v1.2.3 From bb6066e1cecc55a50ac29da200bf3beba1ddd80b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 18:16:20 +0200 Subject: fix(capelin): Eliminate unnecessary double to long conversions This change eliminates the unnecessary conversions from double to long in the Capelin metric processing code. --- .../capelin/monitor/ExperimentMetricExporter.kt | 12 ++--- .../capelin/monitor/ExperimentMonitor.kt | 16 +++--- .../capelin/monitor/ParquetExperimentMonitor.kt | 24 ++++----- .../experiments/capelin/CapelinIntegrationTest.kt | 60 +++++++++++----------- .../org/opendc/web/runner/WebExperimentMonitor.kt | 24 ++++----- 5 files changed, 68 insertions(+), 68 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index 16358817..be94593c 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -65,12 +65,12 @@ public class ExperimentMetricExporter( for ((id, hostMetric) in hostMetrics) { val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) val host = hosts.getValue(id) - monitor.reportHostSlice( + monitor.reportHostData( clock.millis(), - (hostMetric.requestedBurst - lastHostMetric.requestedBurst).toLong(), - (hostMetric.grantedBurst - lastHostMetric.grantedBurst).toLong(), - (hostMetric.overcommissionedBurst - lastHostMetric.overcommissionedBurst).toLong(), - (hostMetric.interferedBurst - lastHostMetric.interferedBurst).toLong(), + hostMetric.requestedBurst - lastHostMetric.requestedBurst, + hostMetric.grantedBurst - lastHostMetric.grantedBurst, + hostMetric.overcommissionedBurst - lastHostMetric.overcommissionedBurst, + hostMetric.interferedBurst - lastHostMetric.interferedBurst, hostMetric.cpuUsage, hostMetric.cpuDemand, hostMetric.powerDraw, @@ -141,7 +141,7 @@ public class ExperimentMetricExporter( val hosts = metrics["hosts.total"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 val availableHosts = metrics["hosts.available"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - monitor.reportProvisionerMetrics( + monitor.reportServiceData( clock.millis(), hosts, availableHosts, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt index 79af88fe..9a4aec35 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt @@ -44,23 +44,23 @@ public interface ExperimentMonitor : AutoCloseable { /** * This method is invoked for a host for each slice that is finishes. */ - public fun reportHostSlice( + public fun reportHostData( time: Long, - requestedBurst: Long, - grantedBurst: Long, - overcommissionedBurst: Long, - interferedBurst: Long, + totalWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double, powerDraw: Double, - numberOfDeployedImages: Int, + instanceCount: Int, host: Host ) {} /** - * This method is invoked for a provisioner event. + * This method is invoked for reporting service data. */ - public fun reportProvisionerMetrics( + public fun reportServiceData( time: Long, totalHostCount: Int, availableHostCount: Int, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt index d314c6f5..83351c41 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt @@ -57,16 +57,16 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: logger.debug { "Host ${host.uid} changed state $newState [$time]" } } - override fun reportHostSlice( + override fun reportHostData( time: Long, - requestedBurst: Long, - grantedBurst: Long, - overcommissionedBurst: Long, - interferedBurst: Long, + totalWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double, powerDraw: Double, - numberOfDeployedImages: Int, + instanceCount: Int, host: Host ) { hostWriter.write( @@ -74,11 +74,11 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: time, 5 * 60 * 1000L, host, - numberOfDeployedImages, - requestedBurst.toLong(), - grantedBurst.toLong(), - overcommissionedBurst.toLong(), - interferedBurst.toLong(), + instanceCount, + totalWork.toLong(), + grantedWork.toLong(), + overcommittedWork.toLong(), + interferedWork.toLong(), cpuUsage, cpuDemand, powerDraw, @@ -87,7 +87,7 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: ) } - override fun reportProvisionerMetrics( + override fun reportServiceData( time: Long, totalHostCount: Int, availableHostCount: Int, diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 9b98b329..8008c944 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -120,10 +120,10 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(220346369672, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(206667809431, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(1151611104, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, - { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } + { assertEquals(220346369753, monitor.totalWork) { "Incorrect requested burst" } }, + { assertEquals(206667809529, monitor.totalGrantedWork) { "Incorrect granted burst" } }, + { assertEquals(1151611104, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, + { assertEquals(0, monitor.totalInterferedWork) { "Incorrect interfered burst" } } ) } @@ -160,10 +160,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(38051879542, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(34888186396, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(971668973, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, - { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } + { assertEquals(38051879552, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(34888186408, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(971668973, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -204,10 +204,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(38051879542, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(34888186396, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(971668973, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, - { assertEquals(13910799, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } + { assertEquals(38051879552, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(34888186408, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(971668973, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(13910814, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -256,10 +256,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(25412073100, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(23695061847, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(368502468, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, - { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } + { assertEquals(25412073109, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(23695061858, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(368502468, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -283,27 +283,27 @@ class CapelinIntegrationTest { } class TestExperimentReporter : ExperimentMonitor { - var totalRequestedBurst = 0L - var totalGrantedBurst = 0L - var totalOvercommissionedBurst = 0L - var totalInterferedBurst = 0L + var totalWork = 0L + var totalGrantedWork = 0L + var totalOvercommittedWork = 0L + var totalInterferedWork = 0L - override fun reportHostSlice( + override fun reportHostData( time: Long, - requestedBurst: Long, - grantedBurst: Long, - overcommissionedBurst: Long, - interferedBurst: Long, + totalWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double, powerDraw: Double, - numberOfDeployedImages: Int, + instanceCount: Int, host: Host, ) { - totalRequestedBurst += requestedBurst.toLong() - totalGrantedBurst += grantedBurst.toLong() - totalOvercommissionedBurst += overcommissionedBurst.toLong() - totalInterferedBurst += interferedBurst.toLong() + this.totalWork += totalWork.toLong() + totalGrantedWork += grantedWork.toLong() + totalOvercommittedWork += overcommittedWork.toLong() + totalInterferedWork += interferedWork.toLong() } override fun close() {} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt index 140f067a..82e2a334 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt @@ -43,16 +43,16 @@ public class WebExperimentMonitor : ExperimentMonitor { logger.debug { "Host ${host.uid} changed state $newState [$time]" } } - override fun reportHostSlice( + override fun reportHostData( time: Long, - requestedBurst: Double, - grantedBurst: Double, - overcommissionedBurst: Double, - interferedBurst: Double, + totalWork: Double, + grantedWork: Double, + overcommittedWork: Double, + interferedWork: Double, cpuUsage: Double, cpuDemand: Double, powerDraw: Double, - numberOfDeployedImages: Int, + instanceCount: Int, host: Host, ) { processHostEvent( @@ -60,11 +60,11 @@ public class WebExperimentMonitor : ExperimentMonitor { time, 5 * 60 * 1000L, host, - numberOfDeployedImages, - requestedBurst, - grantedBurst, - overcommissionedBurst, - interferedBurst, + instanceCount, + totalWork.toLong(), + grantedWork.toLong(), + overcommittedWork.toLong(), + interferedWork.toLong(), cpuUsage, cpuDemand, powerDraw, @@ -120,7 +120,7 @@ public class WebExperimentMonitor : ExperimentMonitor { private var provisionerMetrics: AggregateProvisionerMetrics = AggregateProvisionerMetrics() - override fun reportProvisionerMetrics( + override fun reportServiceData( time: Long, totalHostCount: Int, availableHostCount: Int, -- cgit v1.2.3 From e5b79b18dab4f2874f3c5730b7e599dc74573c8d Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 18:24:55 +0200 Subject: refactor(capelin): Simplify metric extraction for monitor This change updates the metric exporter logic in the Capelin module and reduces the number of allocations by looping directly over the collection of metrics. --- .../experiments/capelin/ExperimentHelpers.kt | 38 ++++++--- .../capelin/monitor/ExperimentMetricExporter.kt | 91 +++++++++++----------- 2 files changed, 74 insertions(+), 55 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 4cffb8d3..7f428b2a 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -24,6 +24,7 @@ package org.opendc.experiments.capelin import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider +import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel @@ -208,24 +209,41 @@ class ComputeMetrics { var runningVms: Int = 0 var unscheduledVms: Int = 0 var finishedVms: Int = 0 + var hosts: Int = 0 + var availableHosts = 0 } /** * Collect the metrics of the compute service. */ fun collectMetrics(metricProducer: MetricProducer): ComputeMetrics { - val metrics = metricProducer.collectAllMetrics().associateBy { it.name } + return extractComputeMetrics(metricProducer.collectAllMetrics()) +} + +/** + * Extract an [ComputeMetrics] object from the specified list of metric data. + */ +internal fun extractComputeMetrics(metrics: Collection): ComputeMetrics { val res = ComputeMetrics() - try { - // Hack to extract metrics from OpenTelemetry SDK - res.submittedVms = metrics["servers.submitted"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - res.queuedVms = metrics["servers.waiting"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - res.unscheduledVms = metrics["servers.unscheduled"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - res.runningVms = metrics["servers.active"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - res.finishedVms = metrics["servers.finished"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - } catch (cause: Throwable) { - logger.warn(cause) { "Failed to collect metrics" } + for (metric in metrics) { + val points = metric.longSumData.points + + if (points.isEmpty()) { + continue + } + + val value = points.first().value.toInt() + when (metric.name) { + "servers.submitted" -> res.submittedVms = value + "servers.waiting" -> res.queuedVms = value + "servers.unscheduled" -> res.unscheduledVms = value + "servers.active" -> res.runningVms = value + "servers.finished" -> res.finishedVms = value + "hosts.total" -> res.hosts = value + "hosts.available" -> res.availableHosts = value + } } + return res } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index be94593c..e9c817de 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -27,6 +27,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import org.opendc.compute.service.driver.Host +import org.opendc.experiments.capelin.extractComputeMetrics import java.time.Clock /** @@ -37,44 +38,50 @@ public class ExperimentMetricExporter( private val clock: Clock, private val hosts: Map ) : MetricExporter { - private val hostKey = ResourceAttributes.HOST_ID override fun export(metrics: Collection): CompletableResultCode { - val metricsByName = metrics.associateBy { it.name } - reportHostMetrics(metricsByName) - reportProvisionerMetrics(metricsByName) - return CompletableResultCode.ofSuccess() + return try { + reportHostMetrics(metrics) + reportProvisionerMetrics(metrics) + CompletableResultCode.ofSuccess() + } catch (e: Throwable) { + CompletableResultCode.ofFailure() + } } private var lastHostMetrics: Map = emptyMap() private val hostMetricsSingleton = HostMetrics() - private fun reportHostMetrics(metrics: Map) { + private fun reportHostMetrics(metrics: Collection) { val hostMetrics = mutableMapOf() hosts.mapValuesTo(hostMetrics) { HostMetrics() } - mapDoubleSummary(metrics["cpu.demand"], hostMetrics) { m, v -> m.cpuDemand = v } - mapDoubleSummary(metrics["cpu.usage"], hostMetrics) { m, v -> m.cpuUsage = v } - mapDoubleGauge(metrics["power.usage"], hostMetrics) { m, v -> m.powerDraw = v } - mapDoubleSum(metrics["cpu.work.total"], hostMetrics) { m, v -> m.requestedBurst = v } - mapDoubleSum(metrics["cpu.work.granted"], hostMetrics) { m, v -> m.grantedBurst = v } - mapDoubleSum(metrics["cpu.work.overcommit"], hostMetrics) { m, v -> m.overcommissionedBurst = v } - mapDoubleSum(metrics["cpu.work.interference"], hostMetrics) { m, v -> m.interferedBurst = v } - mapLongSum(metrics["guests.active"], hostMetrics) { m, v -> m.numberOfDeployedImages = v.toInt() } + for (metric in metrics) { + when (metric.name) { + "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v } + "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v } + "power.usage" -> mapDoubleGauge(metric, hostMetrics) { m, v -> m.powerDraw = v } + "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v } + "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v } + "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } + "cpu.work.interference" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.interferedWork = v } + "guests.active" -> mapLongSum(metric, hostMetrics) { m, v -> m.instanceCount = v.toInt() } + } + } for ((id, hostMetric) in hostMetrics) { val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) val host = hosts.getValue(id) monitor.reportHostData( clock.millis(), - hostMetric.requestedBurst - lastHostMetric.requestedBurst, - hostMetric.grantedBurst - lastHostMetric.grantedBurst, - hostMetric.overcommissionedBurst - lastHostMetric.overcommissionedBurst, - hostMetric.interferedBurst - lastHostMetric.interferedBurst, + hostMetric.totalWork - lastHostMetric.totalWork, + hostMetric.grantedWork - lastHostMetric.grantedWork, + hostMetric.overcommittedWork - lastHostMetric.overcommittedWork, + hostMetric.interferedWork - lastHostMetric.interferedWork, hostMetric.cpuUsage, hostMetric.cpuDemand, hostMetric.powerDraw, - hostMetric.numberOfDeployedImages, + hostMetric.instanceCount, host ) } @@ -82,10 +89,10 @@ public class ExperimentMetricExporter( lastHostMetrics = hostMetrics } - private fun mapDoubleSummary(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { - val points = data?.doubleSummaryData?.points ?: emptyList() + private fun mapDoubleSummary(data: MetricData, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { + val points = data.doubleSummaryData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[hostKey] + val uid = point.attributes[ResourceAttributes.HOST_ID] val hostMetric = hostMetrics[uid] if (hostMetric != null) { @@ -99,7 +106,7 @@ public class ExperimentMetricExporter( private fun mapDoubleGauge(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { val points = data?.doubleGaugeData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[hostKey] + val uid = point.attributes[ResourceAttributes.HOST_ID] val hostMetric = hostMetrics[uid] if (hostMetric != null) { @@ -111,7 +118,7 @@ public class ExperimentMetricExporter( private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Long) -> Unit) { val points = data?.longSumData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[hostKey] + val uid = point.attributes[ResourceAttributes.HOST_ID] val hostMetric = hostMetrics[uid] if (hostMetric != null) { @@ -123,7 +130,7 @@ public class ExperimentMetricExporter( private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { val points = data?.doubleSumData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[hostKey] + val uid = point.attributes[ResourceAttributes.HOST_ID] val hostMetric = hostMetrics[uid] if (hostMetric != null) { @@ -132,35 +139,29 @@ public class ExperimentMetricExporter( } } - private fun reportProvisionerMetrics(metrics: Map) { - val submittedVms = metrics["servers.submitted"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - val queuedVms = metrics["servers.waiting"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - val unscheduledVms = metrics["servers.unscheduled"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - val runningVms = metrics["servers.active"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - val finishedVms = metrics["servers.finished"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - val hosts = metrics["hosts.total"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 - val availableHosts = metrics["hosts.available"]?.longSumData?.points?.last()?.value?.toInt() ?: 0 + private fun reportProvisionerMetrics(metrics: Collection) { + val res = extractComputeMetrics(metrics) monitor.reportServiceData( clock.millis(), - hosts, - availableHosts, - submittedVms, - runningVms, - finishedVms, - queuedVms, - unscheduledVms + res.hosts, + res.availableHosts, + res.submittedVms, + res.runningVms, + res.finishedVms, + res.queuedVms, + res.unscheduledVms ) } private class HostMetrics { - var requestedBurst: Double = 0.0 - var grantedBurst: Double = 0.0 - var overcommissionedBurst: Double = 0.0 - var interferedBurst: Double = 0.0 + var totalWork: Double = 0.0 + var grantedWork: Double = 0.0 + var overcommittedWork: Double = 0.0 + var interferedWork: Double = 0.0 var cpuUsage: Double = 0.0 var cpuDemand: Double = 0.0 - var numberOfDeployedImages: Int = 0 + var instanceCount: Int = 0 var powerDraw: Double = 0.0 } -- cgit v1.2.3 From 8f58ae2b28518c6a2ed2fe3657984f417b3d3ddb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 20:35:01 +0200 Subject: refactor(simulator): Remove usage and speed fields from SimMachine This change removes the usage and speed fields from SimMachine. We currently use other ways to capture the usage and speed and these fields cause an additional maintenance burden and performance impact. Hence the removal of these fields. --- .../opendc/simulator/compute/SimAbstractMachine.kt | 40 --------------------- .../simulator/compute/SimBareMetalMachine.kt | 12 ++++--- .../org/opendc/simulator/compute/SimMachine.kt | 6 ---- .../compute/kernel/SimAbstractHypervisor.kt | 2 ++ .../simulator/compute/power/SimplePowerDriver.kt | 11 +++++- .../org/opendc/simulator/compute/SimMachineTest.kt | 41 ---------------------- .../simulator/compute/kernel/SimHypervisorTest.kt | 11 +----- .../compute/kernel/SimSpaceSharedHypervisorTest.kt | 18 +--------- 8 files changed, 22 insertions(+), 119 deletions(-) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index f416643e..266db0dd 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -23,8 +23,6 @@ package org.opendc.simulator.compute import kotlinx.coroutines.* -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import org.opendc.simulator.compute.device.SimNetworkAdapter import org.opendc.simulator.compute.device.SimPeripheral import org.opendc.simulator.compute.model.MachineModel @@ -48,20 +46,6 @@ public abstract class SimAbstractMachine( final override val parent: SimResourceSystem?, final override val model: MachineModel ) : SimMachine, SimResourceSystem { - /** - * A [StateFlow] representing the CPU usage of the simulated machine. - */ - private val _usage = MutableStateFlow(0.0) - public final override val usage: StateFlow - get() = _usage - - /** - * The speed of the CPU cores. - */ - public val speed: DoubleArray - get() = _speed - private var _speed = doubleArrayOf() - /** * The resources allocated for this machine. */ @@ -106,10 +90,6 @@ public abstract class SimAbstractMachine( val ctx = Context(meta) - // Before the workload starts, initialize the initial power draw - _speed = DoubleArray(model.cpus.size) { 0.0 } - updateUsage(0.0) - return suspendCancellableCoroutine { cont -> this.cont = cont @@ -136,26 +116,6 @@ public abstract class SimAbstractMachine( cancel() } - /* SimResourceSystem */ - override fun onConverge(timestamp: Long) { - val totalCapacity = model.cpus.sumOf { it.frequency } - val cpus = cpus - var totalSpeed = 0.0 - for (cpu in cpus) { - _speed[cpu.model.id] = cpu.speed - totalSpeed += cpu.speed - } - - updateUsage(totalSpeed / totalCapacity) - } - - /** - * This method is invoked when the usage of the machine is updated. - */ - protected open fun updateUsage(usage: Double) { - _usage.value = usage - } - /** * Cancel the workload that is currently running on the machine. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt index 887f0885..2c711945 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt @@ -32,7 +32,7 @@ import org.opendc.simulator.resources.SimResourceInterpreter /** * A simulated bare-metal machine that is able to run a single workload. * - * A [SimBareMetalMachine] is a stateful object and you should be careful when operating this object concurrently. For + * A [SimBareMetalMachine] is a stateful object, and you should be careful when operating this object concurrently. For * example, the class expects only a single concurrent call to [run]. * * @param interpreter The [SimResourceInterpreter] to drive the simulation. @@ -55,13 +55,17 @@ public class SimBareMetalMachine( Cpu(SimResourceSource(cpu.frequency, interpreter, this@SimBareMetalMachine), cpu) } - override fun updateUsage(usage: Double) { - super.updateUsage(usage) + /** + * The logic of the power driver. + */ + private val powerDriverLogic = powerDriver.createLogic(this, cpus) + + override fun onConverge(timestamp: Long) { psu.update() } init { - psu.connect(powerDriver.createLogic(this, cpus)) + psu.connect(powerDriverLogic) } /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt index 0f4674d5..d8dd8205 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.compute -import kotlinx.coroutines.flow.StateFlow import org.opendc.simulator.compute.device.SimPeripheral import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload @@ -41,11 +40,6 @@ public interface SimMachine : AutoCloseable { */ public val peripherals: List - /** - * A [StateFlow] representing the CPU usage of the simulated machine. - */ - public val usage: StateFlow - /** * Run the specified [SimWorkload] on this machine and suspend execution util the workload has finished. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index 6002270a..98271fb0 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -145,6 +145,8 @@ public abstract class SimAbstractHypervisor( interferenceDomain?.leave(interferenceKey) } } + + override fun onConverge(timestamp: Long) {} } /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt index e43c89ac..bf7aeff1 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt @@ -30,8 +30,17 @@ import org.opendc.simulator.compute.SimProcessingUnit */ public class SimplePowerDriver(private val model: PowerModel) : PowerDriver { override fun createLogic(machine: SimMachine, cpus: List): PowerDriver.Logic = object : PowerDriver.Logic { + override fun computePower(): Double { - return model.computePower(machine.usage.value) + var targetFreq = 0.0 + var totalSpeed = 0.0 + + for (cpu in cpus) { + targetFreq += cpu.capacity + totalSpeed += cpu.speed + } + + return model.computePower(totalSpeed / targetFreq) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt index 19808a77..81268879 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt @@ -23,9 +23,7 @@ package org.opendc.simulator.compute import kotlinx.coroutines.* -import kotlinx.coroutines.flow.toList import org.junit.jupiter.api.* -import org.junit.jupiter.api.Assertions.assertArrayEquals import org.junit.jupiter.api.Assertions.assertEquals import org.opendc.simulator.compute.device.SimNetworkAdapter import org.opendc.simulator.compute.model.* @@ -100,45 +98,6 @@ class SimMachineTest { } } - @Test - fun testUsage() = runBlockingSimulation { - val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), - machineModel, - SimplePowerDriver(ConstantPowerModel(0.0)) - ) - - val res = mutableListOf() - val job = launch { machine.usage.toList(res) } - - try { - machine.run(SimFlopsWorkload(2_000, utilization = 1.0)) - yield() - job.cancel() - assertEquals(listOf(0.0, 1.0, 0.0), res) { "Machine is fully utilized" } - } finally { - machine.close() - } - } - - @Test - fun testSpeed() = runBlockingSimulation { - val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), - machineModel, - SimplePowerDriver(ConstantPowerModel(0.0)) - ) - - try { - coroutineScope { - launch { machine.run(SimFlopsWorkload(2_000, utilization = 1.0)) } - assertArrayEquals(doubleArrayOf(1000.0, 1000.0), machine.speed) - } - } finally { - machine.close() - } - } - @Test fun testPower() = runBlockingSimulation { val interpreter = SimResourceInterpreter(coroutineContext, clock) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index 918271d1..8dea0045 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -22,11 +22,7 @@ package org.opendc.simulator.compute.kernel -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.yield +import kotlinx.coroutines.* import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -108,19 +104,14 @@ internal class SimHypervisorTest { } yield() val vm = hypervisor.createMachine(model) - val res = mutableListOf() - val job = launch { machine.usage.toList(res) } - vm.run(workloadA) yield() - job.cancel() machine.close() assertAll( { assertEquals(1113300.0, listener.totalRequestedWork, "Requested Burst does not match") }, { assertEquals(1023300.0, listener.totalGrantedWork, "Granted Burst does not match") }, { assertEquals(90000.0, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, - { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), res) { "VM usage is correct" } }, { assertEquals(1200000, clock.millis()) { "Current time is correct" } } ) } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index 80496992..3d3feb2a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.compute.kernel import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.* @@ -64,9 +63,6 @@ internal class SimSpaceSharedHypervisorTest { */ @Test fun testTrace() = runBlockingSimulation { - val usagePm = mutableListOf() - val usageVm = mutableListOf() - val duration = 5 * 60L val workloadA = SimTraceWorkload( @@ -84,27 +80,15 @@ internal class SimSpaceSharedHypervisorTest { ) val hypervisor = SimSpaceSharedHypervisor(interpreter) - val colA = launch { machine.usage.toList(usagePm) } launch { machine.run(hypervisor) } - - yield() - val vm = hypervisor.createMachine(machineModel) - val colB = launch { vm.usage.toList(usageVm) } vm.run(workloadA) yield() vm.close() machine.close() - colA.cancel() - colB.cancel() - assertAll( - { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), usagePm) { "Correct PM usage" } }, - // Temporary limitation is that VMs do not emit usage information - // { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), usageVm) { "Correct VM usage" } }, - { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } - ) + assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } /** -- cgit v1.2.3 From b0f6402f60ddbba1aad7e198fe6757792337f4d4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 20:46:36 +0200 Subject: refactor(compute): Measure power draw without PSU overhead This change updates the SimHost implementation to measure the power draw of the machine without PSU overhead to make the results more realistic. --- .../main/kotlin/org/opendc/compute/simulator/SimHost.kt | 2 +- .../capelin/monitor/ExperimentMetricExporter.kt | 14 +------------- .../opendc/experiments/capelin/CapelinIntegrationTest.kt | 5 ++++- .../org/opendc/simulator/compute/SimBareMetalMachine.kt | 6 ++++++ 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index dcc525cb..20e5a9db 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -114,7 +114,7 @@ public class SimHost( _interferedWork.add(interferedWork) _cpuDemand.record(cpuDemand) _cpuUsage.record(cpuUsage) - _powerUsage.record(machine.psu.powerDraw) + _powerUsage.record(machine.powerDraw) } } ) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index e9c817de..42b7cbb8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -60,7 +60,7 @@ public class ExperimentMetricExporter( when (metric.name) { "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v } "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v } - "power.usage" -> mapDoubleGauge(metric, hostMetrics) { m, v -> m.powerDraw = v } + "power.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.powerDraw = v } "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v } "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v } "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } @@ -103,18 +103,6 @@ public class ExperimentMetricExporter( } } - private fun mapDoubleGauge(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { - val points = data?.doubleGaugeData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] - val hostMetric = hostMetrics[uid] - - if (hostMetric != null) { - block(hostMetric, point.value) - } - } - } - private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Long) -> Unit) { val points = data?.longSumData?.points ?: emptyList() for (point in points) { diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 8008c944..e4d3fed3 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -123,7 +123,8 @@ class CapelinIntegrationTest { { assertEquals(220346369753, monitor.totalWork) { "Incorrect requested burst" } }, { assertEquals(206667809529, monitor.totalGrantedWork) { "Incorrect granted burst" } }, { assertEquals(1151611104, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, - { assertEquals(0, monitor.totalInterferedWork) { "Incorrect interfered burst" } } + { assertEquals(0, monitor.totalInterferedWork) { "Incorrect interfered burst" } }, + { assertEquals(1.7671768767192196E7, monitor.totalPowerDraw, 0.01) { "Incorrect power draw" } }, ) } @@ -287,6 +288,7 @@ class CapelinIntegrationTest { var totalGrantedWork = 0L var totalOvercommittedWork = 0L var totalInterferedWork = 0L + var totalPowerDraw = 0.0 override fun reportHostData( time: Long, @@ -304,6 +306,7 @@ class CapelinIntegrationTest { totalGrantedWork += grantedWork.toLong() totalOvercommittedWork += overcommittedWork.toLong() totalInterferedWork += interferedWork.toLong() + totalPowerDraw += powerDraw } override fun close() {} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt index 2c711945..639ca450 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt @@ -48,6 +48,12 @@ public class SimBareMetalMachine( public val psu: SimPsu = SimPsu(500.0, mapOf(1.0 to 1.0)), parent: SimResourceSystem? = null, ) : SimAbstractMachine(interpreter, parent, model) { + /** + * The power draw of the machine onto the PSU. + */ + public val powerDraw: Double + get() = powerDriverLogic.computePower() + /** * The processing units of the machine. */ -- cgit v1.2.3 From 26d366ede8be1884faa5b591eabb369ed1031b27 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 11:17:28 +0200 Subject: build: Update to Kotlin 1.5.30 --- buildSrc/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6ada3535..a5e99bfa 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -31,9 +31,9 @@ repositories { } dependencies { - implementation(kotlin("gradle-plugin", version = "1.5.21")) + implementation(kotlin("gradle-plugin", version = "1.5.30")) implementation("org.jlleitschuh.gradle:ktlint-gradle:10.1.0") - implementation("org.jetbrains.kotlin:kotlin-allopen:1.5.21") + implementation("org.jetbrains.kotlin:kotlin-allopen:1.5.30") implementation("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.3.1") implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.5.0") implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:7.0.0") -- cgit v1.2.3 From 5e4d8e65159384d33cd411b1985bc950b342977e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 11:17:42 +0200 Subject: build: Update dependencies to latest version --- gradle/libs.versions.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4f2ec58c..fd737393 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,15 +6,15 @@ log4j = "2.14.1" opentelemetry-main = "1.5.0" opentelemetry-metrics = "1.5.0-alpha" opentelemetry-semconv = "1.5.0-alpha" -hadoop = "3.3.0" -ktor = "1.6.2" -jackson = "2.12.4" +hadoop = "3.3.1" +ktor = "1.6.3" +jackson = "2.12.5" [libraries] kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.5.1" } # Logging -kotlin-logging = { module = "io.github.microutils:kotlin-logging", version = "2.0.10" } +kotlin-logging = { module = "io.github.microutils:kotlin-logging", version = "2.0.11" } slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } log4j-slf4j = { module = "org.apache.logging.log4j:log4j-slf4j-impl", version.ref = "log4j" } sentry-log4j2 = { module = "io.sentry:sentry-log4j2", version = "4.3.0" } @@ -51,7 +51,7 @@ config = { module = "com.typesafe:config", version = "1.4.1" } kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime-jvm", version = "0.3.1" } # Other -classgraph = { module = "io.github.classgraph:classgraph", version = "4.8.113" } +classgraph = { module = "io.github.classgraph:classgraph", version = "4.8.115" } hadoop-common = { module = "org.apache.hadoop:hadoop-common", version.ref = "hadoop" } hadoop-mapreduce-client-core = { module = "org.apache.hadoop:hadoop-mapreduce-client-core", version.ref = "hadoop" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } -- cgit v1.2.3 From 99f391d11db57c3db3f326958de8f66502969cdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Sep 2021 22:32:14 +0200 Subject: build(ui): Bump Next.js from 11.1.0 to 11.1.1 Bumps [next](https://github.com/vercel/next.js) from 11.1.0 to 11.1.1. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v11.1.0...v11.1.1) --- updated-dependencies: - dependency-name: next dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- opendc-web/opendc-web-ui/package.json | 2 +- opendc-web/opendc-web-ui/yarn.lock | 100 ++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 42 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 3f8d31fa..f7d671b2 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -34,7 +34,7 @@ "konva": "~7.2.5", "lint-staged": "~10.2.2", "mathjs": "~7.6.0", - "next": "^11.1.0", + "next": "^11.1.1", "next-transpile-modules": "^8.0.0", "normalizr": "^3.6.1", "prettier": "~2.0.5", diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 0573e612..f6c3d031 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -67,17 +67,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/runtime@7.12.5": - version "7.12.5" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz" - integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.9.2": - version "7.14.6" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz" - integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== +"@babel/runtime@7.15.3", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.9.2": + version "7.15.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b" + integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA== dependencies: regenerator-runtime "^0.13.4" @@ -162,25 +155,25 @@ resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c" integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA== -"@next/env@11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.0.tgz#cae83d8e0a65aa9f2af3368f8269ffd9d911746a" - integrity sha512-zPJkMFRenSf7BLlVee8987G0qQXAhxy7k+Lb/5hLAGkPVHAHm+oFFeL+2ipbI2KTEFlazdmGY0M+AlLQn7pWaw== +"@next/env@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.1.tgz#d403282accbe8795aa2341f0e02c2e8bfc92bfb0" + integrity sha512-UEAzlfKofotLmj9LIgNixAfXpRck9rt/1CU9Q4ZtNDueGBJQP3HUzPHlrLChltWY2TA5MOzDQGL82H0a3+i5Ag== "@next/eslint-plugin-next@10.2.3": version "10.2.3" resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-10.2.3.tgz" integrity sha512-XkYm3cMxY2RZgbGyZLDN3vR9StFyiQVdwdS/EL6NxOerzt0To03/coY22p4jcFLtLYlQxAivJRicMTDNhRzPog== -"@next/polyfill-module@11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.0.tgz#ee6b9117a1f9bb137479dfa51d5a9e38e066a62f" - integrity sha512-64EgW8SzJRQls2yJ5DkuljRxgE24o2kYtX/ghTkPUJYsfidHMWzQGwg26IgRbb/uHqTd1G0W5UkKag+Nt8TWaQ== +"@next/polyfill-module@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.1.tgz#89d5a70685a52a0fad79f05a1f97a6b15cc727aa" + integrity sha512-9FyVSnz00WGdlLsgc2w1xL1Lm/Q25y6FYIyA+1WlJvT6LA2lbR78GKiHgedzUvrAatVGAcg/Og+d0d7B4tsJOg== -"@next/react-dev-overlay@11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.0.tgz#8d4e8020a4cbdacbca431a0bf40c4d28187083af" - integrity sha512-h+ry0sTk1W3mJw+TwEf91aqLbBJ5oqAsxfx+QryqEItNtfW6zLSSjxkyTYTqX8DkgSssQQutQfATkzBVgOR+qQ== +"@next/react-dev-overlay@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.1.tgz#3cd99202a85412bada8ba9c8e3f4cf7c19294b24" + integrity sha512-CXc/A0DbSk5VXYu4+zr0fHm52Zh/LhPlLyVPEctJOZL64ccxkls5xGoXvgolJCku9L0pLjJzvdfAmhNLOp5dyw== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -194,10 +187,30 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.0.tgz#60c3c7b127a5dab8b0a2889a7dcf8a90d2c4e592" - integrity sha512-g5DtFTpLTGa36iy9DuZawtJeitI11gysFGKPQQqy+mNbSFazguArcJ10gAYFlbqpIi4boUamWNI5mAoSPx3kog== +"@next/react-refresh-utils@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.1.tgz#8d1a5432a53c9f987503d5ab07d3241230afb33f" + integrity sha512-j186y+lWc8BHAuysAWvlOqO9Bp7E3BLK/d/Ju3W2sP5BCH5ZLyLG/p308zSy/O0MGTag0B038ZA1dCy/msouRQ== + +"@next/swc-darwin-arm64@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.1.tgz#ea9a76bcff00945df29a81bc43b3b22dd0a6cb53" + integrity sha512-KyB0aLpfQ+B2dsyGYpkM0ZwK3PV0t4C4b9yjgQc1VoTVnIjzXdDPnNOuVvmD849ZNOHfj3x8e2rlbxkj0lPm3A== + +"@next/swc-darwin-x64@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.1.tgz#95838e9116897ae734d02fdbbfa601b6f52adaf3" + integrity sha512-B3ZXgrGx0bQplbrk2oggPjKPPsmyg8Fl0PJLMTVQ+erQ8g1m5QzyS9P6tB3SiIZa180JgENuguTHlVK5qEj4UA== + +"@next/swc-linux-x64-gnu@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.1.tgz#42c4973213a880977ebdfad01474217d7d71e8c2" + integrity sha512-qvZL7gSKF+E+GZ3L1XiTnE3cOh9rk0wkqimT/q+wwcZA4E720Lu4lrT79I3HPuj6i/JPgGvmNskcnYrDeaoFaw== + +"@next/swc-win32-x64-msvc@11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.1.tgz#1ffcbd01a0155fa8558f7aefffea1066e9bebe74" + integrity sha512-jhnCiA1De1L+kA0gmHG1AJijHoxOcrETWziDWy8fcqSrM1NlC4aJ5Mnu6k0QMcM9MnmXTA4TQZOEv3kF7vhJUQ== "@node-rs/helper@1.2.1": version "1.2.1" @@ -2714,17 +2727,17 @@ next-transpile-modules@^8.0.0: enhanced-resolve "^5.7.0" escalade "^3.1.1" -next@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/next/-/next-11.1.0.tgz#767d4c4fa0b9b0c768cdbd6c9f03dd86b5d701c0" - integrity sha512-GHBk/c7Wyr6YbFRFZF37I0X7HKzkHHI8pur/loyXo5AIE8wdkbGPGO0ds3vNAO6f8AxZAKGCRYtAzoGlVLoifA== +next@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/next/-/next-11.1.1.tgz#ca15c6d6b4b4bf8c3e859f7fc4f9657ce59bcb63" + integrity sha512-vfLJDkwAHsZUho5R1K4w49nfYhftUMWNmeNSjCtulOvnRBuEFb7ROyRZOQk7f29rMz02eLQrPZ9yiAmPsexL2g== dependencies: - "@babel/runtime" "7.12.5" + "@babel/runtime" "7.15.3" "@hapi/accept" "5.0.2" - "@next/env" "11.1.0" - "@next/polyfill-module" "11.1.0" - "@next/react-dev-overlay" "11.1.0" - "@next/react-refresh-utils" "11.1.0" + "@next/env" "11.1.1" + "@next/polyfill-module" "11.1.1" + "@next/react-dev-overlay" "11.1.1" + "@next/react-refresh-utils" "11.1.1" "@node-rs/helper" "1.2.1" assert "2.0.0" ast-types "0.13.2" @@ -2766,9 +2779,14 @@ next@^11.1.0: timers-browserify "2.0.12" tty-browserify "0.0.1" use-subscription "1.5.1" - util "0.12.3" + util "0.12.4" vm-browserify "1.1.2" watchpack "2.1.1" + optionalDependencies: + "@next/swc-darwin-arm64" "11.1.1" + "@next/swc-darwin-x64" "11.1.1" + "@next/swc-linux-x64-gnu" "11.1.1" + "@next/swc-win32-x64-msvc" "11.1.1" node-fetch@2.6.1: version "2.6.1" @@ -4284,10 +4302,10 @@ util@0.10.3: dependencies: inherits "2.0.1" -util@0.12.3, util@^0.12.0: - version "0.12.3" - resolved "https://registry.npmjs.org/util/-/util-0.12.3.tgz" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== +util@0.12.4, util@^0.12.0: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== dependencies: inherits "^2.0.3" is-arguments "^1.0.4" -- cgit v1.2.3 From b0806dcf21ab811c46b715cfdff8a6307e117810 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 1 Sep 2021 18:28:34 +0200 Subject: feat(trace): Add API for trace reading This change introduces a new OpenDC API for reading various trace formats in a streaming manner. --- opendc-trace/opendc-trace-api/build.gradle.kts | 32 ++++++++ .../kotlin/org/opendc/trace/ResourceColumns.kt | 29 ++++++++ .../org/opendc/trace/ResourceStateColumns.kt | 86 ++++++++++++++++++++++ .../src/main/kotlin/org/opendc/trace/Table.kt | 53 +++++++++++++ .../main/kotlin/org/opendc/trace/TableColumn.kt | 59 +++++++++++++++ .../main/kotlin/org/opendc/trace/TableColumns.kt | 59 +++++++++++++++ .../main/kotlin/org/opendc/trace/TableReader.kt | 70 ++++++++++++++++++ .../src/main/kotlin/org/opendc/trace/Tables.kt | 44 +++++++++++ .../main/kotlin/org/opendc/trace/TaskColumns.kt | 86 ++++++++++++++++++++++ .../src/main/kotlin/org/opendc/trace/Trace.kt | 43 +++++++++++ .../kotlin/org/opendc/trace/spi/TraceFormat.kt | 62 ++++++++++++++++ settings.gradle.kts | 1 + 12 files changed, 624 insertions(+) create mode 100644 opendc-trace/opendc-trace-api/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Tables.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt diff --git a/opendc-trace/opendc-trace-api/build.gradle.kts b/opendc-trace/opendc-trace-api/build.gradle.kts new file mode 100644 index 00000000..b2f91593 --- /dev/null +++ b/opendc-trace/opendc-trace-api/build.gradle.kts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Workload trace library for OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt new file mode 100644 index 00000000..65055762 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("ResourceColumns") +package org.opendc.trace + +/** + * Identifier of the resource. + */ +public val RESOURCE_ID: TableColumn = stringColumn("resource:id") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt new file mode 100644 index 00000000..17f52ab6 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("ResourceStateColumns") +package org.opendc.trace + +import java.time.Instant + +/** + * Identifier of the resource. + */ +public val RESOURCE_STATE_ID: TableColumn = stringColumn("resource_state:id") + +/** + * Timestamp for the state. + */ +public val RESOURCE_STATE_TIMESTAMP: TableColumn = TableColumn("resource_state:timestamp", Instant::class.java) + +/** + * Number of CPUs for the resource. + */ +public val RESOURCE_STATE_NCPUS: TableColumn = intColumn("resource_state:ncpus") + +/** + * Total CPU capacity of the resource in MHz. + */ +public val RESOURCE_STATE_CPU_CAPACITY: TableColumn = doubleColumn("resource_state:cpu_capacity") + +/** + * Total CPU usage of the resource in MHz. + */ +public val RESOURCE_STATE_CPU_USAGE: TableColumn = doubleColumn("resource_state:cpu_usage") + +/** + * Total CPU usage of the resource in percentage. + */ +public val RESOURCE_STATE_CPU_USAGE_PCT: TableColumn = doubleColumn("resource_state:cpu_usage_pct") + +/** + * Memory capacity of the resource in KB. + */ +public val RESOURCE_STATE_MEM_CAPACITY: TableColumn = doubleColumn("resource_state:mem_capacity") + +/** + * Memory usage of the resource in KB. + */ +public val RESOURCE_STATE_MEM_USAGE: TableColumn = doubleColumn("resource_state:mem_usage") + +/** + * Disk read throughput of the resource in KB/s. + */ +public val RESOURCE_STATE_DISK_READ: TableColumn = doubleColumn("resource_state:disk_read") + +/** + * Disk write throughput of the resource in KB/s. + */ +public val RESOURCE_STATE_DISK_WRITE: TableColumn = doubleColumn("resource_state:disk_write") + +/** + * Network receive throughput of the resource in KB/s. + */ +public val RESOURCE_STATE_NET_RX: TableColumn = doubleColumn("resource_state:net_rx") + +/** + * Network transmit throughput of the resource in KB/s. + */ +public val RESOURCE_STATE_NET_TX: TableColumn = doubleColumn("resource_state:net_tx") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt new file mode 100644 index 00000000..11e5d6b7 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace + +/** + * A table is collection of rows consisting of typed columns. + */ +public interface Table { + /** + * The name of the table. + */ + public val name: String + + /** + * A flag to indicate that the table is synthetic (derived from another table). + */ + public val isSynthetic: Boolean + + /** + * Determine whether the specified [column] is supported by this table. + */ + public fun isSupported(column: TableColumn<*>): Boolean + + /** + * Open a [TableReader] for this table. + */ + public fun newReader(): TableReader + + /** + * Open a [TableReader] for [partition] of the table. + */ + public fun newReader(partition: String): TableReader +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt new file mode 100644 index 00000000..247e7312 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace + +import java.util.* + +/** + * A column in a trace table. + * + * @param name The universal name of this column. + */ +public class TableColumn(public val name: String, type: Class) { + /** + * The type of the column. + */ + private val type: Class<*> = type + + /** + * Determine whether the type of the column is a subtype of [column]. + */ + public fun isAssignableTo(column: TableColumn<*>): Boolean { + return type.isAssignableFrom(column.type) + } + + /** + * Compute a hash code for this column. + */ + public override fun hashCode(): Int = Objects.hash(name, type) + + /** + * Determine whether this column is equal to [other]. + */ + public override fun equals(other: Any?): Boolean = other is TableColumn<*> && name == other.name && type == other.type + + /** + * Return a string representation of this column. + */ + public override fun toString(): String = "TableColumn[$name,$type]" +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt new file mode 100644 index 00000000..64920498 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("TableColumns") +package org.opendc.trace + +/** + * Construct a [TableColumn] with [Any] type. + */ +public fun objectColumn(name: String): TableColumn = TableColumn(name, Any::class.java) + +/** + * Construct a [TableColumn] with a [String] type. + */ +public fun stringColumn(name: String): TableColumn = TableColumn(name, String::class.java) + +/** + * Construct a [TableColumn] with a [Number] type. + */ +public fun numberColumn(name: String): TableColumn = TableColumn(name, Number::class.java) + +/** + * Construct a [TableColumn] with an [Int] type. + */ +public fun intColumn(name: String): TableColumn = TableColumn(name, Int::class.java) + +/** + * Construct a [TableColumn] with a [Long] type. + */ +public fun longColumn(name: String): TableColumn = TableColumn(name, Long::class.java) + +/** + * Construct a [TableColumn] with a [Double] type. + */ +public fun doubleColumn(name: String): TableColumn = TableColumn(name, Double::class.java) + +/** + * Construct a [TableColumn] with a [Boolean] type. + */ +public fun booleanColumn(name: String): TableColumn = TableColumn(name, Boolean::class.java) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt new file mode 100644 index 00000000..b5e7669f --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace + +/** + * Base class for reading entities from a workload trace table in streaming fashion. + */ +public interface TableReader : AutoCloseable { + /** + * Advance the stream until the next row is reached. + * + * @return `true` if the row is valid, `false` if there are no more rows. + */ + public fun nextRow(): Boolean + + /** + * Determine whether the [TableReader] supports the specified [column]. + */ + public fun hasColumn(column: TableColumn<*>): Boolean + + /** + * Obtain the value of the current column with type [T]. + */ + public fun get(column: TableColumn): T + + /** + * Read the specified [column] as boolean. + */ + public fun getBoolean(column: TableColumn): Boolean + + /** + * Read the specified [column] as integer. + */ + public fun getInt(column: TableColumn): Int + + /** + * Read the specified [column] as long. + */ + public fun getLong(column: TableColumn): Long + + /** + * Read the specified [column] as double. + */ + public fun getDouble(column: TableColumn): Double + + /** + * Closes the reader so that no further iteration or data access can be made. + */ + public override fun close() +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Tables.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Tables.kt new file mode 100644 index 00000000..bb9d93e2 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Tables.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("Tables") +package org.opendc.trace + +/** + * A table containing all workflows in a workload. + */ +public const val TABLE_WORKFLOWS: String = "workflows" + +/** + * A table containing all tasks in a workload. + */ +public const val TABLE_TASKS: String = "tasks" + +/** + * A table containing all resources in a workload. + */ +public const val TABLE_RESOURCES: String = "resources" + +/** + * A table containing all resource states in a workload. + */ +public const val TABLE_RESOURCE_STATES: String = "resource_states" diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt new file mode 100644 index 00000000..5d3143ff --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("TaskColumns") +package org.opendc.trace + +/** + * A column containing the task identifier. + */ +public val TASK_ID: TableColumn = longColumn("task:id") + +/** + * A column containing the identifier of the workflow. + */ +public val TASK_WORKFLOW_ID: TableColumn = longColumn("task:workflow_id") + +/** + * A column containing the submit time of the task. + */ +public val TASK_SUBMIT_TIME: TableColumn = longColumn("task:submit_time") + +/** + * A column containing the wait time of the task. + */ +public val TASK_WAIT_TIME: TableColumn = longColumn("task:wait_time") + +/** + * A column containing the runtime time of the task. + */ +public val TASK_RUNTIME: TableColumn = longColumn("task:runtime") + +/** + * A column containing the parents of a task. + */ +@Suppress("UNCHECKED_CAST") +public val TASK_PARENTS: TableColumn> = TableColumn("task:parents", type = Set::class.java as Class>) + +/** + * A column containing the children of a task. + */ +@Suppress("UNCHECKED_CAST") +public val TASK_CHILDREN: TableColumn> = TableColumn("task:children", type = Set::class.java as Class>) + +/** + * A column containing the requested CPUs of a task. + */ +public val TASK_REQ_NCPUS: TableColumn = intColumn("task:req_ncpus") + +/** + * A column containing the allocated CPUs of a task. + */ +public val TASK_ALLOC_NCPUS: TableColumn = intColumn("task:alloc_ncpus") + +/** + * A column containing the status of a task. + */ +public val TASK_STATUS: TableColumn = intColumn("task:status") + +/** + * A column containing the group id of a task. + */ +public val TASK_GROUP_ID: TableColumn = intColumn("task:group_id") + +/** + * A column containing the user id of a task. + */ +public val TASK_USER_ID: TableColumn = intColumn("task:user_id") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt new file mode 100644 index 00000000..36e93b52 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace + +/** + * A trace is a collection of related tables that characterize a workload. + */ +public interface Trace { + /** + * The list of table names in the workload trace. + */ + public val tables: List + + /** + * Determine if the trace contains a table with the specified [name]. + */ + public fun containsTable(name: String): Boolean + + /** + * Obtain a [Table] with the specified [name]. + */ + public fun getTable(name: String): Table? +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt new file mode 100644 index 00000000..54029fcf --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.spi + +import org.opendc.trace.Trace +import java.net.URL +import java.util.* + +/** + * A service-provider class for parsing trace formats. + */ +public interface TraceFormat { + /** + * The name of the trace format. + */ + public val name: String + + /** + * Open a new [Trace] with this provider. + * + * @param url A reference to the trace. + */ + public fun open(url: URL): Trace + + /** + * A helper object for resolving providers. + */ + public companion object { + /** + * A list of [TraceFormat] that are available on this system. + */ + public val installedProviders: List by lazy { + val loader = ServiceLoader.load(TraceFormat::class.java) + loader.toList() + } + + /** + * Obtain a [TraceFormat] implementation by [name]. + */ + public fun byName(name: String): TraceFormat? = installedProviders.find { it.name == name } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index d85c08f8..36c1d9e0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -46,6 +46,7 @@ include(":opendc-simulator:opendc-simulator-compute") include(":opendc-simulator:opendc-simulator-failures") include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") +include(":opendc-trace:opendc-trace-api") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") include(":opendc-harness:opendc-harness-cli") -- cgit v1.2.3 From 23c1502c2668305fd5f4c38c6c794c985d2037e3 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 14:56:08 +0200 Subject: refactor(trace): Move GWF trace reader into separate module This change starts the process of moving the different trace formats into separate modules. This change in particular moves the GWF trace format into a new module, opendc-trace-gwf. Furthermore, this change also implements the trace API for the GWF module. --- opendc-format/build.gradle.kts | 2 +- .../org/opendc/format/trace/gwf/GwfTraceReader.kt | 176 ----------------- opendc-trace/build.gradle.kts | 21 ++ opendc-trace/opendc-trace-gwf/build.gradle.kts | 37 ++++ .../kotlin/org/opendc/trace/gwf/GwfTaskTable.kt | 59 ++++++ .../org/opendc/trace/gwf/GwfTaskTableReader.kt | 211 +++++++++++++++++++++ .../main/kotlin/org/opendc/trace/gwf/GwfTrace.kt | 46 +++++ .../kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt | 56 ++++++ .../services/org.opendc.trace.spi.TraceFormat | 1 + .../org/opendc/trace/gwf/GwfTraceFormatTest.kt | 109 +++++++++++ .../opendc-trace-gwf/src/test/resources/trace.gwf | 71 +++++++ .../opendc-workflow-service/build.gradle.kts | 6 +- .../org/opendc/workflow/service/TraceReplayer.kt | 127 +++++++++++++ .../service/WorkflowServiceIntegrationTest.kt | 164 ---------------- .../opendc/workflow/service/WorkflowServiceTest.kt | 163 ++++++++++++++++ settings.gradle.kts | 1 + 16 files changed, 904 insertions(+), 346 deletions(-) delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/gwf/GwfTraceReader.kt create mode 100644 opendc-trace/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-gwf/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt create mode 100644 opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt create mode 100644 opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt create mode 100644 opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-gwf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-gwf/src/test/resources/trace.gwf create mode 100644 opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt delete mode 100644 opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt create mode 100644 opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt diff --git a/opendc-format/build.gradle.kts b/opendc-format/build.gradle.kts index c8e30846..c1258428 100644 --- a/opendc-format/build.gradle.kts +++ b/opendc-format/build.gradle.kts @@ -39,7 +39,7 @@ dependencies { exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") } implementation(libs.jackson.dataformat.csv) - implementation(kotlin("reflect")) + implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.30") /* This configuration is necessary for a slim dependency on Apache Parquet */ implementation(libs.parquet) { diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/gwf/GwfTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/gwf/GwfTraceReader.kt deleted file mode 100644 index e68afeb7..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/gwf/GwfTraceReader.kt +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.gwf - -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader -import org.opendc.simulator.compute.workload.SimFlopsWorkload -import org.opendc.workflow.api.Job -import org.opendc.workflow.api.Task -import org.opendc.workflow.api.WORKFLOW_TASK_CORES -import org.opendc.workflow.api.WORKFLOW_TASK_DEADLINE -import java.io.BufferedReader -import java.io.File -import java.io.InputStream -import java.util.* -import kotlin.collections.HashSet -import kotlin.collections.Iterator -import kotlin.collections.List -import kotlin.collections.MutableSet -import kotlin.collections.component1 -import kotlin.collections.component2 -import kotlin.collections.filter -import kotlin.collections.forEach -import kotlin.collections.getOrPut -import kotlin.collections.map -import kotlin.collections.mapIndexed -import kotlin.collections.mapOf -import kotlin.collections.mutableMapOf -import kotlin.collections.set -import kotlin.collections.sortedBy -import kotlin.collections.toMap -import kotlin.math.max -import kotlin.math.min - -/** - * A [TraceReader] for the Grid Workload Format. See the Grid Workloads Archive (http://gwa.ewi.tudelft.nl/) for more - * information about the format. - * - * Be aware that in the Grid Workload Format, workflows are not required to be ordered by submission time and therefore - * this reader needs to read the whole trace into memory before an entry can be read. Consider converting the trace to a - * different format for better performance. - * - * @param reader The buffered reader to read the trace with. - */ -public class GwfTraceReader(reader: BufferedReader) : TraceReader { - /** - * The internal iterator to use for this reader. - */ - private val iterator: Iterator> - - /** - * Create a [GwfTraceReader] instance from the specified [File]. - * - * @param file The file to read from. - */ - public constructor(file: File) : this(file.bufferedReader()) - - /** - * Create a [GwfTraceReader] instance from the specified [InputStream]. - * - * @param input The input stream to read from. - */ - public constructor(input: InputStream) : this(input.bufferedReader()) - - /** - * Initialize the reader. - */ - init { - val workflows = mutableMapOf() - val starts = mutableMapOf() - val tasks = mutableMapOf() - val taskDependencies = mutableMapOf>() - - var workflowIdCol = 0 - var taskIdCol = 0 - var submitTimeCol = 0 - var runtimeCol = 0 - var coreCol = 0 - var dependencyCol = 0 - - try { - reader.lineSequence() - .filter { line -> - // Ignore comments in the trace - !line.startsWith("#") && line.isNotBlank() - } - .forEachIndexed { idx, line -> - val values = line.split(",") - - // Parse GWF header - if (idx == 0) { - val header = values.mapIndexed { col, name -> Pair(name.trim(), col) }.toMap() - workflowIdCol = header["WorkflowID"]!! - taskIdCol = header["JobID"]!! - submitTimeCol = header["SubmitTime"]!! - runtimeCol = header["RunTime"]!! - coreCol = header["NProcs"]!! - dependencyCol = header["Dependencies"]!! - return@forEachIndexed - } - - val workflowId = values[workflowIdCol].trim().toLong() - val taskId = values[taskIdCol].trim().toLong() - val submitTime = values[submitTimeCol].trim().toLong() * 1000 // ms - val runtime = max(0, values[runtimeCol].trim().toLong()) // s - val cores = values[coreCol].trim().toInt() - val dependencies = values[dependencyCol].split(" ") - .filter { it.isNotEmpty() } - .map { it.trim().toLong() } - - val flops: Long = 4000 * runtime * cores - - val workflow = workflows.getOrPut(workflowId) { - Job(UUID(0L, workflowId), "", HashSet()) - } - val workload = SimFlopsWorkload(flops) - val task = Task( - UUID(0L, taskId), - "", - HashSet(), - mapOf( - "workload" to workload, - WORKFLOW_TASK_CORES to cores, - WORKFLOW_TASK_DEADLINE to (runtime * 1000) - ), - ) - starts.merge(workflowId, submitTime, ::min) - (workflow.tasks as MutableSet).add(task) - tasks[taskId] = task - taskDependencies[task] = dependencies - } - } finally { - reader.close() - } - - // Fix dependencies and dependents for all tasks - taskDependencies.forEach { (task, dependencies) -> - (task.dependencies as MutableSet).addAll( - dependencies.map { taskId -> - tasks[taskId] ?: throw IllegalArgumentException("Dependency task with id $taskId not found") - } - ) - } - - // Create the entry iterator - iterator = workflows.map { (id, job) -> TraceEntry(job.uid, job.name, starts.getValue(id), job, job.metadata) } - .sortedBy { it.start } - .iterator() - } - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() {} -} diff --git a/opendc-trace/build.gradle.kts b/opendc-trace/build.gradle.kts new file mode 100644 index 00000000..7edfd134 --- /dev/null +++ b/opendc-trace/build.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ diff --git a/opendc-trace/opendc-trace-gwf/build.gradle.kts b/opendc-trace/opendc-trace-gwf/build.gradle.kts new file mode 100644 index 00000000..f3dfd6ef --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/build.gradle.kts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for GWF traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) + + implementation(libs.jackson.dataformat.csv) +} diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt new file mode 100644 index 00000000..80a99d10 --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.gwf + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.net.URL + +/** + * A [Table] containing the tasks in a GWF trace. + */ +internal class GwfTaskTable(private val factory: CsvFactory, private val url: URL) : Table { + override val name: String = TABLE_TASKS + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + TASK_WORKFLOW_ID -> true + TASK_ID -> true + TASK_SUBMIT_TIME -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_ALLOC_NCPUS -> true + TASK_PARENTS -> true + else -> false + } + } + + override fun newReader(): TableReader { + return GwfTaskTableReader(factory.createParser(url)) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Invalid partition $partition") + } + + override fun toString(): String = "GwfTaskTable" +} diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt new file mode 100644 index 00000000..64b7d465 --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.gwf + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.util.regex.Pattern + +/** + * A [TableReader] implementation for the GWF format. + */ +internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { + /** + * The current parser state. + */ + private val state = RowState() + + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + // Reset the row state + state.reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "WorkflowID" -> state.workflowId = parser.longValue + "JobID" -> state.jobId = parser.longValue + "SubmitTime" -> state.submitTime = parser.longValue + "RunTime" -> state.runtime = parser.longValue + "NProcs" -> state.nProcs = parser.intValue + "ReqNProcs" -> state.reqNProcs = parser.intValue + "Dependencies" -> parseParents(parser.valueAsString) + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + TASK_WORKFLOW_ID -> true + TASK_ID -> true + TASK_SUBMIT_TIME -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_ALLOC_NCPUS -> true + TASK_PARENTS -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any = when (column) { + TASK_WORKFLOW_ID -> state.workflowId + TASK_ID -> state.jobId + TASK_SUBMIT_TIME -> state.submitTime + TASK_RUNTIME -> state.runtime + TASK_REQ_NCPUS -> state.nProcs + TASK_ALLOC_NCPUS -> state.reqNProcs + TASK_PARENTS -> state.dependencies + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + TASK_REQ_NCPUS -> state.nProcs + TASK_ALLOC_NCPUS -> state.reqNProcs + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + return when (column) { + TASK_WORKFLOW_ID -> state.workflowId + TASK_ID -> state.jobId + TASK_SUBMIT_TIME -> state.submitTime + TASK_RUNTIME -> state.runtime + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getDouble(column: TableColumn): Double { + throw IllegalArgumentException("Invalid column") + } + + override fun close() { + parser.close() + } + + /** + * The pattern used to parse the parents. + */ + private val pattern = Pattern.compile("\\s+") + + /** + * Parse the parents into a set of longs. + */ + private fun parseParents(value: String): Set { + val result = mutableSetOf() + val deps = value.split(pattern) + + for (dep in deps) { + if (dep.isBlank()) { + continue + } + + result.add(dep.toLong(10)) + } + + return result + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * The current row state. + */ + private class RowState { + var workflowId = -1L + var jobId = -1L + var submitTime = -1L + var runtime = -1L + var nProcs = -1 + var reqNProcs = -1 + var dependencies = emptySet() + + /** + * Reset the state. + */ + fun reset() { + workflowId = -1 + jobId = -1 + submitTime = -1 + runtime = -1 + nProcs = -1 + reqNProcs = -1 + dependencies = emptySet() + } + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("WorkflowID", CsvSchema.ColumnType.NUMBER) + .addColumn("JobID", CsvSchema.ColumnType.NUMBER) + .addColumn("SubmitTime", CsvSchema.ColumnType.NUMBER) + .addColumn("RunTime", CsvSchema.ColumnType.NUMBER) + .addColumn("NProcs", CsvSchema.ColumnType.NUMBER) + .addColumn("ReqNProcs", CsvSchema.ColumnType.NUMBER) + .addColumn("Dependencies", CsvSchema.ColumnType.STRING) + .setAllowComments(true) + .setUseHeader(true) + .setColumnSeparator(',') + .build() + } +} diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt new file mode 100644 index 00000000..166c1e56 --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.gwf + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.net.URL + +/** + * [Trace] implementation for the GWF format. + */ +public class GwfTrace internal constructor(private val factory: CsvFactory, private val url: URL) : Trace { + override val tables: List = listOf(TABLE_TASKS) + + override fun containsTable(name: String): Boolean = TABLE_TASKS == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + + return GwfTaskTable(factory, url) + } + + override fun toString(): String = "GwfTrace[$url]" +} diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt new file mode 100644 index 00000000..6d542503 --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.gwf + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A [TraceFormat] implementation for the GWF trace format. + */ +public class GwfTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "gwf" + + /** + * The [CsvFactory] used to create the parser. + */ + private val factory = CsvFactory() + .enable(CsvParser.Feature.ALLOW_COMMENTS) + .enable(CsvParser.Feature.TRIM_SPACES) + + /** + * Read the tasks in the GWF trace. + */ + public override fun open(url: URL): GwfTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return GwfTrace(factory, url) + } +} diff --git a/opendc-trace/opendc-trace-gwf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-gwf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..99a874c8 --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.gwf.GwfTraceFormat diff --git a/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt b/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt new file mode 100644 index 00000000..6b0568fe --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.gwf + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.* +import java.net.URL + +/** + * Test suite for the [GwfTraceFormat] class. + */ +internal class GwfTraceFormatTest { + @Test + fun testTraceExists() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + assertDoesNotThrow { + format.open(input) + } + } + + @Test + fun testTraceDoesNotExists() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + assertThrows { + format.open(URL(input.toString() + "help")) + } + } + + @Test + fun testTables() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + val trace = format.open(input) + + assertEquals(listOf(TABLE_TASKS), trace.tables) + } + + @Test + fun testTableExists() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + val trace = format.open(input) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + @Test + fun testTableReader() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS)!! + val reader = table.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals(0L, reader.getLong(TASK_WORKFLOW_ID)) }, + { assertEquals(1L, reader.getLong(TASK_ID)) }, + { assertEquals(16, reader.getLong(TASK_SUBMIT_TIME)) }, + { assertEquals(11, reader.getLong(TASK_RUNTIME)) }, + { assertEquals(setOf(), reader.get(TASK_PARENTS)) }, + ) + } + + @Test + fun testTableReaderPartition() { + val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) + val format = GwfTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS)!! + + assertThrows { table.newReader("test") } + } +} diff --git a/opendc-trace/opendc-trace-gwf/src/test/resources/trace.gwf b/opendc-trace/opendc-trace-gwf/src/test/resources/trace.gwf new file mode 100644 index 00000000..2f99616d --- /dev/null +++ b/opendc-trace/opendc-trace-gwf/src/test/resources/trace.gwf @@ -0,0 +1,71 @@ +WorkflowID, JobID , SubmitTime, RunTime , NProcs , ReqNProcs , Dependencies +0 , 1 , 16 , 11 , 1 , 1 , +0 , 2 , 40 , 11 , 1 , 1 , 1 +0 , 3 , 40 , 11 , 1 , 1 , 1 +0 , 4 , 64 , 11 , 1 , 1 , 2 +0 , 5 , 63 , 11 , 1 , 1 , 3 +0 , 6 , 64 , 11 , 1 , 1 , 3 +0 , 7 , 87 , 11 , 1 , 1 , 4 5 6 +1 , 8 , 4 , 11 , 1 , 1 , +1 , 9 , 15 , 11 , 1 , 1 , 8 +1 , 10 , 15 , 11 , 1 , 1 , 8 +1 , 11 , 27 , 11 , 1 , 1 , 9 +1 , 12 , 27 , 11 , 1 , 1 , 10 +1 , 13 , 27 , 11 , 1 , 1 , 10 +1 , 14 , 38 , 11 , 1 , 1 , 12 11 13 +2 , 15 , 3 , 11 , 1 , 1 , +2 , 16 , 27 , 11 , 1 , 1 , 15 +2 , 17 , 27 , 11 , 1 , 1 , 15 +2 , 18 , 52 , 11 , 1 , 1 , 16 +2 , 19 , 51 , 11 , 1 , 1 , 17 +2 , 20 , 51 , 11 , 1 , 1 , 17 +2 , 21 , 75 , 11 , 1 , 1 , 20 18 19 +3 , 22 , 3 , 11 , 1 , 1 , +3 , 23 , 27 , 11 , 1 , 1 , 22 +3 , 24 , 27 , 11 , 1 , 1 , 22 +3 , 25 , 51 , 11 , 1 , 1 , 23 +3 , 26 , 50 , 11 , 1 , 1 , 24 +3 , 27 , 51 , 11 , 1 , 1 , 24 +3 , 28 , 75 , 11 , 1 , 1 , 25 27 26 +4 , 29 , 3 , 11 , 1 , 1 , +4 , 30 , 27 , 11 , 1 , 1 , 29 +4 , 31 , 27 , 11 , 1 , 1 , 29 +4 , 32 , 50 , 11 , 1 , 1 , 30 +4 , 33 , 50 , 11 , 1 , 1 , 31 +4 , 34 , 51 , 11 , 1 , 1 , 31 +4 , 35 , 74 , 11 , 1 , 1 , 33 32 34 +5 , 36 , 3 , 11 , 1 , 1 , +5 , 37 , 27 , 11 , 1 , 1 , 36 +5 , 38 , 26 , 11 , 1 , 1 , 36 +5 , 39 , 51 , 11 , 1 , 1 , 37 +5 , 40 , 50 , 11 , 1 , 1 , 38 +5 , 41 , 50 , 11 , 1 , 1 , 38 +5 , 42 , 74 , 11 , 1 , 1 , 39 40 41 +6 , 43 , 4 , 11 , 1 , 1 , +6 , 44 , 27 , 11 , 1 , 1 , 43 +6 , 45 , 27 , 11 , 1 , 1 , 43 +6 , 46 , 51 , 11 , 1 , 1 , 44 +6 , 47 , 51 , 11 , 1 , 1 , 45 +6 , 48 , 51 , 11 , 1 , 1 , 45 +6 , 49 , 75 , 11 , 1 , 1 , 46 47 48 +7 , 50 , 3 , 0 , 1 , 1 , +7 , 51 , 17 , 0 , 1 , 1 , 50 +7 , 52 , 17 , 0 , 1 , 1 , 50 +7 , 53 , 30 , 0 , 1 , 1 , 51 +7 , 54 , 30 , 0 , 1 , 1 , 52 +7 , 55 , 31 , 0 , 1 , 1 , 52 +7 , 56 , 44 , 0 , 1 , 1 , 55 54 53 +8 , 57 , 3 , 11 , 1 , 1 , +8 , 58 , 26 , 11 , 1 , 1 , 57 +8 , 59 , 27 , 11 , 1 , 1 , 57 +8 , 60 , 50 , 11 , 1 , 1 , 58 +8 , 61 , 51 , 11 , 1 , 1 , 59 +8 , 62 , 50 , 11 , 1 , 1 , 59 +8 , 63 , 74 , 11 , 1 , 1 , 62 61 60 +9 , 64 , 3 , 11 , 1 , 1 , +9 , 65 , 27 , 11 , 1 , 1 , 64 +9 , 66 , 27 , 11 , 1 , 1 , 64 +9 , 67 , 51 , 11 , 1 , 1 , 65 +9 , 68 , 50 , 11 , 1 , 1 , 66 +9 , 69 , 51 , 11 , 1 , 1 , 66 +9 , 70 , 74 , 11 , 1 , 1 , 68 69 67 diff --git a/opendc-workflow/opendc-workflow-service/build.gradle.kts b/opendc-workflow/opendc-workflow-service/build.gradle.kts index bc082dbc..941202d2 100644 --- a/opendc-workflow/opendc-workflow-service/build.gradle.kts +++ b/opendc-workflow/opendc-workflow-service/build.gradle.kts @@ -39,11 +39,7 @@ dependencies { testImplementation(projects.opendcSimulator.opendcSimulatorCore) testImplementation(projects.opendcCompute.opendcComputeSimulator) - testImplementation(projects.opendcFormat) + testImplementation(projects.opendcTrace.opendcTraceGwf) testImplementation(projects.opendcTelemetry.opendcTelemetrySdk) - testImplementation(libs.jackson.module.kotlin) { - exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") - } - testImplementation(kotlin("reflect")) testRuntimeOnly(libs.log4j.slf4j) } diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt new file mode 100644 index 00000000..a390fe08 --- /dev/null +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.workflow.service + +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import org.opendc.simulator.compute.workload.SimFlopsWorkload +import org.opendc.trace.* +import org.opendc.workflow.api.Job +import org.opendc.workflow.api.Task +import org.opendc.workflow.api.WORKFLOW_TASK_CORES +import org.opendc.workflow.api.WORKFLOW_TASK_DEADLINE +import java.time.Clock +import java.util.* +import kotlin.collections.HashMap +import kotlin.collections.HashSet +import kotlin.math.max +import kotlin.math.min + +/** + * Helper tool to replay workflow trace. + */ +internal class TraceReplayer(private val trace: Trace) { + /** + * Replay the workload. + */ + public suspend fun replay(clock: Clock, service: WorkflowService) { + val jobs = parseTrace(trace) + + // Sort jobs by their arrival time + (jobs as MutableList).sortBy { it.metadata["WORKFLOW_SUBMIT_TIME"] as Long } + + // Wait until the trace is started + val startTime = jobs[0].metadata["WORKFLOW_SUBMIT_TIME"] as Long + delay(min(0L, startTime - clock.millis())) + + val offset = startTime - clock.millis() + + coroutineScope { + for (job in jobs) { + val submitTime = job.metadata["WORKFLOW_SUBMIT_TIME"] as Long + delay(max(0, (submitTime - offset) - clock.millis())) + + launch { service.run(job) } + } + } + } + + /** + * Convert [trace] into a list of [Job]s that can be submitted to the workflow service. + */ + public fun parseTrace(trace: Trace): List { + val table = checkNotNull(trace.getTable(TABLE_TASKS)) + val reader = table.newReader() + + val jobs = mutableMapOf() + val tasks = mutableMapOf() + val taskDependencies = mutableMapOf>() + + try { + while (reader.nextRow()) { + // Bag of tasks without workflow ID all share the same workflow + val workflowId = if (reader.hasColumn(TASK_WORKFLOW_ID)) reader.getLong(TASK_WORKFLOW_ID) else 0L + val workflow = jobs.computeIfAbsent(workflowId) { id -> Job(UUID(0L, id), "", HashSet(), HashMap()) } + + val id = reader.getLong(TASK_ID) + val grantedCpus = if (reader.hasColumn(TASK_ALLOC_NCPUS)) + reader.getInt(TASK_ALLOC_NCPUS) + else + reader.getInt(TASK_REQ_NCPUS) + val submitTime = reader.getLong(TASK_SUBMIT_TIME) + val runtime = reader.getLong(TASK_RUNTIME) + val flops: Long = 4000 * runtime * grantedCpus + val workload = SimFlopsWorkload(flops) + val task = Task( + UUID(0L, id), + "", + HashSet(), + mapOf( + "workload" to workload, + WORKFLOW_TASK_CORES to grantedCpus, + WORKFLOW_TASK_DEADLINE to (runtime * 1000) + ), + ) + + tasks[id] = task + taskDependencies[task] = reader.get(TASK_PARENTS) + + (workflow.metadata as MutableMap).merge("WORKFLOW_SUBMIT_TIME", submitTime) { a, b -> min(a as Long, b as Long) } + (workflow.tasks as MutableSet).add(task) + } + + // Resolve dependencies for all tasks + for ((task, deps) in taskDependencies) { + for (dep in deps) { + val parent = requireNotNull(tasks[dep]) { "Dependency task with id $dep not found" } + (task.dependencies as MutableSet).add(parent) + } + } + } finally { + reader.close() + } + + return jobs.values.toList() + } +} diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt deleted file mode 100644 index d82959e7..00000000 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.workflow.service - -import io.opentelemetry.api.metrics.MeterProvider -import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.metrics.export.MetricProducer -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.DisplayName -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.opendc.compute.service.ComputeService -import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.filters.RamFilter -import org.opendc.compute.service.scheduler.filters.VCpuFilter -import org.opendc.compute.service.scheduler.weights.VCpuWeigher -import org.opendc.compute.simulator.SimHost -import org.opendc.format.environment.sc18.Sc18EnvironmentReader -import org.opendc.format.trace.gwf.GwfTraceReader -import org.opendc.simulator.compute.kernel.SimSpaceSharedHypervisorProvider -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.telemetry.sdk.toOtelClock -import org.opendc.workflow.service.internal.WorkflowServiceImpl -import org.opendc.workflow.service.scheduler.WorkflowSchedulerMode -import org.opendc.workflow.service.scheduler.job.NullJobAdmissionPolicy -import org.opendc.workflow.service.scheduler.job.SubmissionTimeJobOrderPolicy -import org.opendc.workflow.service.scheduler.task.NullTaskEligibilityPolicy -import org.opendc.workflow.service.scheduler.task.SubmissionTimeTaskOrderPolicy -import kotlin.math.max - -/** - * Integration test suite for the [WorkflowServiceImpl]. - */ -@DisplayName("WorkflowService") -internal class WorkflowServiceIntegrationTest { - /** - * A large integration test where we check whether all tasks in some trace are executed correctly. - */ - @Test - fun testTrace() = runBlockingSimulation { - val meterProvider: MeterProvider = SdkMeterProvider - .builder() - .setClock(clock.toOtelClock()) - .build() - - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val hosts = Sc18EnvironmentReader(checkNotNull(object {}.javaClass.getResourceAsStream("/environment.json"))) - .use { it.read() } - .map { def -> - SimHost( - def.uid, - def.name, - def.model, - def.meta, - coroutineContext, - interpreter, - MeterProvider.noop().get("opendc-compute-simulator"), - SimSpaceSharedHypervisorProvider() - ) - } - - val meter = MeterProvider.noop().get("opendc-compute") - val computeScheduler = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), - weighers = listOf(VCpuWeigher(1.0, multiplier = 1.0)) - ) - val compute = ComputeService(coroutineContext, clock, meter, computeScheduler, schedulingQuantum = 1000) - - hosts.forEach { compute.addHost(it) } - - val scheduler = WorkflowService( - coroutineContext, - clock, - meterProvider.get("opendc-workflow"), - compute.newClient(), - mode = WorkflowSchedulerMode.Batch(100), - jobAdmissionPolicy = NullJobAdmissionPolicy, - jobOrderPolicy = SubmissionTimeJobOrderPolicy(), - taskEligibilityPolicy = NullTaskEligibilityPolicy, - taskOrderPolicy = SubmissionTimeTaskOrderPolicy(), - ) - - val reader = GwfTraceReader(checkNotNull(object {}.javaClass.getResourceAsStream("/trace.gwf"))) - var offset = Long.MIN_VALUE - - coroutineScope { - while (reader.hasNext()) { - val entry = reader.next() - - if (offset < 0) { - offset = entry.start - clock.millis() - } - - delay(max(0, (entry.start - offset) - clock.millis())) - launch { - scheduler.run(entry.workload) - } - } - } - - hosts.forEach(SimHost::close) - scheduler.close() - compute.close() - - val metrics = collectMetrics(meterProvider as MetricProducer) - - assertAll( - { assertEquals(758, metrics.jobsSubmitted, "No jobs submitted") }, - { assertEquals(0, metrics.jobsActive, "Not all submitted jobs started") }, - { assertEquals(metrics.jobsSubmitted, metrics.jobsFinished, "Not all started jobs finished") }, - { assertEquals(0, metrics.tasksActive, "Not all started tasks finished") }, - { assertEquals(metrics.tasksSubmitted, metrics.tasksFinished, "Not all started tasks finished") } - ) - } - - class WorkflowMetrics { - var jobsSubmitted = 0L - var jobsActive = 0L - var jobsFinished = 0L - var tasksSubmitted = 0L - var tasksActive = 0L - var tasksFinished = 0L - } - - /** - * Collect the metrics of the workflow service. - */ - private fun collectMetrics(metricProducer: MetricProducer): WorkflowMetrics { - val metrics = metricProducer.collectAllMetrics().associateBy { it.name } - val res = WorkflowMetrics() - res.jobsSubmitted = metrics["jobs.submitted"]?.longSumData?.points?.last()?.value ?: 0 - res.jobsActive = metrics["jobs.active"]?.longSumData?.points?.last()?.value ?: 0 - res.jobsFinished = metrics["jobs.finished"]?.longSumData?.points?.last()?.value ?: 0 - res.tasksSubmitted = metrics["tasks.submitted"]?.longSumData?.points?.last()?.value ?: 0 - res.tasksActive = metrics["tasks.active"]?.longSumData?.points?.last()?.value ?: 0 - res.tasksFinished = metrics["tasks.finished"]?.longSumData?.points?.last()?.value ?: 0 - return res - } -} diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt new file mode 100644 index 00000000..07433d1f --- /dev/null +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.workflow.service + +import io.opentelemetry.api.metrics.MeterProvider +import io.opentelemetry.sdk.metrics.SdkMeterProvider +import io.opentelemetry.sdk.metrics.export.MetricProducer +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.opendc.compute.service.ComputeService +import org.opendc.compute.service.scheduler.FilterScheduler +import org.opendc.compute.service.scheduler.filters.ComputeFilter +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.VCpuWeigher +import org.opendc.compute.simulator.SimHost +import org.opendc.simulator.compute.kernel.SimSpaceSharedHypervisorProvider +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.model.MemoryUnit +import org.opendc.simulator.compute.model.ProcessingNode +import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.telemetry.sdk.toOtelClock +import org.opendc.trace.gwf.GwfTraceFormat +import org.opendc.workflow.service.internal.WorkflowServiceImpl +import org.opendc.workflow.service.scheduler.WorkflowSchedulerMode +import org.opendc.workflow.service.scheduler.job.NullJobAdmissionPolicy +import org.opendc.workflow.service.scheduler.job.SubmissionTimeJobOrderPolicy +import org.opendc.workflow.service.scheduler.task.NullTaskEligibilityPolicy +import org.opendc.workflow.service.scheduler.task.SubmissionTimeTaskOrderPolicy +import java.util.* + +/** + * Integration test suite for the [WorkflowServiceImpl]. + */ +@DisplayName("WorkflowService") +internal class WorkflowServiceTest { + /** + * A large integration test where we check whether all tasks in some trace are executed correctly. + */ + @Test + fun testTrace() = runBlockingSimulation { + val meterProvider: MeterProvider = SdkMeterProvider + .builder() + .setClock(clock.toOtelClock()) + .build() + + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val machineModel = createMachineModel() + val hvProvider = SimSpaceSharedHypervisorProvider() + val hosts = List(4) { id -> + SimHost( + UUID(0, id.toLong()), + "node-$id", + machineModel, + emptyMap(), + coroutineContext, + interpreter, + meterProvider.get("opendc-compute-simulator"), + hvProvider, + ) + } + + val meter = MeterProvider.noop().get("opendc-compute") + val computeScheduler = FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), + weighers = listOf(VCpuWeigher(1.0, multiplier = 1.0)) + ) + val compute = ComputeService(coroutineContext, clock, meter, computeScheduler, schedulingQuantum = 1000) + + hosts.forEach { compute.addHost(it) } + + val scheduler = WorkflowService( + coroutineContext, + clock, + meterProvider.get("opendc-workflow"), + compute.newClient(), + mode = WorkflowSchedulerMode.Batch(100), + jobAdmissionPolicy = NullJobAdmissionPolicy, + jobOrderPolicy = SubmissionTimeJobOrderPolicy(), + taskEligibilityPolicy = NullTaskEligibilityPolicy, + taskOrderPolicy = SubmissionTimeTaskOrderPolicy(), + ) + + val trace = GwfTraceFormat().open(checkNotNull(WorkflowServiceTest::class.java.getResource("/trace.gwf"))) + val replayer = TraceReplayer(trace) + + replayer.replay(clock, scheduler) + + hosts.forEach(SimHost::close) + scheduler.close() + compute.close() + + val metrics = collectMetrics(meterProvider as MetricProducer) + + assertAll( + { assertEquals(758, metrics.jobsSubmitted, "No jobs submitted") }, + { assertEquals(0, metrics.jobsActive, "Not all submitted jobs started") }, + { assertEquals(metrics.jobsSubmitted, metrics.jobsFinished, "Not all started jobs finished") }, + { assertEquals(0, metrics.tasksActive, "Not all started tasks finished") }, + { assertEquals(metrics.tasksSubmitted, metrics.tasksFinished, "Not all started tasks finished") }, + { assertEquals(33213237L, clock.millis()) } + ) + } + + /** + * The machine model based on: https://www.spec.org/power_ssj2008/results/res2020q1/power_ssj2008-20191125-01012.html + */ + private fun createMachineModel(): MachineModel { + val node = ProcessingNode("AMD", "am64", "EPYC 7742", 32) + val cpus = List(node.coreCount) { id -> ProcessingUnit(node, id, 3400.0) } + val memory = List(8) { MemoryUnit("Samsung", "Unknown", 2933.0, 16_000) } + + return MachineModel(cpus, memory) + } + + class WorkflowMetrics { + var jobsSubmitted = 0L + var jobsActive = 0L + var jobsFinished = 0L + var tasksSubmitted = 0L + var tasksActive = 0L + var tasksFinished = 0L + } + + /** + * Collect the metrics of the workflow service. + */ + private fun collectMetrics(metricProducer: MetricProducer): WorkflowMetrics { + val metrics = metricProducer.collectAllMetrics().associateBy { it.name } + val res = WorkflowMetrics() + res.jobsSubmitted = metrics["jobs.submitted"]?.longSumData?.points?.last()?.value ?: 0 + res.jobsActive = metrics["jobs.active"]?.longSumData?.points?.last()?.value ?: 0 + res.jobsFinished = metrics["jobs.finished"]?.longSumData?.points?.last()?.value ?: 0 + res.tasksSubmitted = metrics["tasks.submitted"]?.longSumData?.points?.last()?.value ?: 0 + res.tasksActive = metrics["tasks.active"]?.longSumData?.points?.last()?.value ?: 0 + res.tasksFinished = metrics["tasks.finished"]?.longSumData?.points?.last()?.value ?: 0 + return res + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 36c1d9e0..e941356e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -47,6 +47,7 @@ include(":opendc-simulator:opendc-simulator-failures") include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") include(":opendc-trace:opendc-trace-api") +include(":opendc-trace:opendc-trace-gwf") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") include(":opendc-harness:opendc-harness-cli") -- cgit v1.2.3 From e8cdfbcec3f75b3f303ce52bac5f5595a94555e4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 15:14:46 +0200 Subject: refactor(trace): Extract Parquet helpers into separate module This change extracts the Parquet helpers outside format module into a new module, in order to improve re-usability of these helpers. --- .../opendc-experiments-capelin/build.gradle.kts | 1 + .../telemetry/parquet/ParquetEventWriter.kt | 2 +- .../capelin/trace/RawParquetTraceReader.kt | 2 +- .../capelin/trace/StreamingParquetTraceReader.kt | 2 +- .../experiments/capelin/trace/TraceConverter.kt | 2 +- opendc-format/build.gradle.kts | 24 +--- .../org/opendc/format/trace/wtf/WtfTraceReader.kt | 2 +- .../org/opendc/format/util/LocalInputFile.kt | 107 ------------------ .../org/opendc/format/util/LocalOutputFile.kt | 95 ---------------- .../org/opendc/format/util/LocalParquetReader.kt | 112 ------------------ .../kotlin/org/opendc/format/util/ParquetTest.kt | 125 --------------------- opendc-trace/opendc-trace-parquet/build.gradle.kts | 60 ++++++++++ .../opendc/trace/util/parquet/LocalInputFile.kt | 107 ++++++++++++++++++ .../opendc/trace/util/parquet/LocalOutputFile.kt | 95 ++++++++++++++++ .../trace/util/parquet/LocalParquetReader.kt | 112 ++++++++++++++++++ .../org/opendc/trace/util/parquet/ParquetTest.kt | 125 +++++++++++++++++++++ settings.gradle.kts | 1 + 17 files changed, 507 insertions(+), 467 deletions(-) delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/util/LocalInputFile.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/util/LocalOutputFile.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/util/LocalParquetReader.kt delete mode 100644 opendc-format/src/test/kotlin/org/opendc/format/util/ParquetTest.kt create mode 100644 opendc-trace/opendc-trace-parquet/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalInputFile.kt create mode 100644 opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalOutputFile.kt create mode 100644 opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalParquetReader.kt create mode 100644 opendc-trace/opendc-trace-parquet/src/test/kotlin/org/opendc/trace/util/parquet/ParquetTest.kt diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 53643aba..e597c5ad 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -32,6 +32,7 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcHarness.opendcHarnessApi) implementation(projects.opendcFormat) + implementation(projects.opendcTrace.opendcTraceParquet) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcSimulator.opendcSimulatorFailures) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt index d8f7ff75..897a6692 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt @@ -28,7 +28,7 @@ import org.apache.avro.generic.GenericData import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.experiments.capelin.telemetry.Event -import org.opendc.format.util.LocalOutputFile +import org.opendc.trace.util.parquet.LocalOutputFile import java.io.Closeable import java.io.File import java.util.concurrent.ArrayBlockingQueue diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt index 16ad6816..2630784b 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt @@ -25,9 +25,9 @@ package org.opendc.experiments.capelin.trace import org.apache.avro.generic.GenericData import org.opendc.format.trace.TraceEntry import org.opendc.format.trace.TraceReader -import org.opendc.format.util.LocalParquetReader import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.trace.util.parquet.LocalParquetReader import java.io.File import java.util.UUID diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt index 35f4c5b8..9b5d0f47 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt @@ -32,9 +32,9 @@ import org.apache.parquet.filter2.predicate.UserDefinedPredicate import org.apache.parquet.io.api.Binary import org.opendc.format.trace.TraceEntry import org.opendc.format.trace.TraceReader -import org.opendc.format.util.LocalInputFile import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.trace.util.parquet.LocalInputFile import java.io.File import java.io.Serializable import java.util.SortedSet diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt index d7daa35b..e64f997f 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt @@ -37,8 +37,8 @@ import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.format.trace.bitbrains.BitbrainsTraceReader -import org.opendc.format.util.LocalOutputFile import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.trace.util.parquet.LocalOutputFile import java.io.BufferedReader import java.io.File import java.io.FileReader diff --git a/opendc-format/build.gradle.kts b/opendc-format/build.gradle.kts index c1258428..0c7f2a51 100644 --- a/opendc-format/build.gradle.kts +++ b/opendc-format/build.gradle.kts @@ -41,29 +41,7 @@ dependencies { implementation(libs.jackson.dataformat.csv) implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.30") - /* This configuration is necessary for a slim dependency on Apache Parquet */ - implementation(libs.parquet) { - exclude(group = "org.apache.hadoop") - } - runtimeOnly(libs.hadoop.common) { - exclude(group = "org.slf4j", module = "slf4j-log4j12") - exclude(group = "log4j") - exclude(group = "org.apache.hadoop") - exclude(group = "org.apache.curator") - exclude(group = "org.apache.zookeeper") - exclude(group = "org.apache.kerby") - exclude(group = "org.apache.httpcomponents") - exclude(group = "org.apache.htrace") - exclude(group = "commons-cli") - exclude(group = "javax.servlet") - exclude(group = "org.eclipse.jetty") - exclude(group = "com.sun.jersey") - exclude(group = "com.jcraft") - exclude(group = "dnsjava") - } - runtimeOnly(libs.hadoop.mapreduce.client.core) { - isTransitive = false - } + implementation(projects.opendcTrace.opendcTraceParquet) testRuntimeOnly(libs.slf4j.simple) } diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt index dde1b340..e8e72f0e 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt @@ -25,8 +25,8 @@ package org.opendc.format.trace.wtf import org.apache.avro.generic.GenericRecord import org.opendc.format.trace.TraceEntry import org.opendc.format.trace.TraceReader -import org.opendc.format.util.LocalParquetReader import org.opendc.simulator.compute.workload.SimFlopsWorkload +import org.opendc.trace.util.parquet.LocalParquetReader import org.opendc.workflow.api.Job import org.opendc.workflow.api.Task import org.opendc.workflow.api.WORKFLOW_TASK_CORES diff --git a/opendc-format/src/main/kotlin/org/opendc/format/util/LocalInputFile.kt b/opendc-format/src/main/kotlin/org/opendc/format/util/LocalInputFile.kt deleted file mode 100644 index 92319ace..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/util/LocalInputFile.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.util - -import org.apache.parquet.io.InputFile -import org.apache.parquet.io.SeekableInputStream -import java.io.EOFException -import java.io.File -import java.nio.ByteBuffer -import java.nio.channels.FileChannel -import java.nio.file.Path -import java.nio.file.StandardOpenOption - -/** - * An [InputFile] on the local filesystem. - */ -public class LocalInputFile(private val path: Path) : InputFile { - /** - * The [FileChannel] used for accessing the input path. - */ - private val channel = FileChannel.open(path, StandardOpenOption.READ) - - /** - * Construct a [LocalInputFile] for the specified [file]. - */ - public constructor(file: File) : this(file.toPath()) - - override fun getLength(): Long = channel.size() - - override fun newStream(): SeekableInputStream = object : SeekableInputStream() { - override fun read(buf: ByteBuffer): Int { - return channel.read(buf) - } - - override fun read(): Int { - val single = ByteBuffer.allocate(1) - var read: Int - - // ReadableByteChannel#read might read zero bytes so continue until we read at least one byte - do { - read = channel.read(single) - } while (read == 0) - - return if (read == -1) { - read - } else { - single.get(0).toInt() and 0xff - } - } - - override fun getPos(): Long { - return channel.position() - } - - override fun seek(newPos: Long) { - channel.position(newPos) - } - - override fun readFully(bytes: ByteArray) { - readFully(ByteBuffer.wrap(bytes)) - } - - override fun readFully(bytes: ByteArray, start: Int, len: Int) { - readFully(ByteBuffer.wrap(bytes, start, len)) - } - - override fun readFully(buf: ByteBuffer) { - var remainder = buf.remaining() - while (remainder > 0) { - val read = channel.read(buf) - remainder -= read - - if (read == -1 && remainder > 0) { - throw EOFException() - } - } - } - - override fun close() { - channel.close() - } - - override fun toString(): String = "NioSeekableInputStream" - } - - override fun toString(): String = "LocalInputFile[path=$path]" -} diff --git a/opendc-format/src/main/kotlin/org/opendc/format/util/LocalOutputFile.kt b/opendc-format/src/main/kotlin/org/opendc/format/util/LocalOutputFile.kt deleted file mode 100644 index 657bca5a..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/util/LocalOutputFile.kt +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.util - -import org.apache.parquet.io.OutputFile -import org.apache.parquet.io.PositionOutputStream -import java.io.File -import java.io.OutputStream -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.StandardOpenOption - -/** - * An [OutputFile] on the local filesystem. - */ -public class LocalOutputFile(private val path: Path) : OutputFile { - /** - * Construct a [LocalOutputFile] from the specified [file] - */ - public constructor(file: File) : this(file.toPath()) - - override fun create(blockSizeHint: Long): PositionOutputStream { - val output = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) - return NioPositionOutputStream(output) - } - - override fun createOrOverwrite(blockSizeHint: Long): PositionOutputStream { - val output = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING) - return NioPositionOutputStream(output) - } - - override fun supportsBlockSize(): Boolean = false - - override fun defaultBlockSize(): Long = - throw UnsupportedOperationException("Local filesystem does not have default block size") - - override fun getPath(): String = path.toString() - - /** - * Implementation of [PositionOutputStream] for an [OutputStream]. - */ - private class NioPositionOutputStream(private val output: OutputStream) : PositionOutputStream() { - /** - * The current position in the file. - */ - private var _pos = 0L - - override fun getPos(): Long = _pos - - override fun write(b: Int) { - output.write(b) - _pos++ - } - - override fun write(b: ByteArray) { - output.write(b) - _pos += b.size - } - - override fun write(b: ByteArray, off: Int, len: Int) { - output.write(b, off, len) - _pos += len - } - - override fun flush() { - output.flush() - } - - override fun close() { - output.close() - } - - override fun toString(): String = "NioPositionOutputStream[output=$output]" - } -} diff --git a/opendc-format/src/main/kotlin/org/opendc/format/util/LocalParquetReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/util/LocalParquetReader.kt deleted file mode 100644 index 5083f3e1..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/util/LocalParquetReader.kt +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.util - -import org.apache.parquet.avro.AvroParquetReader -import org.apache.parquet.hadoop.ParquetReader -import org.apache.parquet.io.InputFile -import java.io.File -import java.io.IOException -import java.nio.file.Files -import java.nio.file.Path -import kotlin.io.path.isDirectory - -/** - * A helper class to read Parquet files. - * - * @param path The path to the Parquet file or directory to read. - */ -public class LocalParquetReader(path: Path) : AutoCloseable { - /** - * The input files to process. - */ - private val filesIterator = if (path.isDirectory()) - Files.list(path) - .filter { !it.isDirectory() } - .sorted() - .map { LocalInputFile(it) } - .iterator() - else - listOf(LocalInputFile(path)).iterator() - - /** - * The Parquet reader to use. - */ - private var reader: ParquetReader? = null - - /** - * Construct a [LocalParquetReader] for the specified [file]. - */ - public constructor(file: File) : this(file.toPath()) - - /** - * Read a single entry in the Parquet file. - */ - public fun read(): T? { - return try { - val next = reader?.read() - if (next != null) { - next - } else { - initReader() - - if (reader == null) - null - else - read() - } - } catch (e: InterruptedException) { - throw IOException(e) - } - } - - /** - * Close the Parquet reader. - */ - override fun close() { - reader?.close() - } - - /** - * Initialize the next reader. - */ - private fun initReader() { - reader?.close() - - this.reader = if (filesIterator.hasNext()) { - createReader(filesIterator.next()) - } else { - null - } - } - - /** - * Create a Parquet reader for the specified file. - */ - private fun createReader(input: InputFile): ParquetReader { - return AvroParquetReader - .builder(input) - .disableCompatibility() - .build() - } -} diff --git a/opendc-format/src/test/kotlin/org/opendc/format/util/ParquetTest.kt b/opendc-format/src/test/kotlin/org/opendc/format/util/ParquetTest.kt deleted file mode 100644 index e496dd96..00000000 --- a/opendc-format/src/test/kotlin/org/opendc/format/util/ParquetTest.kt +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.util - -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData -import org.apache.parquet.avro.AvroParquetReader -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetFileWriter -import org.junit.jupiter.api.* -import org.junit.jupiter.api.Assertions.assertEquals -import java.io.File -import java.nio.file.FileAlreadyExistsException -import java.nio.file.NoSuchFileException - -/** - * Test suite for the Parquet helper classes. - */ -internal class ParquetTest { - private val schema = SchemaBuilder - .record("test") - .namespace("org.opendc.format.util") - .fields() - .name("field").type().intType().noDefault() - .endRecord() - - private lateinit var file: File - - /** - * Setup the test - */ - @BeforeEach - fun setUp() { - file = File.createTempFile("opendc", "parquet") - } - - /** - * Tear down the test. - */ - @AfterEach - fun tearDown() { - file.delete() - } - - /** - * Initial test to verify whether the Parquet writer works. - */ - @Test - fun testSmoke() { - val n = 4 - val writer = AvroParquetWriter.builder(LocalOutputFile(file)) - .withSchema(schema) - .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) - .build() - - try { - repeat(n) { i -> - val record = GenericData.Record(schema) - record.put("field", i) - writer.write(record) - } - } finally { - writer.close() - } - - val reader = AvroParquetReader.builder(LocalInputFile(file)) - .build() - - var counter = 0 - try { - while (true) { - val record = reader.read() ?: break - assertEquals(counter++, record.get("field")) - } - } finally { - reader.close() - } - - assertEquals(n, counter) - } - - /** - * Test if overwriting fails if not specified. - */ - @Test - fun testOverwrite() { - assertThrows { - AvroParquetWriter.builder(LocalOutputFile(file)) - .withSchema(schema) - .build() - } - } - - /** - * Test non-existent file. - */ - @Test - fun testNonExistent() { - file.delete() - assertThrows { - AvroParquetReader.builder(LocalInputFile(file)) - .build() - } - } -} diff --git a/opendc-trace/opendc-trace-parquet/build.gradle.kts b/opendc-trace/opendc-trace-parquet/build.gradle.kts new file mode 100644 index 00000000..75378509 --- /dev/null +++ b/opendc-trace/opendc-trace-parquet/build.gradle.kts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Parquet helpers for traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + + /* This configuration is necessary for a slim dependency on Apache Parquet */ + api(libs.parquet) { + exclude(group = "org.apache.hadoop") + } + runtimeOnly(libs.hadoop.common) { + exclude(group = "org.slf4j", module = "slf4j-log4j12") + exclude(group = "log4j") + exclude(group = "org.apache.hadoop") + exclude(group = "org.apache.curator") + exclude(group = "org.apache.zookeeper") + exclude(group = "org.apache.kerby") + exclude(group = "org.apache.httpcomponents") + exclude(group = "org.apache.htrace") + exclude(group = "commons-cli") + exclude(group = "javax.servlet") + exclude(group = "org.eclipse.jetty") + exclude(group = "com.sun.jersey") + exclude(group = "com.jcraft") + exclude(group = "dnsjava") + } + runtimeOnly(libs.hadoop.mapreduce.client.core) { + isTransitive = false + } + + testRuntimeOnly(libs.slf4j.simple) +} diff --git a/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalInputFile.kt b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalInputFile.kt new file mode 100644 index 00000000..fd2e00cd --- /dev/null +++ b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalInputFile.kt @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.util.parquet + +import org.apache.parquet.io.InputFile +import org.apache.parquet.io.SeekableInputStream +import java.io.EOFException +import java.io.File +import java.nio.ByteBuffer +import java.nio.channels.FileChannel +import java.nio.file.Path +import java.nio.file.StandardOpenOption + +/** + * An [InputFile] on the local filesystem. + */ +public class LocalInputFile(private val path: Path) : InputFile { + /** + * The [FileChannel] used for accessing the input path. + */ + private val channel = FileChannel.open(path, StandardOpenOption.READ) + + /** + * Construct a [LocalInputFile] for the specified [file]. + */ + public constructor(file: File) : this(file.toPath()) + + override fun getLength(): Long = channel.size() + + override fun newStream(): SeekableInputStream = object : SeekableInputStream() { + override fun read(buf: ByteBuffer): Int { + return channel.read(buf) + } + + override fun read(): Int { + val single = ByteBuffer.allocate(1) + var read: Int + + // ReadableByteChannel#read might read zero bytes so continue until we read at least one byte + do { + read = channel.read(single) + } while (read == 0) + + return if (read == -1) { + read + } else { + single.get(0).toInt() and 0xff + } + } + + override fun getPos(): Long { + return channel.position() + } + + override fun seek(newPos: Long) { + channel.position(newPos) + } + + override fun readFully(bytes: ByteArray) { + readFully(ByteBuffer.wrap(bytes)) + } + + override fun readFully(bytes: ByteArray, start: Int, len: Int) { + readFully(ByteBuffer.wrap(bytes, start, len)) + } + + override fun readFully(buf: ByteBuffer) { + var remainder = buf.remaining() + while (remainder > 0) { + val read = channel.read(buf) + remainder -= read + + if (read == -1 && remainder > 0) { + throw EOFException() + } + } + } + + override fun close() { + channel.close() + } + + override fun toString(): String = "NioSeekableInputStream" + } + + override fun toString(): String = "LocalInputFile[path=$path]" +} diff --git a/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalOutputFile.kt b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalOutputFile.kt new file mode 100644 index 00000000..1b17ae5d --- /dev/null +++ b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalOutputFile.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.util.parquet + +import org.apache.parquet.io.OutputFile +import org.apache.parquet.io.PositionOutputStream +import java.io.File +import java.io.OutputStream +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardOpenOption + +/** + * An [OutputFile] on the local filesystem. + */ +public class LocalOutputFile(private val path: Path) : OutputFile { + /** + * Construct a [LocalOutputFile] from the specified [file] + */ + public constructor(file: File) : this(file.toPath()) + + override fun create(blockSizeHint: Long): PositionOutputStream { + val output = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) + return NioPositionOutputStream(output) + } + + override fun createOrOverwrite(blockSizeHint: Long): PositionOutputStream { + val output = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING) + return NioPositionOutputStream(output) + } + + override fun supportsBlockSize(): Boolean = false + + override fun defaultBlockSize(): Long = + throw UnsupportedOperationException("Local filesystem does not have default block size") + + override fun getPath(): String = path.toString() + + /** + * Implementation of [PositionOutputStream] for an [OutputStream]. + */ + private class NioPositionOutputStream(private val output: OutputStream) : PositionOutputStream() { + /** + * The current position in the file. + */ + private var _pos = 0L + + override fun getPos(): Long = _pos + + override fun write(b: Int) { + output.write(b) + _pos++ + } + + override fun write(b: ByteArray) { + output.write(b) + _pos += b.size + } + + override fun write(b: ByteArray, off: Int, len: Int) { + output.write(b, off, len) + _pos += len + } + + override fun flush() { + output.flush() + } + + override fun close() { + output.close() + } + + override fun toString(): String = "NioPositionOutputStream[output=$output]" + } +} diff --git a/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalParquetReader.kt b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalParquetReader.kt new file mode 100644 index 00000000..ef9eaeb3 --- /dev/null +++ b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/LocalParquetReader.kt @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.util.parquet + +import org.apache.parquet.avro.AvroParquetReader +import org.apache.parquet.hadoop.ParquetReader +import org.apache.parquet.io.InputFile +import java.io.File +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Path +import kotlin.io.path.isDirectory + +/** + * A helper class to read Parquet files. + * + * @param path The path to the Parquet file or directory to read. + */ +public class LocalParquetReader(path: Path) : AutoCloseable { + /** + * The input files to process. + */ + private val filesIterator = if (path.isDirectory()) + Files.list(path) + .filter { !it.isDirectory() } + .sorted() + .map { LocalInputFile(it) } + .iterator() + else + listOf(LocalInputFile(path)).iterator() + + /** + * The Parquet reader to use. + */ + private var reader: ParquetReader? = null + + /** + * Construct a [LocalParquetReader] for the specified [file]. + */ + public constructor(file: File) : this(file.toPath()) + + /** + * Read a single entry in the Parquet file. + */ + public fun read(): T? { + return try { + val next = reader?.read() + if (next != null) { + next + } else { + initReader() + + if (reader == null) + null + else + read() + } + } catch (e: InterruptedException) { + throw IOException(e) + } + } + + /** + * Close the Parquet reader. + */ + override fun close() { + reader?.close() + } + + /** + * Initialize the next reader. + */ + private fun initReader() { + reader?.close() + + this.reader = if (filesIterator.hasNext()) { + createReader(filesIterator.next()) + } else { + null + } + } + + /** + * Create a Parquet reader for the specified file. + */ + private fun createReader(input: InputFile): ParquetReader { + return AvroParquetReader + .builder(input) + .disableCompatibility() + .build() + } +} diff --git a/opendc-trace/opendc-trace-parquet/src/test/kotlin/org/opendc/trace/util/parquet/ParquetTest.kt b/opendc-trace/opendc-trace-parquet/src/test/kotlin/org/opendc/trace/util/parquet/ParquetTest.kt new file mode 100644 index 00000000..8ef4d1fb --- /dev/null +++ b/opendc-trace/opendc-trace-parquet/src/test/kotlin/org/opendc/trace/util/parquet/ParquetTest.kt @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.util.parquet + +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericData +import org.apache.parquet.avro.AvroParquetReader +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetFileWriter +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.assertEquals +import java.io.File +import java.nio.file.FileAlreadyExistsException +import java.nio.file.NoSuchFileException + +/** + * Test suite for the Parquet helper classes. + */ +internal class ParquetTest { + private val schema = SchemaBuilder + .record("test") + .namespace("org.opendc.format.util") + .fields() + .name("field").type().intType().noDefault() + .endRecord() + + private lateinit var file: File + + /** + * Setup the test + */ + @BeforeEach + fun setUp() { + file = File.createTempFile("opendc", "parquet") + } + + /** + * Tear down the test. + */ + @AfterEach + fun tearDown() { + file.delete() + } + + /** + * Initial test to verify whether the Parquet writer works. + */ + @Test + fun testSmoke() { + val n = 4 + val writer = AvroParquetWriter.builder(LocalOutputFile(file)) + .withSchema(schema) + .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) + .build() + + try { + repeat(n) { i -> + val record = GenericData.Record(schema) + record.put("field", i) + writer.write(record) + } + } finally { + writer.close() + } + + val reader = AvroParquetReader.builder(LocalInputFile(file)) + .build() + + var counter = 0 + try { + while (true) { + val record = reader.read() ?: break + assertEquals(counter++, record.get("field")) + } + } finally { + reader.close() + } + + assertEquals(n, counter) + } + + /** + * Test if overwriting fails if not specified. + */ + @Test + fun testOverwrite() { + assertThrows { + AvroParquetWriter.builder(LocalOutputFile(file)) + .withSchema(schema) + .build() + } + } + + /** + * Test non-existent file. + */ + @Test + fun testNonExistent() { + file.delete() + assertThrows { + AvroParquetReader.builder(LocalInputFile(file)) + .build() + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index e941356e..ec697d80 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") include(":opendc-trace:opendc-trace-api") include(":opendc-trace:opendc-trace-gwf") +include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") include(":opendc-harness:opendc-harness-cli") -- cgit v1.2.3 From 9fcce6ade8714f7f0a9073fe5b7ddd3f0b35c375 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 15:44:47 +0200 Subject: refactor(format): Remove environment reader from format library This change removes the environment reader from the format library since they are highly specific for the particular experiment. In the future, we hope to have a single format to setup the entire datacenter (perhaps similar to the format used by the web runner). --- .../experiments/capelin/ExperimentHelpers.kt | 2 +- .../capelin/env/ClusterEnvironmentReader.kt | 2 - .../experiments/capelin/env/EnvironmentReader.kt | 35 +++++++++ .../opendc/experiments/capelin/env/MachineDef.kt | 38 +++++++++ .../capelin/trace/StreamingParquetTraceReader.kt | 2 +- .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../opendc-experiments-tf20/build.gradle.kts | 5 +- .../experiments/tf20/TensorFlowExperiment.kt | 3 +- .../experiments/tf20/util/MLEnvironmentReader.kt | 17 ++--- .../org/opendc/experiments/tf20/util/MachineDef.kt | 38 +++++++++ .../opendc/format/environment/EnvironmentReader.kt | 35 --------- .../org/opendc/format/environment/MachineDef.kt | 35 --------- .../org/opendc/format/environment/sc18/Model.kt | 66 ---------------- .../environment/sc18/Sc18EnvironmentReader.kt | 89 ---------------------- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 4 +- 15 files changed, 130 insertions(+), 243 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt create mode 100644 opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/environment/EnvironmentReader.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Model.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 7f428b2a..20dd603f 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -45,9 +45,9 @@ import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher import org.opendc.compute.service.scheduler.weights.RamWeigher import org.opendc.compute.service.scheduler.weights.VCpuWeigher import org.opendc.compute.simulator.SimHost +import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.monitor.ExperimentMetricExporter import org.opendc.experiments.capelin.monitor.ExperimentMonitor -import org.opendc.format.environment.EnvironmentReader import org.opendc.format.trace.TraceReader import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt index d73d14f5..babd8ada 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt @@ -22,8 +22,6 @@ package org.opendc.experiments.capelin.env -import org.opendc.format.environment.EnvironmentReader -import org.opendc.format.environment.MachineDef import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt new file mode 100644 index 00000000..a968b043 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.env + +import java.io.Closeable + +/** + * An interface for reading descriptions of topology environments into memory. + */ +public interface EnvironmentReader : Closeable { + /** + * Read the environment into a list. + */ + public fun read(): List +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt new file mode 100644 index 00000000..b0c0318f --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.env + +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.power.PowerModel +import java.util.* + +/** + * A definition of a machine in a cluster. + */ +public data class MachineDef( + val uid: UUID, + val name: String, + val meta: Map, + val model: MachineModel, + val powerModel: PowerModel +) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt index 9b5d0f47..9bcbdc75 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt @@ -187,7 +187,7 @@ class StreamingParquetTraceReader(traceFile: File, selectedVms: List = e assert(uid !in takenIds) takenIds += uid - logger.info("Processing VM $id") + logger.info { "Processing VM $id" } val internalBuffer = mutableListOf() val externalBuffer = mutableListOf() diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index e4d3fed3..9d6329d1 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -36,12 +36,12 @@ import org.opendc.compute.service.scheduler.filters.RamFilter import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.service.scheduler.weights.CoreRamWeigher import org.opendc.experiments.capelin.env.ClusterEnvironmentReader +import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.monitor.ExperimentMonitor import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader -import org.opendc.format.environment.EnvironmentReader import org.opendc.format.trace.TraceReader import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload diff --git a/opendc-experiments/opendc-experiments-tf20/build.gradle.kts b/opendc-experiments/opendc-experiments-tf20/build.gradle.kts index b088045b..882c4894 100644 --- a/opendc-experiments/opendc-experiments-tf20/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-tf20/build.gradle.kts @@ -34,8 +34,11 @@ dependencies { implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcTelemetry.opendcTelemetrySdk) - implementation(projects.opendcFormat) implementation(projects.opendcUtils) implementation(libs.kotlin.logging) + implementation(libs.jackson.module.kotlin) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") + } + implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.30") } diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/TensorFlowExperiment.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/TensorFlowExperiment.kt index 9a48aced..2153a862 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/TensorFlowExperiment.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/TensorFlowExperiment.kt @@ -55,7 +55,8 @@ public class TensorFlowExperiment : Experiment(name = "tf20") { .build() val meter = meterProvider.get("opendc-tf20") - val def = MLEnvironmentReader(TensorFlowExperiment::class.java.getResourceAsStream(environmentFile)).read().first() + val envInput = checkNotNull(TensorFlowExperiment::class.java.getResourceAsStream(environmentFile)) + val def = MLEnvironmentReader().readEnvironment(envInput).first() val device = SimTFDevice( def.uid, def.meta["gpu"] as Boolean, coroutineContext, clock, meter, def.model.cpus[0], def.model.memory[0], LinearPowerModel(250.0, 60.0) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt index 3e61f508..3cdf28fd 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt @@ -25,8 +25,6 @@ package org.opendc.experiments.tf20.util import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue -import org.opendc.format.environment.EnvironmentReader -import org.opendc.format.environment.MachineDef import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode @@ -36,13 +34,16 @@ import java.io.InputStream import java.util.* /** - * An [EnvironmentReader] for the TensorFlow experiments. + * An environment reader for the TensorFlow experiments. */ -public class MLEnvironmentReader(input: InputStream, mapper: ObjectMapper = jacksonObjectMapper()) : EnvironmentReader { +public class MLEnvironmentReader { + /** + * The [ObjectMapper] to convert the format. + */ + private val mapper = jacksonObjectMapper() - private val setup: Setup = mapper.readValue(input) - - override fun read(): List { + public fun readEnvironment(input: InputStream): List { + val setup: Setup = mapper.readValue(input) var counter = 0 return setup.rooms.flatMap { room -> room.objects.flatMap { roomObject -> @@ -109,6 +110,4 @@ public class MLEnvironmentReader(input: InputStream, mapper: ObjectMapper = jack } } } - - override fun close() {} } diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt new file mode 100644 index 00000000..271f5923 --- /dev/null +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.tf20.util + +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.power.PowerModel +import java.util.* + +/** + * A definition of a machine in a cluster. + */ +public data class MachineDef( + val uid: UUID, + val name: String, + val meta: Map, + val model: MachineModel, + val powerModel: PowerModel +) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/EnvironmentReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/EnvironmentReader.kt deleted file mode 100644 index 97d6f239..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/EnvironmentReader.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.environment - -import java.io.Closeable - -/** - * An interface for reading descriptions of topology environments into memory. - */ -public interface EnvironmentReader : Closeable { - /** - * Read the environment into a list. - */ - public fun read(): List -} diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt deleted file mode 100644 index f65c4880..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.environment - -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.power.PowerModel -import java.util.* - -public data class MachineDef( - val uid: UUID, - val name: String, - val meta: Map, - val model: MachineModel, - val powerModel: PowerModel -) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Model.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Model.kt deleted file mode 100644 index c313467f..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Model.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.environment.sc18 - -import com.fasterxml.jackson.annotation.JsonSubTypes -import com.fasterxml.jackson.annotation.JsonTypeInfo - -/** - * A topology setup. - * - * @property name The name of the setup. - * @property rooms The rooms in the topology. - */ -internal data class Setup(val name: String, val rooms: List) - -/** - * A room in a topology. - * - * @property type The type of room in the topology. - * @property objects The objects in the room. - */ -internal data class Room(val type: String, val objects: List) - -/** - * An object in a [Room]. - * - * @property type The type of the room object. - */ -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") -@JsonSubTypes(value = [JsonSubTypes.Type(name = "RACK", value = RoomObject.Rack::class)]) -internal sealed class RoomObject(val type: String) { - /** - * A rack in a server room. - * - * @property machines The machines in the rack. - */ - internal data class Rack(val machines: List) : RoomObject("RACK") -} - -/** - * A machine in the setup that consists of the specified CPU's represented as - * integer identifiers and ethernet speed. - * - * @property cpus The CPUs in the machine represented as integer identifiers. - */ -internal data class Machine(val cpus: List) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt deleted file mode 100644 index 7780a98e..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.environment.sc18 - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import org.opendc.format.environment.EnvironmentReader -import org.opendc.format.environment.MachineDef -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.compute.power.ConstantPowerModel -import java.io.InputStream -import java.util.* - -/** - * A parser for the JSON experiment setup files used for the SC18 paper: "A Reference Architecture for Topology - * Schedulers". - * - * @param input The input stream to read from. - * @param mapper The Jackson object mapper to use. - */ -public class Sc18EnvironmentReader(input: InputStream, mapper: ObjectMapper = jacksonObjectMapper()) : EnvironmentReader { - /** - * The environment that was read from the file. - */ - private val setup: Setup = mapper.readValue(input) - - /** - * Read the environment. - */ - public override fun read(): List { - var counter = 0 - return setup.rooms.flatMap { room -> - room.objects.flatMap { roomObject -> - when (roomObject) { - is RoomObject.Rack -> { - roomObject.machines.map { machine -> - val cores = machine.cpus.flatMap { id -> - when (id) { - 1 -> { - val node = ProcessingNode("Intel", "Core(TM) i7-6920HQ", "amd64", 4) - List(node.coreCount) { ProcessingUnit(node, it, 4100.0) } - } - 2 -> { - val node = ProcessingNode("Intel", "Core(TM) i7-6920HQ", "amd64", 2) - List(node.coreCount) { ProcessingUnit(node, it, 3500.0) } - } - else -> throw IllegalArgumentException("The cpu id $id is not recognized") - } - } - MachineDef( - UUID(0L, counter++.toLong()), - "node-$counter", - emptyMap(), - MachineModel(cores, listOf(MemoryUnit("", "", 2300.0, 16000))), - ConstantPowerModel(0.0) - ) - } - } - } - } - } - } - - override fun close() {} -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index c5f5cd03..53d50357 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -34,12 +34,12 @@ import kotlinx.coroutines.channels.Channel import mu.KotlinLogging import org.opendc.compute.service.scheduler.weights.* import org.opendc.experiments.capelin.* +import org.opendc.experiments.capelin.env.EnvironmentReader +import org.opendc.experiments.capelin.env.MachineDef import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader -import org.opendc.format.environment.EnvironmentReader -import org.opendc.format.environment.MachineDef import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit -- cgit v1.2.3 From 214480d154771f0b783829b6e5ec82b837304ad2 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 16:18:56 +0200 Subject: refactor(trace): Move Bitbrains format into separate module This change moves Bitbrains trace support into a separate module and adds support for the new trace api. --- .../opendc-experiments-capelin/build.gradle.kts | 1 + .../experiments/capelin/trace/TraceConverter.kt | 84 +- .../trace/bitbrains/BitbrainsRawTraceReader.kt | 100 - .../format/trace/bitbrains/BitbrainsTraceReader.kt | 127 - .../trace/bitbrains/BitbrainsTraceReaderTest.kt | 45 - opendc-format/src/test/resources/bitbrains.csv | 8620 -------------------- .../opendc-trace-bitbrains/build.gradle.kts | 36 + .../trace/bitbrains/BitbrainsResourceStateTable.kt | 139 + .../bitbrains/BitbrainsResourceStateTableReader.kt | 218 + .../org/opendc/trace/bitbrains/BitbrainsTrace.kt | 46 + .../opendc/trace/bitbrains/BitbrainsTraceFormat.kt | 56 + .../services/org.opendc.trace.spi.TraceFormat | 1 + .../trace/bitbrains/BitbrainsTraceFormatTest.kt | 100 + .../src/test/resources/bitbrains.csv | 8620 ++++++++++++++++++++ settings.gradle.kts | 1 + 15 files changed, 9280 insertions(+), 8914 deletions(-) delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt delete mode 100644 opendc-format/src/test/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReaderTest.kt delete mode 100644 opendc-format/src/test/resources/bitbrains.csv create mode 100644 opendc-trace/opendc-trace-bitbrains/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/test/resources/bitbrains.csv diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index e597c5ad..97ca97ec 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { api(projects.opendcHarness.opendcHarnessApi) implementation(projects.opendcFormat) implementation(projects.opendcTrace.opendcTraceParquet) + implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcSimulator.opendcSimulatorFailures) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt index e64f997f..0ded32f3 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt @@ -36,8 +36,8 @@ import org.apache.avro.generic.GenericData import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.format.trace.bitbrains.BitbrainsTraceReader -import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.trace.* +import org.opendc.trace.bitbrains.BitbrainsTraceFormat import org.opendc.trace.util.parquet.LocalOutputFile import java.io.BufferedReader import java.io.File @@ -338,33 +338,73 @@ class BitbrainsConversion : TraceConversion("Bitbrains") { metaWriter: ParquetWriter ): MutableList { val fragments = mutableListOf() - BitbrainsTraceReader(traceDirectory).use { reader -> - reader.forEach { entry -> - val trace = (entry.workload as SimTraceWorkload).trace - var maxTime = Long.MIN_VALUE - trace.forEach { fragment -> - val flops: Long = (fragment.usage * fragment.duration / 1000).toLong() + val trace = BitbrainsTraceFormat().open(traceDirectory.toURI().toURL()) + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + var lastId: String? = null + var maxCores = Int.MIN_VALUE + var requiredMemory = Long.MIN_VALUE + var minTime = Long.MAX_VALUE + var maxTime = Long.MIN_VALUE + var lastTimestamp = Long.MIN_VALUE + + while (reader.nextRow()) { + val id = reader.get(RESOURCE_STATE_ID) + + if (lastId != null && lastId != id) { + val metaRecord = GenericData.Record(metaSchema) + metaRecord.put("id", lastId) + metaRecord.put("submissionTime", minTime) + metaRecord.put("endTime", maxTime) + metaRecord.put("maxCores", maxCores) + metaRecord.put("requiredMemory", requiredMemory) + metaWriter.write(metaRecord) + } + lastId = id + + val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP) + val timestampMs = timestamp.toEpochMilli() + val cpuUsage = reader.getDouble(RESOURCE_STATE_MEM_USAGE) + val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val memCapacity = reader.getDouble(RESOURCE_STATE_MEM_CAPACITY) + + maxCores = max(maxCores, cores) + requiredMemory = max(requiredMemory, (memCapacity / 1000).toLong()) + + if (lastTimestamp < 0) { + lastTimestamp = timestampMs - 5 * 60 * 1000L + minTime = min(minTime, lastTimestamp) + } + + if (fragments.isEmpty()) { + val duration = 5 * 60 * 1000L + val flops: Long = (cpuUsage * duration / 1000).toLong() + fragments.add(Fragment(id, lastTimestamp, flops, duration, cpuUsage, cores)) + } else { + val last = fragments.last() + val duration = timestampMs - lastTimestamp + val flops: Long = (cpuUsage * duration / 1000).toLong() + + // Perform run-length encoding + if (last.id == id && (duration == 0L || last.usage == cpuUsage)) { + fragments[fragments.size - 1] = last.copy(duration = last.duration + duration) + } else { fragments.add( Fragment( - entry.name, - fragment.timestamp, + id, + lastTimestamp, flops, - fragment.duration, - fragment.usage, - fragment.cores + duration, + cpuUsage, + cores ) ) - maxTime = max(maxTime, fragment.timestamp + fragment.duration) } - - val metaRecord = GenericData.Record(metaSchema) - metaRecord.put("id", entry.name) - metaRecord.put("submissionTime", entry.start) - metaRecord.put("endTime", maxTime) - metaRecord.put("maxCores", entry.meta["cores"]) - metaRecord.put("requiredMemory", entry.meta["required-memory"]) - metaWriter.write(metaRecord) } + + val last = fragments.last() + maxTime = max(maxTime, last.tick + last.duration) + lastTimestamp = timestampMs } return fragments } diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt deleted file mode 100644 index ff6cdd02..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsRawTraceReader.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.bitbrains - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.MappingIterator -import com.fasterxml.jackson.dataformat.csv.CsvMapper -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import java.io.InputStream - -/** - * A trace reader that enables the user to read Bitbrains specific trace data. - */ -public class BitbrainsRawTraceReader(input: InputStream) : Iterator, AutoCloseable { - /** - * The [CsvSchema] that is used to parse the trace. - */ - private val schema = CsvSchema.builder() - .addColumn("Timestamp [ms]", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU cores", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU capacity provisioned [MHZ]", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU usage [MHZ]", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU usage [%]", CsvSchema.ColumnType.NUMBER) - .addColumn("Memory capacity provisioned [KB]", CsvSchema.ColumnType.NUMBER) - .addColumn("Memory usage [KB]", CsvSchema.ColumnType.NUMBER) - .addColumn("Disk read throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .addColumn("Disk write throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .addColumn("Network received throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .addColumn("Network transmitted throughput [KB/s]", CsvSchema.ColumnType.NUMBER) - .setAllowComments(true) - .setUseHeader(true) - .setColumnSeparator(';') - .build() - - /** - * The mapping iterator to use. - */ - private val iterator: MappingIterator = CsvMapper().readerFor(Entry::class.java).with(schema) - .readValues(input) - - override fun hasNext(): Boolean { - return iterator.hasNext() - } - - override fun next(): Entry { - return iterator.next() - } - - override fun close() { - iterator.close() - } - - /** - * A single entry in the trace. - */ - public data class Entry( - @JsonProperty("Timestamp [ms]") - val timestamp: Long, - @JsonProperty("CPU cores") - val cpuCores: Int, - @JsonProperty("CPU capacity provisioned [MHZ]") - val cpuCapacity: Double, - @JsonProperty("CPU usage [MHZ]") - val cpuUsage: Double, - @JsonProperty("CPU usage [%]") - val cpuUsagePct: Double, - @JsonProperty("Memory capacity provisioned [KB]") - val memCapacity: Double, - @JsonProperty("Memory usage [KB]") - val memUsage: Double, - @JsonProperty("Disk read throughput [KB/s]") - val diskRead: Double, - @JsonProperty("Disk write throughput [KB/s]") - val diskWrite: Double, - @JsonProperty("Network received throughput [KB/s]") - val netReceived: Double, - @JsonProperty("Network transmitted throughput [KB/s]") - val netTransmitted: Double - ) -} diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt deleted file mode 100644 index 9e4876df..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReader.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.bitbrains - -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import java.io.File -import java.io.FileInputStream -import java.util.* -import kotlin.math.max -import kotlin.math.min - -/** - * A [TraceReader] for the public VM workload trace format. - * - * @param traceDirectory The directory of the traces. - */ -public class BitbrainsTraceReader(traceDirectory: File) : TraceReader { - /** - * The internal iterator to use for this reader. - */ - private val iterator: Iterator> - - /** - * Initialize the reader. - */ - init { - val entries = mutableMapOf>() - val traceInterval = 5 * 60 * 1000L - - traceDirectory.walk() - .filterNot { it.isDirectory } - .filter { it.extension == "csv" } - .forEach { vmFile -> - val flopsHistory = mutableListOf() - var vmId = -1L - var maxCores = Int.MIN_VALUE - var requiredMemory = Long.MIN_VALUE - var startTime = Long.MAX_VALUE - var lastTimestamp = Long.MIN_VALUE - - BitbrainsRawTraceReader(FileInputStream(vmFile)).use { reader -> - reader.forEach { entry -> - val timestamp = entry.timestamp * 1000L - val cpuUsage = entry.cpuUsage - vmId = vmFile.nameWithoutExtension.trim().toLong() - val cores = entry.cpuCores - maxCores = max(maxCores, cores) - requiredMemory = max(requiredMemory, (entry.memCapacity / 1000).toLong()) - - if (lastTimestamp < 0) { - lastTimestamp = timestamp - 5 * 60 * 1000L - startTime = min(startTime, lastTimestamp) - } - - if (flopsHistory.isEmpty()) { - flopsHistory.add(SimTraceWorkload.Fragment(lastTimestamp, traceInterval, cpuUsage, cores)) - } else { - val last = flopsHistory.last() - val duration = timestamp - lastTimestamp - // Perform run-length encoding - if (duration == 0L || last.usage == cpuUsage) { - flopsHistory[flopsHistory.size - 1] = last.copy(duration = last.duration + duration) - } else { - flopsHistory.add( - SimTraceWorkload.Fragment( - lastTimestamp, - duration, - cpuUsage, - cores - ) - ) - } - } - - lastTimestamp = timestamp - } - } - - val uuid = UUID(0L, vmId) - - val workload = SimTraceWorkload(flopsHistory.asSequence()) - entries[vmId] = TraceEntry( - uuid, - vmId.toString(), - startTime, - workload, - mapOf( - "cores" to maxCores, - "required-memory" to requiredMemory, - "workload" to workload - ) - ) - } - - // Create the entry iterator - iterator = entries.values.sortedBy { it.start }.iterator() - } - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() {} -} diff --git a/opendc-format/src/test/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReaderTest.kt b/opendc-format/src/test/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReaderTest.kt deleted file mode 100644 index 48b4a2e3..00000000 --- a/opendc-format/src/test/kotlin/org/opendc/format/trace/bitbrains/BitbrainsTraceReaderTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.bitbrains - -import org.junit.jupiter.api.Assertions.assertAll -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test - -/** - * Test suite for the [BitbrainsTraceReader] class. - */ -class BitbrainsTraceReaderTest { - @Test - fun testSmoke() { - val file = BitbrainsTraceReaderTest::class.java.getResourceAsStream("/bitbrains.csv")!! - BitbrainsRawTraceReader(file).use { reader -> - val entry = reader.next() - - assertAll( - { assertEquals(1376314846, entry.timestamp) }, - { assertEquals(19.066, entry.cpuUsage, 0.01) } - ) - } - } -} diff --git a/opendc-format/src/test/resources/bitbrains.csv b/opendc-format/src/test/resources/bitbrains.csv deleted file mode 100644 index f5e300e8..00000000 --- a/opendc-format/src/test/resources/bitbrains.csv +++ /dev/null @@ -1,8620 +0,0 @@ -Timestamp [ms]; CPU cores; CPU capacity provisioned [MHZ]; CPU usage [MHZ]; CPU usage [%]; Memory capacity provisioned [KB]; Memory usage [KB]; Disk read throughput [KB/s]; Disk write throughput [KB/s]; Network received throughput [KB/s]; Network transmitted throughput [KB/s] -1376314846; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 -1376315146; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376315446; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376315746; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376316046; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376316346; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 -1376316646; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 128624.26666666666; 0.06666666666666667; 8.733333333333333; 0.3333333333333333; 0.6 -1376316946; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 134216.8; 0.0; 1.2; 0.0; 0.0 -1376317246; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1376317546; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.5333333333333334; 0.0; 0.0 -1376317846; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376318146; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.06666666666666667; 1.6; 0.06666666666666667; 0.13333333333333333 -1376318446; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376318746; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1376319046; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 -1376319346; 1; 2599.999626; 38.99999439; 1.5; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1376319646; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1376319946; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1376320246; 1; 2599.999626; 41.599994016000004; 1.6; 2097152.0; 150993.6; 0.0; 2.7333333333333334; 67.46666666666667; 0.5333333333333333 -1376320546; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376320846; 1; 2599.999626; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376321146; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 1.0; 0.06666666666666667; 0.0 -1376321446; 1; 2599.999626; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376321746; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376322046; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376322346; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.6; 0.0 -1376322647; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376322947; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376323247; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 117439.2; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1376323547; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 -1376323847; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 146800.0; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 -1376324147; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.2; 1.5333333333333334; 0.0; 0.0 -1376324447; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.5333333333333334; 0.0; 0.0 -1376324747; 1; 2599.999626; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376325047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376325347; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1376325647; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.2; 0.0; 0.0 -1376325947; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376326247; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1376326547; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1376326847; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376327147; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376327447; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 198527.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376327747; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376328047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376328347; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376328647; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 -1376328947; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376329247; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 -1376329547; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 -1376329847; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376330147; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 125828.0; 0.2; 7.466666666666667; 0.2; 0.13333333333333333 -1376330447; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1376330747; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 155188.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376331047; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 167771.2; 0.0; 2.466666666666667; 0.3333333333333333; 0.4666666666666667 -1376331347; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 132817.6; 0.0; 1.6666666666666667; 0.0; 0.0 -1376331647; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376331947; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376332247; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376332547; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376332847; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.6; 0.0; 0.0 -1376333147; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376333447; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1376333747; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376334047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1376334347; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1376334647; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 170565.86666666667; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 -1376334947; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 128624.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376335247; 1; 2599.999626; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 -1376335547; 1; 2599.999626; 46.799993268; 1.8; 2097152.0; 341134.4; 161.73333333333332; 14.666666666666666; 0.0; 0.2 -1376335847; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 216702.93333333332; 0.0; 7.733333333333333; 0.26666666666666666; 0.13333333333333333 -1376336147; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 160780.53333333333; 31.8; 3.8666666666666667; 0.0; 0.0 -1376336447; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 1.3333333333333333; 0.26666666666666666; 0.0 -1376336747; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376337047; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 -1376337347; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 -1376337647; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376337947; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.0; 0.0 -1376338248; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 205518.66666666666; 0.0; 3.066666666666667; 0.0; 0.4666666666666667 -1376338548; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 138410.93333333332; 0.06666666666666667; 1.5333333333333334; 0.0; 0.0 -1376338848; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376339148; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376339448; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376339748; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376340048; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.2; 0.0; 0.0 -1376340348; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.6666666666666666; 0.0 -1376340648; 1; 2599.999626; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376340948; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1376341248; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376341548; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 -1376341848; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 127225.33333333333; 0.2; 2.6666666666666665; 0.0; 0.4666666666666667 -1376342148; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.2; 0.06666666666666667; 0.0 -1376342448; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 -1376342748; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 -1376343048; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1376343348; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.13333333333333333; 0.0 -1376343648; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.3333333333333333; 0.0 -1376343948; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 149594.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1376344248; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 1.1333333333333333; 0.6; 0.0 -1376344548; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376344848; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376345148; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1376345448; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 162177.86666666667; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 -1376345748; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1376346048; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 -1376346348; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376346648; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 74097.06666666667; 2.6666666666666665; 1.4666666666666666; 0.13333333333333333; 0.0 -1376346948; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 -1376347248; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 -1376347548; 1; 2599.999626; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376347848; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1376348148; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 7.466666666666667; 0.26666666666666666; 0.2 -1376348448; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1376348749; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376349049; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376349349; 1; 2599.999626; 41.599994016000004; 1.6; 2097152.0; 187343.73333333334; 161.0; 21.6; 0.06666666666666667; 0.4 -1376349649; 1; 2599.999626; 22.533330092; 0.8666666666666667; 2097152.0; 577414.1333333333; 0.0; 2.466666666666667; 0.0; 0.0 -1376349949; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 234878.4; 31.8; 3.6666666666666665; 0.0; 0.0 -1376350249; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 178954.4; 0.8; 2.466666666666667; 0.0; 0.06666666666666667 -1376350549; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 1.7333333333333334; 0.0; 0.0 -1376350849; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376351149; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.06666666666666667; 0.0 -1376351449; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376351749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376352049; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 1.4666666666666666; 1.6666666666666667; 0.0; 0.0 -1376352349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376352649; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 178954.13333333333; 3.8666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 -1376352949; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 141206.4; 0.0; 1.0; 0.0; 0.0 -1376353249; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376353549; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1376353849; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.6; 12.4; 0.0; 0.0 -1376354149; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 192936.0; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.13333333333333333 -1376354449; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 130022.4; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 -1376354749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.4; 0.0; 0.0 -1376355049; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376355349; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 -1376355649; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1376355949; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376356249; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 138410.66666666666; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 -1376356549; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 121633.33333333333; 0.0; 2.066666666666667; 0.0; 0.0 -1376356849; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.2; 0.06666666666666667; 0.0 -1376357149; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1376357449; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376357749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1376358049; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1376358349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1376358649; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 -1376358949; 1; 2599.999626; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 1.4666666666666666; 0.0; 0.0 -1376359250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376359550; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 138411.2; 0.0; 7.4; 0.2; 0.13333333333333333 -1376359850; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 160780.53333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1376360150; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376360450; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1376360750; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376361050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.06666666666666667; 0.0 -1376361350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 -1376361650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.4; 0.06666666666666667; 0.0 -1376361950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.4666666666666666; 0.0; 0.0 -1376362250; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376362550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376362849; 1; 2599.999626; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 -1376363149; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1376363449; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 169168.53333333333; 0.06666666666666667; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 -1376363749; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 -1376364049; 1; 2599.999626; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1376364349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 -1376364650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 135614.66666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1376364950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376365250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 -1376365550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 -1376365850; 1; 2599.999626; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1376366150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.4666666666666666; 0.0; 0.0 -1376366450; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.06666666666666667; 7.466666666666667; 0.2; 0.13333333333333333 -1376366750; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1376367050; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 2.6; 0.4; 0.5333333333333333 -1376367350; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 139809.33333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376367650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376367950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 -1376368250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376368550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376368850; 1; 2599.999626; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 1.6; 0.0; 0.0 -1376369150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376369450; 1; 2599.999626; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.26666666666666666; 0.0 -1376369750; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376370050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 58717.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1376370350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1376370650; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 142604.0; 0.06666666666666667; 3.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376370950; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.6666666666666666; 0.0 -1376371250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.2; 0.0 -1376371550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376371850; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 167770.13333333333; 0.0; 7.066666666666666; 0.3333333333333333; 0.13333333333333333 -1376372150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 1.2; 0.0; 0.0 -1376372450; 1; 2599.999626; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376372750; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.4; 0.0; 0.0 -1376373050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.5333333333333334; 0.0; 0.0 -1376373350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376373651; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 -1376373951; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376374251; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 163575.46666666667; 0.06666666666666667; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376374551; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 128623.73333333334; 0.0; 1.2; 0.0; 0.0 -1376374851; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376375151; 1; 2599.999626; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376375451; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376375751; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 3.0; 0.13333333333333333; 0.13333333333333333 -1376376051; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 2.066666666666667; 0.06666666666666667; 0.0 -1376376351; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376376651; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 127225.33333333333; 0.0; 1.2; 0.0; 0.0 -1376376951; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 -1376377251; 1; 2599.999626; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1376377551; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376377851; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 180353.6; 0.6; 2.6666666666666665; 0.13333333333333333; 0.4666666666666667 -1376378151; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1376378451; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 116041.06666666667; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 -1376378751; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376379051; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376379351; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1376379651; 1; 2599.999626; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376379951; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 2.0; 0.0; 0.0 -1376380251; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376380551; 1; 2599.999626; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376380851; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376381151; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376381451; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 144003.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1376381751; 1; 2599.999626; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.2; 0.06666666666666667; 0.0 -1376382051; 1; 2599.999626; 0.0; 0.0; 2097152.0; 138409.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1376382351; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1376382651; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 81087.73333333334; 0.0; 1.4; 0.0; 0.0 -1376382951; 1; 2599.999626; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376383251; 1; 2599.999626; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.0; 0.0 -1376383551; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376383851; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.4; 0.0; 0.0 -1376384151; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376384451; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 -1376384752; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376385052; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1376385352; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376385652; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 95069.06666666667; 0.0; 7.0; 1.0666666666666667; 0.2 -1376385952; 1; 2599.999626; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376386252; 1; 2599.999626; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1376386552; 1; 2599.999626; 0.0; 0.0; 2097152.0; 127225.86666666667; 0.0; 1.2; 0.0; 0.0 -1376386852; 1; 2599.999626; 0.0; 0.0; 2097152.0; 132818.4; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376387152; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1376387452; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.2; 0.0 -1376387752; 1; 2599.999626; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 -1376388052; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376388352; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376388652; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 169168.26666666666; 0.0; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 -1376388952; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.2; 0.0; 0.0 -1376389252; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376389552; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.4; 0.0; 0.0 -1376389852; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376390152; 1; 2599.999626; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376390452; 1; 2599.999626; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376390752; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.4666666666666666; 0.0; 0.0 -1376391052; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376391352; 1; 2599.999626; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376391652; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376391952; 1; 2599.999626; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 -1376392252; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 191537.33333333334; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376392552; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 163576.0; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1376392853; 1; 2599.999626; 0.0; 0.0; 2097152.0; 138409.6; 0.0; 1.2; 0.13333333333333333; 0.0 -1376393153; 1; 2599.999602; 38.999994029999996; 1.5; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1376393453; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 109049.6; 0.0; 1.5333333333333334; 0.0; 0.0 -1376393753; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376394053; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1376394353; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 111846.66666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1376394653; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376394953; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 60115.73333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376395253; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 -1376395552; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1376395852; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1376396152; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 103457.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1376396452; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1376396752; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 -1376397052; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1376397352; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376397652; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 97865.33333333333; 0.0; 12.533333333333333; 0.0; 0.0 -1376397952; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1376398252; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376398552; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1376398853; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 7.2; 7.2; 0.13333333333333333 -1376399153; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 1.4; 0.0; 0.0 -1376399453; 1; 2599.999602; 22.533329884; 0.8666666666666667; 2097152.0; 178955.46666666667; 0.0; 2.6666666666666665; 0.06666666666666667; 0.5333333333333333 -1376399753; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1376400053; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376400353; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 74097.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1376400653; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 92272.8; 0.0; 1.6666666666666667; 0.0; 0.0 -1376400953; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 2.0; 0.0; 0.0 -1376401253; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 69902.66666666667; 0.0; 1.2; 0.0; 0.0 -1376401553; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1376401853; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 130022.4; 0.0; 1.4; 0.0; 0.0 -1376402153; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 -1376402453; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 -1376402753; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376403053; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 113244.8; 0.0; 3.1333333333333333; 0.0; 0.4666666666666667 -1376403353; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1376403653; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376403953; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376404253; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 74097.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 -1376404553; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.13333333333333333 -1376404853; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 -1376405153; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 65708.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1376405453; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1376405753; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 106254.13333333333; 0.0; 7.4; 0.2; 0.13333333333333333 -1376406053; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376406353; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1376406653; 1; 2599.999602; 74.53332192399999; 2.8666666666666667; 2097152.0; 630542.1333333333; 161.13333333333333; 23.266666666666666; 0.06666666666666667; 0.8666666666666667 -1376406954; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 369096.8; 0.3333333333333333; 20.2; 0.0; 0.0 -1376407254; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 237674.93333333332; 31.8; 3.933333333333333; 0.0; 0.0 -1376407554; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 141207.46666666667; 4.266666666666667; 2.533333333333333; 0.06666666666666667; 0.0 -1376407854; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.7333333333333334; 0.0; 0.0 -1376408154; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376408454; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376408754; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.5333333333333334; 0.2; 0.0 -1376409054; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376409354; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376409654; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 -1376409954; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376410254; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 149595.46666666667; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 -1376410554; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 -1376410854; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376411154; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376411454; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 -1376411754; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 100661.6; 12.733333333333333; 13.466666666666667; 0.3333333333333333; 0.2 -1376412054; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.6666666666666667; 0.0; 0.0 -1376412354; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376412654; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 -1376412954; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 -1376413255; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376413555; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376413855; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 138409.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 -1376414155; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 96467.2; 0.0; 1.4666666666666666; 0.0; 0.0 -1376414455; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376414755; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1376415055; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376415355; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376415655; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376415955; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376416255; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376416555; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1376416855; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 82485.86666666667; 1.0666666666666667; 1.9333333333333333; 0.0; 0.0 -1376417155; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.4666666666666666; 0.0; 0.0 -1376417455; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 195732.26666666666; 0.0; 2.4; 0.0; 0.5333333333333333 -1376417755; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376418055; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1376418355; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 -1376418655; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376418955; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376419255; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376419555; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 1.2; 0.0; 0.0 -1376419855; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 64310.13333333333; 0.0; 1.4666666666666666; 0.0; 0.0 -1376420155; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 -1376420455; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.6; 0.0; 0.06666666666666667 -1376420755; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376421055; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 202721.86666666667; 0.0; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 -1376421355; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 100661.6; 0.0; 1.4666666666666666; 0.0; 0.0 -1376421655; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376421955; 1; 2599.999602; 45.066659768; 1.7333333333333334; 2097152.0; 360707.73333333334; 161.73333333333332; 14.466666666666667; 0.0; 0.2 -1376422255; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 282414.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1376422555; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 194334.13333333333; 31.8; 3.8666666666666667; 0.0; 0.0 -1376422856; 1; 2599.999602; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1376423156; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1376423456; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1376423756; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 -1376424056; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1376424356; 1; 2599.999602; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 -1376424656; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 153790.13333333333; 0.06666666666666667; 8.933333333333334; 0.26666666666666666; 0.6 -1376424956; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 -1376425256; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 82485.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376425556; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 -1376425856; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 -1376426156; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 -1376426456; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 83884.0; 0.0; 1.4; 0.0; 0.0 -1376426756; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1376427056; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.0; 0.06666666666666667; 0.0 -1376427356; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376427656; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.06666666666666667; 0.0 -1376427956; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376428256; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 199926.4; 0.06666666666666667; 3.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376428556; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 163576.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1376428856; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1376429156; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1376429456; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 -1376429756; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 1.2; 0.0; 0.0 -1376430056; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1376430356; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1376430656; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1376430956; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.5333333333333334; 0.0; 0.0 -1376431256; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 121633.6; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1376431556; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.2; 0.0; 0.0 -1376431856; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1376432156; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.4; 0.0; 0.0 -1376432456; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 -1376432756; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376433056; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 131419.73333333334; 0.06666666666666667; 2.7333333333333334; 0.0; 0.0 -1376433356; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 137013.06666666668; 0.0; 1.6666666666666667; 0.4666666666666667; 0.13333333333333333 -1376433656; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 -1376433956; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376434256; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 -1376434556; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1376434856; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376435156; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 103457.86666666667; 0.0; 1.6; 0.0; 0.0 -1376435456; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 178955.46666666667; 0.13333333333333333; 3.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376435756; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376436056; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 1.2; 0.0; 0.0 -1376436356; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.4; 0.0; 0.0 -1376436656; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376436956; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376437256; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 -1376437556; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.06666666666666667; 7.8; 0.3333333333333333; 0.13333333333333333 -1376437856; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1376438156; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376438456; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376438756; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 -1376439056; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 197130.4; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376439356; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 1.2; 0.0; 0.0 -1376439656; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376439956; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.2; 0.0 -1376440256; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 67106.4; 0.0; 1.8; 0.0; 0.0 -1376440557; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 69902.66666666667; 0.0; 1.4; 0.0; 0.0 -1376440857; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1376441157; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 12.0; 0.06666666666666667; 0.0 -1376441457; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1376441757; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1376442057; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 134216.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1376442357; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1376442657; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 180353.6; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 -1376442957; 1; 2599.99945; 31.777771055555554; 1.2222222222222223; 2097152.0; 97865.33333333333; 0.0; 0.625; 0.0; 0.0 -1376443257; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 156585.33333333334; 0.0; 7.2; 0.3333333333333333; 0.13333333333333333 -1376443557; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 146800.0; 0.0; 1.2; 0.0; 0.0 -1376443857; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 -1376444157; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 114642.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376444457; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 148197.33333333334; 0.0; 1.2; 0.06666666666666667; 0.0 -1376444757; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 1.4666666666666666; 0.0; 0.0 -1376445057; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1376445357; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376445657; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 96467.2; 0.0; 1.8666666666666667; 10.933333333333334; 0.0 -1376445957; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376446257; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 134216.0; 0.0; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 -1376446557; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376446857; 1; 2599.99945; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1376447157; 1; 2599.99945; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376447457; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 141206.66666666666; 0.0; 1.2; 0.06666666666666667; 0.0 -1376447757; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 153789.6; 0.0; 1.2; 0.13333333333333333; 0.0 -1376448057; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1376448357; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1376448657; 1; 2599.99945; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376448957; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 103457.86666666667; 0.0; 1.6; 0.3333333333333333; 0.0 -1376449257; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 -1376449558; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1376449858; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 152390.93333333332; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1376450158; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 137012.8; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 -1376450458; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1376450758; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376451058; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376451358; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1376451658; 1; 2599.99945; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.6666666666666667; 0.0; 0.0 -1376451958; 1; 2599.99945; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.4; 0.0; 0.0 -1376452258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376452558; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376452858; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376453158; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.4666666666666666; 0.0; 0.0 -1376453458; 1; 2599.99945; 13.866663733333333; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.6; 0.2; 0.4666666666666667 -1376453758; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 104856.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1376454058; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376454358; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 -1376454658; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376454958; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 -1376455258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376455558; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 89476.53333333334; 0.0; 6.933333333333334; 0.3333333333333333; 0.2 -1376455858; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 116041.06666666667; 0.0; 2.1333333333333333; 0.0; 0.0 -1376456158; 1; 2599.99945; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1376456458; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376456758; 1; 2599.99945; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 -1376457058; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 -1376457359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376457659; 1; 2599.99945; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376457959; 1; 2599.99945; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376458259; 1; 2599.99945; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376458559; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.5333333333333334; 0.06666666666666667; 0.0 -1376458859; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376459159; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376459459; 1; 2599.99945; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376459759; 1; 2599.99945; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1376460059; 1; 2599.99945; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.4; 0.0; 0.0 -1376460359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.3333333333333333; 1.6; 0.0 -1376460659; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 150993.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 -1376460959; 1; 2599.99945; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376461258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 -1376461558; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 75495.2; 0.06666666666666667; 6.8; 0.26666666666666666; 0.2 -1376461858; 1; 2599.99945; 124.79997359999999; 4.8; 2097152.0; 524285.86666666664; 161.46666666666667; 170.26666666666668; 20.866666666666667; 1.0666666666666667 -1376462158; 1; 2599.99945; 17.333329666666668; 0.6666666666666667; 2097152.0; 541063.2; 5.066666666666666; 12.2; 0.13333333333333333; 0.06666666666666667 -1376462458; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 243267.2; 31.8; 4.6; 0.06666666666666667; 0.0 -1376462758; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 187343.2; 0.0; 2.8666666666666667; 0.0; 0.0 -1376463059; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 2.066666666666667; 0.0; 0.0 -1376463359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 -1376463659; 1; 2599.99945; 20.7999956; 0.8; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 -1376463959; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376464259; 1; 2599.999602; 28.599995622; 1.1; 2097152.0; 188740.0; 0.0; 1.4444444444444444; 0.1111111111111111; 0.0 -1376464559; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 125827.46666666666; 0.0; 1.2; 0.06666666666666667; 0.0 -1376464859; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1376465159; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376465459; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.5333333333333334; 0.0; 0.0 -1376465759; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376466059; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376466359; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 125828.0; 0.0; 1.6; 0.0; 0.0 -1376466659; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 -1376466959; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376467259; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 107651.46666666666; 0.0; 1.2; 0.0; 0.0 -1376467559; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376467859; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 152391.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1376468159; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376468459; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 131420.53333333333; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 -1376468759; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1376469059; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376469359; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376469659; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.6; 0.0; 0.0 -1376469959; 1; 2599.999602; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376470259; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376470559; 1; 2599.999602; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376470859; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.3333333333333333; 0.9333333333333333; 0.0 -1376471159; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376471459; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 159381.6; 0.06666666666666667; 2.8; 0.13333333333333333; 0.4666666666666667 -1376471759; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 -1376472059; 1; 2599.999602; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.2; 0.0; 0.0 -1376472359; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 1.4; 0.0; 0.0 -1376472659; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376472959; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 150993.6; 20.6; 2.2666666666666666; 0.0; 0.06666666666666667 -1376473260; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 114642.93333333333; 0.0; 4.2; 0.0; 0.0 -1376473560; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 110448.53333333334; 0.0; 2.933333333333333; 0.0; 0.0 -1376473860; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 142604.53333333333; 12.733333333333333; 13.666666666666666; 0.26666666666666666; 0.13333333333333333 -1376474160; 1; 2599.999602; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 1.4666666666666666; 0.0; 0.0 -1376474460; 1; 2599.999602; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376474760; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376475060; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 162177.86666666667; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1376475360; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1376475660; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1376475960; 1; 2599.999602; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376476260; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 -1376476560; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1376476860; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1376477160; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1376477460; 1; 2599.999602; 0.0; 0.0; 2097152.0; 148197.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 -1376477760; 1; 2599.99945; 31.199993399999997; 1.2; 2097152.0; 134216.8; 0.0; 1.2222222222222223; 0.0; 0.0 -1376478060; 1; 2599.99945; 13.866663733333333; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 -1376478360; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376478660; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 174760.0; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1376478960; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 121632.8; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376479260; 1; 2599.99945; 17.333329666666668; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.6; 0.06666666666666667; 0.0 -1376479560; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1376479860; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 -1376480160; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 124429.06666666667; 0.0; 1.2; 0.0; 0.0 -1376480460; 1; 2599.999343; 37.55554606555556; 1.4444444444444446; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1376480760; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.8; 0.06666666666666667; 0.0 -1376481060; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1376481360; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376481660; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1376481960; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 -1376482261; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 142604.0; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 -1376482561; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 -1376482861; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 -1376483161; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376483461; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.6; 0.0; 0.0 -1376483761; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.2; 0.0; 0.0 -1376484061; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 1.2; 0.0; 0.0 -1376484361; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376484661; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376484961; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 79689.6; 0.0; 12.266666666666667; 0.0; 0.0 -1376485261; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142605.6; 0.06666666666666667; 7.6; 0.2; 0.13333333333333333 -1376485561; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130021.6; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376485861; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 166371.46666666667; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 -1376486161; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 113244.8; 0.0; 1.5333333333333334; 0.0; 0.0 -1376486461; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1376486761; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376487061; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 -1376487361; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1376487661; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130021.6; 0.0; 1.6; 0.0; 0.0 -1376487961; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376488261; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376488561; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376488861; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.8; 1.8; 1.5333333333333334; 0.0; 0.06666666666666667 -1376489161; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376489461; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 -1376489761; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376490061; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.8; 0.06666666666666667; 0.0 -1376490362; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 -1376490662; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376490962; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 130022.4; 0.0; 7.6; 0.26666666666666666; 0.26666666666666666 -1376491262; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376491562; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376491862; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125827.2; 0.0; 1.3333333333333333; 0.13333333333333333; 0.0 -1376492162; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1376492462; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 -1376492762; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1376493062; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 162177.86666666667; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376493362; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121632.8; 0.0; 1.2666666666666666; 0.0; 0.0 -1376493662; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376493962; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 2.4; 0.0 -1376494261; 1; 2599.999309; 25.999993089999997; 1.0; 2097152.0; 71300.8; 0.0; 1.1111111111111112; 0.0; 0.0 -1376494561; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1376494861; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376495161; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 -1376495461; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1376495761; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.06666666666666667; 0.0 -1376496061; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376496362; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376496662; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 163575.2; 0.2; 2.8666666666666667; 0.13333333333333333; 0.5333333333333333 -1376496962; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 7.466666666666667; 0.3333333333333333; 0.13333333333333333 -1376497262; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 120235.46666666666; 0.0; 1.6; 0.0; 0.0 -1376497562; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 72698.93333333333; 0.0; 1.2; 0.0; 0.0 -1376497862; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376498162; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376498462; 1; 2599.999297; 29.249992091249997; 1.125; 2097152.0; 76019.5; 0.0; 1.0; 0.0; 0.0 -1376498762; 1; 2599.999297; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1376499062; 1; 2599.999297; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1376499362; 1; 2599.999297; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1376499662; 1; 2599.999297; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376499962; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.4; 0.0; 0.0 -1376500262; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 152391.2; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1376500562; 1; 2599.999297; 0.0; 0.0; 2097152.0; 117438.93333333333; 0.0; 1.2; 0.2; 0.0 -1376500862; 1; 2599.999297; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376501162; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 143.66666666666666; 0.0 -1376501462; 1; 2599.999297; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.5333333333333334; 0.0; 0.0 -1376501762; 1; 2599.999297; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 -1376502062; 1; 2599.999297; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.4; 0.0; 0.0 -1376502362; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1376502662; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 8.4; 0.0 -1376502962; 1; 2599.999297; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 -1376503263; 1; 2599.999297; 0.0; 0.0; 2097152.0; 113244.26666666666; 0.0; 1.2; 0.0; 0.0 -1376503563; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 138410.93333333332; 0.0; 7.466666666666667; 0.2; 0.13333333333333333 -1376503863; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 169168.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1376504163; 1; 2599.999297; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 1.6; 0.0; 0.0 -1376504463; 1; 2599.999297; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1376504763; 1; 2599.999297; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376505063; 1; 2599.999297; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.2; 0.0; 0.0 -1376505363; 1; 2599.999297; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376505663; 1; 2599.999297; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1376505963; 1; 2599.999297; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 1.2; 0.0; 0.0 -1376506263; 1; 2599.999297; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1376506563; 1; 2599.999297; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1376506863; 1; 2599.999297; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.4; 0.0; 0.0 -1376507163; 1; 2599.999297; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376507463; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 162177.86666666667; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 -1376507763; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376508063; 1; 2599.999297; 317.19991423399995; 12.2; 2097152.0; 437603.2; 907.8; 1409.7333333333333; 246.6; 7.866666666666666 -1376508363; 1; 2599.999297; 109.199970474; 4.2; 2097152.0; 829071.7333333333; 1.4666666666666666; 6.466666666666667; 0.0; 0.13333333333333333 -1376508663; 1; 2599.999304; 31.199991648; 1.2; 2097152.0; 419428.0; 0.0; 1.7777777777777777; 0.0; 0.0 -1376508963; 1; 2599.999304; 34.66665738666667; 1.3333333333333335; 2097152.0; 321561.86666666664; 0.8; 5.0; 0.0; 0.06666666666666667 -1376509263; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 223693.33333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1376509563; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376509863; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.13333333333333333; 0.0 -1376510163; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376510463; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376510763; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1376511064; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 201324.8; 17.266666666666666; 2.6; 0.06666666666666667; 0.4666666666666667 -1376511364; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376511664; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1376511964; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1376512264; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376512564; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376512864; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1376513164; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1376513464; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376513764; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 -1376514064; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1376514364; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1376514664; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 -1376514964; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1376515264; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376515564; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376515864; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376516164; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1376516464; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376516764; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 -1376517064; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376517365; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121632.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1376517665; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8; 0.0; 0.0 -1376517965; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376518265; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163576.0; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1376518565; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376518865; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.5333333333333333; 0.0; 0.0 -1376519165; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 -1376519465; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 2.7333333333333334; 1.2; 0.0; 0.0 -1376519765; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.06666666666666667 -1376520065; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 -1376520365; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376520665; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 -1376520965; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376521265; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376521565; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 141206.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376521865; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 164974.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376522165; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1376522465; 1; 2599.999304; 136.93329667733332; 5.266666666666667; 2097152.0; 171964.0; 161.86666666666667; 14.466666666666667; 0.0; 0.0 -1376522765; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 289404.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376523065; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 170567.46666666667; 31.8; 3.7333333333333334; 0.0; 0.0 -1376523365; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 226490.4; 0.0; 0.8; 0.0; 0.0 -1376523665; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376523965; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376524265; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 7.0; 0.2; 0.13333333333333333 -1376524565; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 146798.4; 0.0; 0.8; 0.0; 0.0 -1376524865; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376525165; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1376525465; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 159380.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376525765; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 -1376526065; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 0.8; 0.0; 0.0 -1376526365; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376526665; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.6666666666666666; 1.1333333333333333; 0.0; 0.0 -1376526965; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1376527265; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376527565; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376527865; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1376528165; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1376528465; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 86680.26666666666; 0.0; 11.666666666666666; 0.0; 0.0 -1376528765; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 142604.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376529065; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163576.0; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1376529365; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376529666; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1376529966; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1376530266; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.26666666666; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 -1376530566; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 -1376530866; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 159382.4; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1376531166; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1376531466; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1376531766; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 -1376532066; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376532366; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376532666; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163575.73333333334; 0.0; 2.066666666666667; 0.0; 0.5333333333333333 -1376532966; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 -1376533266; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376533566; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376533866; 1; 2599.999304; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1376534166; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1376534466; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.6; 0.0; 0.0 -1376534766; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1376535066; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1376535366; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376535666; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376535966; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1376536266; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 199926.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376536566; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 128624.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1376536866; 1; 2599.999304; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 -1376537166; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1376537466; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376537766; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.2 -1376538066; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.8; 0.0; 0.8; 0.0; 0.0 -1376538366; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 -1376538666; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376538967; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 174761.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376539267; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117438.13333333333; 0.0; 0.6; 0.0; 0.0 -1376539567; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1376539867; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 174760.53333333333; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1376540167; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376540466; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 -1376540766; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1376541066; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376541366; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1376541666; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1376541966; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.5333333333333333; 0.0; 0.0 -1376542267; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376542567; 1; 2599.999304; 0.0; 0.0; 2097152.0; 148196.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376542867; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1376543167; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376543467; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 188741.33333333334; 0.06666666666666667; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376543767; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.33333333334; 0.0; 6.8; 0.2; 0.13333333333333333 -1376544067; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 -1376544367; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376544667; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1376544967; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 -1376545267; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1376545567; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376545867; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1376546167; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376546467; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376546767; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1376547067; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 166371.73333333334; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1376547367; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 131420.26666666666; 0.0; 0.8; 0.0; 0.0 -1376547667; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1376547967; 1; 2599.999304; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 0.6; 0.0; 0.0 -1376548267; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1376548567; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 1.9333333333333333; 0.0; 0.0 -1376548867; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1376549167; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1376549467; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1376549767; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1376550067; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 153789.06666666668; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1376550367; 1; 2599.999304; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376550667; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 192936.0; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376550968; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.53333333333; 0.0; 0.6; 0.0; 0.0 -1376551268; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1376551568; 1; 2599.999304; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6; 0.0; 0.0 -1376551868; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376552168; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.5333333333333333; 0.0; 0.0 -1376552468; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1376552768; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.6; 0.0; 0.0 -1376553068; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376553368; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376553668; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376553968; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.7333333333333333; 1.9333333333333333; 1.2; 0.0 -1376554268; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 159381.86666666667; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1376554568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155187.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376554868; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376555168; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1376555468; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376555768; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376556068; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1376556368; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 141207.46666666667; 0.0; 6.8; 0.2; 0.13333333333333333 -1376556668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 150993.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376556968; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376557268; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 1.5333333333333334; 1.4666666666666666; 0.0; 0.0 -1376557568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376557868; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 176159.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1376558168; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1376558468; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376558768; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376559068; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376559368; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376559668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1376559968; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376560268; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376560568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376560868; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1376561168; 1; 2599.999304; 0.0; 0.0; 2097152.0; 134215.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376561468; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 132818.4; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1376561768; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376562068; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 7.2; 0.26666666666666666; 0.13333333333333333 -1376562368; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376562668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376562968; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376563269; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1376563569; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1376563869; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376564169; 1; 2599.999304; 195.86661423466666; 7.533333333333334; 2097152.0; 359310.4; 162.26666666666668; 117.66666666666667; 0.0; 0.4 -1376564469; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 655707.7333333333; 0.0; 6.0; 0.06666666666666667; 0.0 -1376564769; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 292200.8; 31.8; 3.466666666666667; 0.0; 0.0 -1376565069; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 255850.4; 18.0; 3.933333333333333; 0.7333333333333333; 0.4666666666666667 -1376565369; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 169168.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 -1376565669; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.06666666666666667; 0.0 -1376565969; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376566269; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.33333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1376566569; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376566869; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1376567169; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376567469; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376567769; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376568069; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 -1376568369; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376568669; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 211111.2; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376568969; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 149595.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376569269; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 -1376569569; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1376569869; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 -1376570169; 1; 2599.999304; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376570469; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 -1376570769; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376571069; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376571369; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.3333333333333333; 0.0 -1376571669; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376571969; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 11.6; 0.0; 0.0 -1376572269; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 141207.2; 1.0; 3.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376572569; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376572869; 1; 2599.999304; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 -1376573169; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376573469; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1376573769; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376574069; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1376574369; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376574669; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 -1376574969; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376575269; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376575569; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 -1376575869; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163576.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1376576169; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.0; 0.06666666666666667; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1376576469; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 0.8; 0.13333333333333333; 0.0 -1376576769; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.3333333333333333; 0.0 -1376577069; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.8; 0.06666666666666667 -1376577369; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376577669; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1376577970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376578270; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 -1376578570; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117438.4; 0.0; 0.6; 0.0; 0.0 -1376578870; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.8; 0.0; 0.0 -1376579170; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 -1376579470; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 155188.0; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376579770; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1376580070; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.6; 0.0; 0.0 -1376580370; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376580670; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 141206.66666666666; 0.0; 0.6; 0.0; 0.0 -1376580970; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376581270; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376581570; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 7.4; 0.3333333333333333; 0.13333333333333333 -1376581870; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 -1376582170; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1376582470; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376582770; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376583070; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 192936.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376583370; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376583670; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376583970; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1376584270; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376584570; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376584870; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376585170; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1376585470; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 2.8; 0.0 -1376585770; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376586070; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 -1376586370; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142604.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376586670; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 176159.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376586970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376587270; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1376587571; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 -1376587871; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376588171; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376588471; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 145401.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376588771; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376589071; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1376589371; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376589670; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376589970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1376590270; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 150993.6; 0.2; 2.0; 0.06666666666666667; 0.4666666666666667 -1376590570; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376590870; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 -1376591170; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376591470; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376591771; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376592071; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376592371; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 62912.0; 0.0; 0.5333333333333333; 0.13333333333333333; 0.0 -1376592671; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376592971; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376593271; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1376593571; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 -1376593871; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 170565.86666666667; 0.0; 8.2; 0.26666666666666666; 0.6666666666666666 -1376594171; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376594471; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 79689.6; 0.0; 0.6; 0.0; 0.0 -1376594771; 1; 2599.999304; 65.86664903466666; 2.533333333333333; 2097152.0; 329950.13333333336; 161.73333333333332; 22.933333333333334; 0.0; 0.2 -1376595071; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 486536.8; 0.0; 1.2; 0.06666666666666667; 0.0 -1376595371; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 174760.8; 31.8; 3.6666666666666665; 0.0; 0.0 -1376595671; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 135614.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376595971; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376596271; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121633.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376596571; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376596871; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 -1376597171; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1376597471; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 190138.66666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.5333333333333333 -1376597771; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376598071; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1376598371; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376598671; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376598971; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376599271; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376599571; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 159381.6; 12.733333333333333; 13.0; 0.4; 0.13333333333333333 -1376599871; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376600171; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376600471; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376600771; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376601072; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 156586.13333333333; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1376601372; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376601672; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376601972; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 145401.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376602272; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1376602572; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1376602872; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 -1376603172; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 -1376603472; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376603772; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1376604072; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1376604372; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376604672; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 220897.6; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376604972; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 7.266666666666667; 0.3333333333333333; 0.13333333333333333 -1376605272; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376605572; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376605872; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 2.6666666666666665; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 -1376606172; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 -1376606472; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376606772; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.06666666666666667; 0.0 -1376607072; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376607372; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376607672; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376607972; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 -1376608272; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 -1376608572; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376608872; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376609172; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376609472; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376609772; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 62912.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376610072; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1376610372; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376610672; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1376610972; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 -1376611272; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1376611572; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376611872; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 201324.53333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376612172; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 -1376612472; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376612772; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376613072; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 92272.8; 0.6; 1.2; 0.0; 0.0 -1376613372; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1376613672; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1376613972; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 125827.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376614272; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1376614572; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1376614872; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376615172; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 -1376615472; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 170565.86666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376615772; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 11.733333333333333; 0.06666666666666667; 0.0 -1376616072; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1376616372; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376616672; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376616973; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376617273; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376617573; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376617873; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 -1376618173; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1376618473; 1; 2599.999304; 71.06664764266665; 2.733333333333333; 2097152.0; 571821.6; 166.6; 21.533333333333335; 0.06666666666666667; 0.4 -1376618773; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 569025.0666666667; 0.0; 2.466666666666667; 0.0; 0.0 -1376619073; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 293599.4666666667; 31.866666666666667; 5.466666666666667; 0.06666666666666667; 0.5333333333333333 -1376619373; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 197130.93333333332; 0.0; 2.2666666666666666; 0.0; 0.0 -1376619673; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 139808.8; 0.0; 1.5333333333333334; 0.0; 0.0 -1376619973; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376620273; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 4.333333333333333; 0.0; 0.0 -1376620573; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376620873; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1376621173; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 132818.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376621473; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 109049.86666666667; 0.0; 0.6; 0.0; 0.0 -1376621773; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376622073; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1376622373; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376622673; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 146798.93333333332; 0.2; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376622973; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 0.8; 0.0; 0.0 -1376623273; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 -1376623573; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1376623873; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 100661.6; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 -1376624173; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1376624473; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376624773; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376625073; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376625373; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376625673; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 1.4666666666666666; 1.0; 0.06666666666666667; 0.06666666666666667 -1376625973; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376626273; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 104856.0; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376626573; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376626873; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376627173; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376627473; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376627773; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1376628073; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1376628373; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1376628673; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376628973; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 150993.6; 0.0; 0.6; 0.0; 0.0 -1376629273; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1376629573; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376629873; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 139808.8; 0.0; 8.2; 0.26666666666666666; 0.6 -1376630173; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 152391.46666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376630474; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1376630774; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 -1376631074; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1376631374; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376631674; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376631974; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376632274; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 -1376632574; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.06666666666666667; 0.0 -1376632874; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376633174; 1; 2599.999304; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1376633474; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 173362.93333333332; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376633774; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376634074; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376634374; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376634674; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.06666666666666667 -1376634974; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 2.066666666666667; 0.0; 0.0 -1376635274; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.6666666666666667; 0.0; 0.0 -1376635574; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1376635874; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376636174; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376636474; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376636774; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376637074; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 157983.46666666667; 0.6; 8.666666666666666; 0.3333333333333333; 0.6666666666666666 -1376637374; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376637674; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376637974; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376638274; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376638574; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376638874; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376639174; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1376639474; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1376639774; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376640074; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376640374; 1; 2599.999304; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376640674; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1376640974; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1376641275; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376641575; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1376641875; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376642175; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376642475; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 -1376642775; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1376643075; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1376643375; 1; 2599.999304; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376643675; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1376643975; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1376644275; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 155187.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376644575; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1376644875; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376645175; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376645475; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 2.2666666666666666; 0.0 -1376645775; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376646075; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1376646375; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376646675; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376646975; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1376647275; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376647575; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376647875; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 209713.6; 0.0; 2.2; 0.0; 0.4666666666666667 -1376648175; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376648475; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376648775; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1376649075; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1376649375; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 -1376649675; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376649975; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 -1376650276; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 -1376650576; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376650876; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376651176; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376651476; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 170566.66666666666; 0.0; 2.2; 0.0; 0.4666666666666667 -1376651776; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376652076; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 2.933333333333333; 0.0 -1376652376; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1376652676; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376652976; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.6; 4.933333333333334; 0.0 -1376653276; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376653576; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121632.8; 0.0; 1.2; 0.0; 0.0 -1376653876; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376654176; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.6666666666666666; 0.0 -1376654476; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376654776; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376655076; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 157983.46666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376655376; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.0; 0.0; 0.8; 0.06666666666666667; 0.0 -1376655676; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 62912.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1376655976; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1376656276; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376656576; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376656876; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376657176; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 1.3333333333333333; 0.0 -1376657476; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 1.5333333333333334; 0.0 -1376657776; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.3333333333333333; 0.0 -1376658076; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.6; 0.0 -1376658376; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.7333333333333333; 0.0 -1376658676; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 188741.6; 0.06666666666666667; 2.4; 0.4; 0.5333333333333333 -1376658976; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 139809.06666666668; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1376659276; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 11.533333333333333; 0.0; 0.0 -1376659576; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376659876; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1376660176; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1376660476; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376660776; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376661076; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142604.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376661376; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1376661676; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.13333333333333333; 0.0 -1376661976; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1376662276; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 198528.53333333333; 12.733333333333333; 14.733333333333333; 0.4; 0.6 -1376662576; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 169169.06666666668; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376662876; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376663176; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 57319.46666666667; 0.0; 1.2; 0.06666666666666667; 0.0 -1376663476; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 62912.0; 0.0; 0.8; 0.2; 0.13333333333333333 -1376663777; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376664077; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376664377; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 121632.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376664677; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376664977; 1; 2599.999304; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.06666666666666667; 0.0 -1376665277; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.13333333333333333; 0.0 -1376665577; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.6; 0.06666666666666667; 0.0 -1376665877; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 171964.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1376666177; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376666477; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 -1376666777; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376667077; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1376667377; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1376667677; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 -1376667977; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.7333333333333334; 0.0; 0.0 -1376668277; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1376668577; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1376668877; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376669177; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 118837.33333333333; 0.0; 7.2; 0.2; 0.13333333333333333 -1376669477; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 169168.53333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376669777; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 131420.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376670077; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376670377; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376670677; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 -1376670977; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1376671277; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376671577; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376671878; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376672178; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 -1376672478; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 146799.2; 0.0; 0.6; 0.0; 0.0 -1376672778; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376673078; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 195732.26666666666; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376673378; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376673678; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376673978; 1; 2599.999304; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1376674278; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376674578; 1; 2599.999304; 25.99999304; 1.0; 2097152.0; 155188.26666666666; 161.06666666666666; 27.466666666666665; 0.4; 0.5333333333333333 -1376674878; 1; 2599.999304; 48.53332034133333; 1.8666666666666665; 2097152.0; 722816.5333333333; 0.0; 2.6; 0.0; 0.0 -1376675178; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 324357.86666666664; 31.8; 3.0; 0.06666666666666667; 0.0 -1376675478; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 174760.8; 0.0; 2.4; 0.0; 0.0 -1376675778; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 187343.73333333334; 0.0; 1.7333333333333334; 0.0; 0.0 -1376676078; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.13333333333; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1376676378; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1376676678; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 156585.33333333334; 0.0; 2.0; 0.13333333333333333; 0.4666666666666667 -1376676978; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376677278; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1376677578; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1376677878; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.6; 0.13333333333333333; 0.0 -1376678178; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.06666666666666667; 0.0 -1376678478; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376678778; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376679078; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142605.6; 0.0; 0.6; 0.0; 0.0 -1376679378; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.06666666666666667; 0.0 -1376679679; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.5333333333333333; 0.13333333333333333; 0.0 -1376679979; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376680279; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 183149.86666666667; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1376680579; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 142605.6; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1376680879; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 164973.33333333334; 0.0; 0.6; 0.0; 0.0 -1376681179; 1; 2599.999304; 43.333321733333335; 1.6666666666666665; 2097152.0; 267036.26666666666; 161.0; 14.466666666666667; 0.0; 0.2 -1376681479; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 459973.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1376681779; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 187344.0; 31.8; 3.466666666666667; 0.0; 0.0 -1376682079; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376682379; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376682679; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376682979; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376683279; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376683579; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1376683879; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 150994.4; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1376684179; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.06666666666666667; 1.6666666666666667; 0.0; 0.0 -1376684479; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376684779; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1376685079; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1376685379; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 149595.73333333334; 0.0; 1.0; 0.0; 0.0 -1376685679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376685979; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376686279; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376686579; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 -1376686879; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1376687179; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 145401.33333333334; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 -1376687479; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 192935.73333333334; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376687779; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376688079; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376688379; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1376688679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376688979; 1; 2599.999304; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376689279; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 -1376689579; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 65708.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376689879; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376690179; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 62912.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1376690479; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376690779; 1; 2599.999304; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376691079; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 187342.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1376691379; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137012.8; 0.0; 0.8; 0.0; 0.0 -1376691679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376691979; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376692279; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.13333333333333333 -1376692579; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 156586.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1376692879; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376693179; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 137012.26666666666; 0.06666666666666667; 7.466666666666667; 0.2; 0.13333333333333333 -1376693480; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376693780; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376694080; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.2; 0.06666666666666667 -1376694380; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1376694680; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376694980; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376695280; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376695580; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1376695880; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376696180; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376696480; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 174760.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376696780; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 146800.0; 0.0; 1.0; 0.0; 0.0 -1376697080; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 -1376697380; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8; 0.06666666666666667; 0.0 -1376697680; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376697980; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376698280; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.0; 0.06666666666666667; 0.5333333333333333 -1376698580; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.5333333333333333; 0.0; 0.0 -1376698880; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 -1376699180; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 124429.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376699480; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1376699780; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376700080; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 -1376700380; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376700680; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376700980; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376701280; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376701581; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1376701881; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 198529.06666666668; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376702181; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376702481; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376702781; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376703081; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 171964.53333333333; 0.0; 11.666666666666666; 0.0; 0.0 -1376703381; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376703681; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376703981; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376704281; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376704581; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376704881; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 -1376705181; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376705481; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 146799.2; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376705781; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 145401.06666666668; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 -1376706081; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1376706381; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376706681; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 -1376706981; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1376707281; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376707581; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.4; 0.0 -1376707881; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 124429.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376708181; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376708481; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376708781; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376709081; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 159383.2; 0.06666666666666667; 2.2666666666666666; 1.0666666666666667; 0.5333333333333333 -1376709381; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 0.6; 0.0; 0.0 -1376709681; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376709981; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376710281; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1376710581; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1376710881; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1376711181; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1376711481; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376711781; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376712082; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 86680.26666666666; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 -1376712382; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.6; 0.06666666666666667; 0.0 -1376712682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 -1376712982; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1376713282; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376713582; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376713882; 1; 2599.999304; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 -1376714182; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1376714482; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1376714782; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376715082; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1376715382; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1376715682; 1; 2599.999304; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 -1376715982; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 -1376716282; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 150993.06666666668; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376716582; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1376716882; 1; 2599.999304; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376717182; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376717482; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 -1376717782; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1376718082; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376718382; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 190138.93333333332; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 -1376718682; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.06666666666666667; 0.0 -1376718982; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1376719282; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117437.6; 0.0; 0.5333333333333333; 0.0; 0.0 -1376719582; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376719882; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 187343.2; 0.2; 2.466666666666667; 0.0; 0.5333333333333333 -1376720182; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1376720482; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376720782; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376721082; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376721382; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.2666666666666666; 0.26666666666666666; 0.13333333333333333 -1376721682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 1.4666666666666666; 0.13333333333333333; 0.0 -1376721982; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1376722282; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 0.6; 0.0; 0.0 -1376722582; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.8; 3.7333333333333334; 0.0 -1376722882; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376723182; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376723482; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 173362.13333333333; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376723782; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 134216.8; 12.733333333333333; 17.0; 0.3333333333333333; 0.2 -1376724082; 1; 2599.999304; 60.66665042666666; 2.3333333333333335; 2097152.0; 279618.6666666667; 161.0; 22.133333333333333; 0.06666666666666667; 0.4 -1376724382; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 763362.4; 0.0; 2.7333333333333334; 0.06666666666666667; 0.0 -1376724682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 348124.8; 31.8; 3.533333333333333; 0.0; 0.0 -1376724982; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 188741.6; 0.0; 2.3333333333333335; 0.0; 0.0 -1376725282; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 -1376725582; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.7333333333333334; 0.0; 0.0 -1376725882; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376726182; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1376726482; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376726782; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376727082; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 181750.93333333332; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1376727382; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 -1376727682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376727982; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376728282; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.2; 0.0 -1376728583; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376728883; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376729183; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376729483; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376729783; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376730083; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 7.0; 0.3333333333333333; 0.13333333333333333 -1376730383; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376730683; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 166372.0; 0.06666666666666667; 2.4; 0.13333333333333333; 0.4666666666666667 -1376730983; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1376731283; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376731583; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376731883; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376732183; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376732483; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376732783; 1; 2599.999304; 0.0; 0.0; 2097152.0; 100660.8; 0.0; 1.0; 0.0; 0.0 -1376733083; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376733383; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376733683; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376733983; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376734283; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184547.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376734583; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376734883; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 64310.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376735184; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376735484; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 7.866666666666666; 0.0 -1376735784; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376736084; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 144002.93333333332; 0.0; 7.533333333333333; 0.2; 0.13333333333333333 -1376736384; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155188.0; 0.0; 0.8; 0.13333333333333333; 0.0 -1376736684; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.2; 0.06666666666666667; 0.0 -1376736984; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376737284; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.2; 0.0 -1376737584; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376737884; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 160779.46666666667; 0.0; 2.466666666666667; 0.2; 0.5333333333333333 -1376738184; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376738484; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376738784; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376739084; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376739384; 1; 2599.999304; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376739684; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376739984; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376740284; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376740584; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1376740884; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376741184; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.13333333333333333; 0.0 -1376741484; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 171964.8; 0.0; 2.2; 0.13333333333333333; 0.4666666666666667 -1376741784; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376742084; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1376742384; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 6.866666666666666; 0.3333333333333333; 0.2 -1376742684; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1376742984; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376743284; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376743584; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376743885; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376744185; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376744485; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1376744785; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376745085; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.3333333333333335; 0.2; 0.4666666666666667 -1376745385; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1376745685; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1376745985; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376746285; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376746585; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 11.6; 0.13333333333333333; 0.0 -1376746885; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 -1376747185; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1376747485; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376747785; 1; 2599.999304; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1376748085; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376748385; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.2; 0.13333333333333333 -1376748685; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 167769.86666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376748985; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138411.2; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1376749285; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1376749585; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1376749885; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.06666666666666667; 1.0666666666666667; 0.06666666666666667; 0.13333333333333333 -1376750185; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 128624.26666666666; 0.06666666666666667; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 -1376750485; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376750785; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376751085; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1376751385; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 -1376751685; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376751985; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376752285; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 141207.46666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1376752586; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376752886; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1376753186; 1; 2599.999304; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376753485; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376753785; 1; 2599.999304; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376754085; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376754385; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376754685; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 81087.73333333334; 0.0; 7.2; 0.2; 0.13333333333333333 -1376754985; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376755285; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376755585; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376755885; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 155188.26666666666; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 -1376756185; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 124429.6; 0.0; 0.8; 0.0; 0.0 -1376756485; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125826.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376756785; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95068.8; 0.0; 0.5333333333333333; 0.0; 0.0 -1376757085; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.4; 0.0; 0.0 -1376757385; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376757685; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376757985; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376758285; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 155188.8; 0.0; 0.6; 0.0; 0.0 -1376758585; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1376758885; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 65708.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376759186; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376759486; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 169168.8; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1376759786; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125827.73333333334; 0.0; 1.0; 0.0; 0.0 -1376760086; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376760386; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 117438.66666666667; 0.0; 6.6; 0.2; 0.13333333333333333 -1376760686; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117438.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376760986; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376761286; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 125827.2; 0.0; 1.0; 0.0; 0.0 -1376761586; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1376761886; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376762186; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 -1376762486; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.06666666666666667 -1376762786; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1376763086; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 198528.8; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376763386; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 125827.73333333334; 0.0; 0.8; 0.0; 0.0 -1376763686; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376763986; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.5333333333333333; 0.0; 0.0 -1376764286; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376764586; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376764886; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376765186; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1376765486; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376765786; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376766086; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376766386; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 139808.53333333333; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1376766686; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 185944.53333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376766986; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376767286; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138411.2; 0.0; 0.5333333333333333; 0.0; 0.0 -1376767586; 1; 2599.999304; 45.06665460266667; 1.7333333333333334; 2097152.0; 166371.73333333334; 161.2; 14.133333333333333; 0.0; 0.2 -1376767886; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 432010.93333333335; 0.0; 1.2; 0.0; 0.0 -1376768187; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 177556.53333333333; 31.8; 3.4; 0.0; 0.0 -1376768487; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184546.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 -1376768787; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1376769087; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376769387; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376769687; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1376769987; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376770287; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 155188.0; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1376770587; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376770887; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1376771187; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1376771487; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376771787; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376772087; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1376772387; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1376772687; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1376772987; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 117438.4; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1376773287; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376773587; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376773887; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 180352.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1376774187; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376774487; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1376774787; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1376775087; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1376775387; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1376775687; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376775988; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376776288; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376776588; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376776891; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376777191; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1376777491; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 149594.4; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376777791; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 -1376778091; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1376778391; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1376778691; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 -1376778991; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 -1376779291; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376779591; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376779891; 1; 2599.999304; 46.799987472000005; 1.8; 2097152.0; 153789.6; 161.46666666666667; 27.933333333333334; 0.3333333333333333; 0.6 -1376780191; 1; 2599.999304; 34.66665738666667; 1.3333333333333335; 2097152.0; 735398.9333333333; 0.0; 2.4; 0.0; 0.0 -1376780491; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 290802.93333333335; 31.8; 3.3333333333333335; 0.0; 0.0 -1376780791; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 178954.4; 0.0; 2.3333333333333335; 0.0; 0.0 -1376781091; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184547.73333333334; 0.06666666666666667; 3.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376781391; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376781691; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376781991; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1376782291; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.6; 0.06666666666666667; 1.0666666666666667; 0.0; 0.0 -1376782591; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130021.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376782891; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376783191; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 137012.53333333333; 0.0; 1.2; 0.0; 0.0 -1376783491; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 164973.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376783791; 1; 2599.999304; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376784091; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376784392; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1376784692; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 156586.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1376784992; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 -1376785292; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376785592; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376785892; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376786191; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 134216.8; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 -1376786491; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 134216.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1376786791; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376787091; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376787391; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1376787691; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 -1376787991; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376788291; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 131419.73333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 -1376788591; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1376788891; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376789191; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376789491; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376789791; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376790092; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376790392; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 127225.6; 0.0; 12.0; 0.0; 0.0 -1376790692; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1376790992; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376791292; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1376791592; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 -1376791892; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 -1376792192; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376792492; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 114642.93333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1376792792; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376793092; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1376793392; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376793692; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 -1376793992; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376794292; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376794592; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376794892; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 -1376795192; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376795492; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 159380.8; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1376795792; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1376796092; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 78291.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376796392; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1376796692; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 128623.46666666666; 0.0; 0.6; 0.0; 0.0 -1376796992; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.0; 0.0 -1376797292; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376797592; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 145401.86666666667; 0.0; 1.2; 0.0; 0.0 -1376797892; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1376798193; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1376798493; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 -1376798793; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1376799093; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 185945.33333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376799393; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376799693; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1376799993; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1376800293; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376800593; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376800893; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1376801193; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376801493; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 76893.33333333333; 0.0; 1.6; 0.0; 0.0 -1376801793; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.5333333333333333; 0.0; 0.0 -1376802093; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 144003.73333333334; 0.0; 0.6; 0.0; 0.0 -1376802393; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138410.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376802693; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 195731.2; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376802993; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376803293; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 -1376803593; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1376803893; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 -1376804193; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376804493; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376804793; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 7.0; 0.2; 0.13333333333333333 -1376805093; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130021.6; 0.0; 0.6; 0.0; 0.0 -1376805393; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1376805693; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376805993; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 -1376806293; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 208314.93333333332; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376806593; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 169169.33333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376806893; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 149595.46666666667; 0.0; 0.8; 0.0; 0.0 -1376807193; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 0.8; 0.0; 0.0 -1376807493; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.13333333333333333 -1376807793; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.8; 0.06666666666666667; 0.0 -1376808093; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 -1376808393; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1376808693; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.5333333333333333; 0.0; 0.0 -1376808993; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376809293; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376809593; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1376809894; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 191537.86666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1376810194; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376810494; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1376810794; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1376811094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376811394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1376811694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376811994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376812294; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 -1376812594; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376812894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376813194; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 -1376813494; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 191537.86666666667; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376813794; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1376814094; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 -1376814394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.5333333333333333; 0.0; 0.0 -1376814694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376814994; 1; 2599.999304; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6; 0.06666666666666667; 0.0 -1376815294; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1376815594; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 -1376815894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376816194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 -1376816494; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376816794; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376817094; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 150993.6; 0.2; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376817394; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1376817694; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376817994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376818294; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376818594; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376818894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376819194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 57319.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376819494; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376819794; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376820094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.8; 0.0; 0.0 -1376820394; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376820694; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 150993.6; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1376820994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376821294; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376821594; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376821894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376822194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1376822494; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376822794; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376823094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 173362.93333333332; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1376823394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376823694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376823995; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376824295; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 142604.8; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1376824595; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376824895; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1376825195; 1; 2599.999304; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376825495; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376825795; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376826095; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376826395; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 -1376826695; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120234.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376826995; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376827295; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376827595; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376827895; 1; 2599.999304; 25.99999304; 1.0; 2097152.0; 185945.6; 161.06666666666666; 22.0; 0.13333333333333333; 0.8666666666666667 -1376828195; 1; 2599.999304; 51.99998608; 2.0; 2097152.0; 812294.1333333333; 0.0; 3.533333333333333; 0.0; 0.0 -1376828495; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 402650.93333333335; 31.8; 3.066666666666667; 0.0; 0.0 -1376828795; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 215304.53333333333; 0.06666666666666667; 2.3333333333333335; 0.0; 0.0 -1376829095; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 1.8666666666666667; 0.0; 0.0 -1376829395; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1376829695; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376829995; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 -1376830295; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376830595; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376830895; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.13333333333333333; 0.06666666666666667 -1376831195; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1376831495; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163575.73333333334; 0.0; 2.3333333333333335; 0.13333333333333333; 0.5333333333333333 -1376831795; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1376832096; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376832396; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376832696; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1376832996; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1376833296; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376833596; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1376833896; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 11.4; 0.0; 0.0 -1376834196; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376834495; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134215.73333333334; 0.0; 0.8; 0.0; 0.0 -1376834795; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376835095; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 187343.73333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 -1376835395; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1376835695; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.13333333333333333; 0.0 -1376835995; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376836295; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 141206.66666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.2 -1376836595; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 146800.0; 0.0; 0.8; 0.0; 0.0 -1376836895; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376837195; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376837495; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376837795; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376838096; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376838396; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376838696; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 192935.73333333334; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1376838996; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376839296; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376839596; 1; 2599.999304; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376839896; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1376840196; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376840496; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376840796; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376841096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376841396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376841696; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376841996; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1376842296; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 155188.0; 0.06666666666666667; 8.266666666666667; 0.26666666666666666; 0.6 -1376842596; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130022.4; 0.06666666666666667; 1.0; 0.06666666666666667; 0.0 -1376842896; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376843196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376843496; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376843796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376844096; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376844396; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376844696; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376844996; 1; 2599.999304; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376845296; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376845596; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1376845896; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 104855.2; 0.06666666666666667; 2.8; 0.06666666666666667; 0.5333333333333333 -1376846196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137011.73333333334; 0.0; 0.8; 0.0; 0.0 -1376846496; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1376846796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376847096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1376847396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376847696; 1; 2599.999304; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376847996; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376848296; 1; 2599.999304; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376848596; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 121633.6; 12.733333333333333; 13.4; 0.3333333333333333; 0.2 -1376848896; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 1.0; 0.0; 0.0 -1376849196; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 167771.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376849496; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.6; 0.0; 1.6666666666666667; 0.06666666666666667; 0.4666666666666667 -1376849796; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 -1376850096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1376850396; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1376850696; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376850996; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376851296; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376851596; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376851896; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376852196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376852496; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376852796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1376853096; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 184548.0; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 -1376853396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376853697; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.6; 0.06666666666666667; 0.0 -1376853996; 1; 2599.999304; 36.399990255999995; 1.4; 2097152.0; 171964.8; 161.06666666666666; 14.333333333333334; 0.0; 0.2 -1376854297; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 461372.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1376854597; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 222295.2; 31.8; 9.666666666666666; 0.2; 0.13333333333333333 -1376854897; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 218100.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376855197; 1; 2599.999304; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376855497; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376855797; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376856097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376856397; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376856697; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167769.6; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1376856997; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 159381.6; 0.0; 1.0; 0.0; 0.0 -1376857297; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376857597; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376857897; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376858197; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376858497; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1376858797; 1; 2599.999304; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376859097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376859397; 1; 2599.999304; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376859697; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1376859997; 1; 2599.999304; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376860297; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 197129.6; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376860597; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 137012.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376860897; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 132818.66666666666; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1376861197; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 144002.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376861497; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376861797; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 132818.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1376862097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1376862397; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376862697; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376862997; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376863298; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376863598; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376863898; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 -1376864198; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1376864498; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376864798; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376865098; 1; 2599.999304; 9.2857118; 0.35714285714285715; 2097152.0; 140808.0; 0.07142857142857142; 1.4285714285714286; 0.14285714285714285; 0.14285714285714285 -1376865398; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376865698; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376865998; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376866298; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376866599; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1376866899; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 107652.26666666666; 0.2; 0.9333333333333333; 0.0; 0.0 -1376867199; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376867500; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 174761.06666666668; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1376867801; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1376868101; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1376868401; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376868701; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 -1376869001; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376869301; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376869601; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376869901; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1376870201; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1376870501; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376870801; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 162178.66666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376871101; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167770.4; 0.0; 2.8; 0.06666666666666667; 0.5333333333333333 -1376871401; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376871701; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376872001; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1376872301; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.06666666666666667; 1.4; 0.0; 0.0 -1376872601; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376872901; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376873201; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1376873501; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1376873801; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1376874101; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376874401; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376874701; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 181751.2; 0.2; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376875001; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 127225.86666666667; 0.0; 1.0; 0.0; 0.0 -1376875301; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376875601; 1; 2599.999304; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376875901; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1376876201; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1376876501; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376876801; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376877101; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376877401; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125827.2; 0.0; 11.6; 0.0; 0.0 -1376877701; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376878001; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 -1376878302; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 171965.06666666668; 0.06666666666666667; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 -1376878602; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138410.93333333332; 0.0; 0.8; 0.0; 0.0 -1376878902; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376879202; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376879502; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376879802; 1; 2599.999304; 71.06664764266665; 2.733333333333333; 2097152.0; 661299.7333333333; 161.0; 21.466666666666665; 0.06666666666666667; 0.4 -1376880102; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 416631.73333333334; 0.0; 8.733333333333333; 0.2; 0.13333333333333333 -1376880402; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 262841.06666666665; 31.8; 3.7333333333333334; 0.0; 0.0 -1376880702; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163576.53333333333; 0.0; 2.2666666666666666; 0.0; 0.0 -1376881002; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 96467.2; 0.0; 1.4; 0.0; 0.0 -1376881302; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376881602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376881902; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 206917.33333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 -1376882202; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 131419.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376882502; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96466.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376882802; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83883.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376883102; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376883402; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1376883702; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376884002; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1376884302; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376884602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376884902; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376885202; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376885502; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 232082.93333333332; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1376885802; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376886102; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376886402; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376886702; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.06666666666666667; 6.8; 0.26666666666666666; 0.2 -1376887002; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 155186.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 -1376887302; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.2; 0.0; 1.0; 0.0; 0.0 -1376887602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1376887902; 1; 2599.999304; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376888202; 1; 2599.999304; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376888502; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376888802; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1376889102; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 180352.53333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376889403; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376889703; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1376890003; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 124429.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376890303; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376890603; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 -1376890903; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1376891203; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376891503; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1376891803; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1376892103; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376892403; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 145401.06666666668; 0.0; 6.533333333333333; 0.2; 0.13333333333333333 -1376892703; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 176158.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1376893003; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376893303; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 -1376893603; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1376893903; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.06666666666666667 -1376894203; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 2.0; 0.06666666666666667; 0.0 -1376894503; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 144003.73333333334; 0.0; 1.4; 0.0; 0.0 -1376894803; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 -1376895103; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 -1376895403; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376895703; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 -1376896003; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1376896304; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 128623.46666666666; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 -1376896604; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376896904; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376897204; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 -1376897504; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 -1376897804; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376898104; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376898404; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 156586.13333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 -1376898704; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376899004; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1376899304; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 -1376899604; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376899904; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167771.46666666667; 0.6; 2.2; 0.06666666666666667; 0.5333333333333333 -1376900204; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1376900504; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 71300.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376900804; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1376901104; 1; 2599.999304; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 -1376901404; 1; 2599.999304; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376901704; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1376902004; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1376902304; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376902604; 1; 2599.999304; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376902904; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 -1376903204; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 132818.4; 0.0; 0.6; 0.0; 0.0 -1376903504; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 218101.06666666668; 0.0; 1.9333333333333333; 0.06666666666666667; 0.5333333333333333 -1376903804; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376904104; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1376904404; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1376904704; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127225.86666666667; 0.0; 6.733333333333333; 0.4; 0.06666666666666667 -1376905004; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142605.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1376905304; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 -1376905604; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376905904; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.4; 0.0; 0.8; 0.0; 0.0 -1376906204; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117438.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376906504; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 62912.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376906804; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1376907104; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 184548.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376907404; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1376907704; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376908004; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1376908304; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376908604; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 -1376908904; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.4; 0.0 -1376909204; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.0; 0.0 -1376909504; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 2.4; 0.0 -1376909804; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376910104; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.13333333333333333; 0.0 -1376910404; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376910705; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 170566.66666666666; 12.8; 16.466666666666665; 0.4666666666666667; 0.7333333333333333 -1376911005; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 -1376911305; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376911605; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376911905; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 162178.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376912205; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1376912505; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96466.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376912805; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 -1376913105; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376913405; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1376913705; 1; 2599.9993; 28.888881111111115; 1.1111111111111112; 2097152.0; 125828.0; 0.0; 1.125; 0.0; 0.0 -1376914005; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376914305; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 166372.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376914605; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376914905; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1376915205; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 61513.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376915505; 1; 2599.999343; 28.599992773000004; 1.1; 2097152.0; 77592.4; 0.0; 1.0; 0.1111111111111111; 0.0 -1376915805; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376916105; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 146800.0; 0.0; 6.8; 0.3333333333333333; 0.13333333333333333 -1376916405; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376916705; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1376917005; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376917305; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376917605; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 124429.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376917905; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 199925.33333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376918205; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376918505; 1; 2599.999343; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376918805; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1376919105; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1376919405; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1376919705; 1; 2599.999343; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1376920005; 1; 2599.999343; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1376920306; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376920606; 1; 2599.99945; 25.9999945; 1.0; 2097152.0; 76257.81818181818; 0.0; 1.1; 0.0; 0.0 -1376920906; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376921206; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 11.6; 0.0; 0.0 -1376921506; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 156584.8; 0.0; 2.2; 0.0; 0.4666666666666667 -1376921806; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 130022.13333333333; 0.0; 7.2; 0.4; 0.2 -1376922106; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 159382.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1376922406; 1; 2599.99945; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1376922706; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 -1376923006; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 121633.06666666667; 0.0; 1.0; 0.0; 0.0 -1376923306; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 110448.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376923606; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376923906; 1; 2599.999306; 21.272721594545455; 0.8181818181818181; 2097152.0; 114388.72727272728; 0.0; 1.0; 0.0; 0.0 -1376924206; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1376924506; 1; 2599.999297; 28.88888107777778; 1.1111111111111112; 2097152.0; 88544.44444444444; 0.0; 0.75; 0.0; 0.0 -1376924806; 1; 2599.999334; 28.363629098181818; 1.0909090909090908; 2097152.0; 101042.90909090909; 0.0; 0.8; 0.1; 0.0 -1376925106; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 141206.66666666666; 0.0; 2.2; 1.0; 0.5333333333333333 -1376925406; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 2.066666666666667; 0.0 -1376925706; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.6; 0.06666666666666667; 0.0 -1376926006; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1376926306; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1376926606; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 61513.86666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376926906; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.13333333333333333; 0.0 -1376927206; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1376927506; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1376927806; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1376928106; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1376928406; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1376928706; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 155188.0; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1376929006; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 -1376929306; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376929606; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1376929906; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376930207; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376930507; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376930807; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 134216.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376931107; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.4; 0.0; 0.6; 0.0; 0.0 -1376931407; 1; 2599.999334; 57.19998534800001; 2.2; 2097152.0; 268433.3333333333; 161.0; 21.733333333333334; 0.0; 0.4 -1376931707; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 773148.0; 0.0; 2.6; 0.0; 0.0 -1376932007; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 304784.0; 31.8; 3.2666666666666666; 0.0; 0.0 -1376932307; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 219498.93333333332; 0.0; 3.6; 0.0; 0.4666666666666667 -1376932607; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.6; 0.0; 1.4666666666666666; 0.0; 0.0 -1376932907; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376933207; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 -1376933507; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145400.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376933807; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 -1376934107; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1376934407; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 146799.46666666667; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 -1376934707; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138410.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 -1376935007; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 -1376935307; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1376935607; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1376935907; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 138410.4; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1376936207; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1376936507; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376936807; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376937107; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376937407; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1376937707; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376938007; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1376938307; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1376938607; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.6; 0.06666666666666667; 0.0 -1376938907; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 -1376939208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376939508; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 139809.33333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376939808; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1376940108; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1376940408; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 111846.13333333333; 161.0; 13.266666666666667; 0.0; 0.2 -1376940708; 1; 2599.999334; 38.13332356533333; 1.4666666666666666; 2097152.0; 518693.6; 0.0; 7.933333333333334; 0.26666666666666666; 0.13333333333333333 -1376941008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 225092.53333333333; 31.8; 3.0; 0.0; 0.0 -1376941308; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 219499.73333333334; 0.0; 1.8; 0.0; 0.0 -1376941608; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116040.8; 0.0; 1.2; 0.0; 0.0 -1376941908; 1; 2599.999334; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376942208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376942508; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1376942808; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376943108; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 190139.73333333334; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1376943408; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376943708; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376944008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376944308; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376944608; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376944908; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376945208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376945508; 1; 2599.999334; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376945808; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.4; 0.0 -1376946108; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376946408; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1376946708; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 195732.26666666666; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1376947008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376947309; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1376947609; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376947909; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376948209; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1376948509; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1376948809; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1376949109; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1376949408; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1376949709; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376950009; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1376950309; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 176158.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376950609; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 149594.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376950909; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1376951209; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1376951509; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.13333333333333333; 0.13333333333333333 -1376951809; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376952109; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1376952409; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 114642.93333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1376952709; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376953009; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1376953309; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1376953610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376953910; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 137012.26666666666; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 -1376954210; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1376954510; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376954810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376955110; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376955410; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 -1376955710; 1; 2599.999334; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376956010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 -1376956310; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376956610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376956910; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376957210; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376957510; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 176159.2; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1376957810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 -1376958110; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 8.466666666666667; 0.0 -1376958410; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376958710; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 7.4; 0.26666666666666666; 0.2 -1376959010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 -1376959310; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1376959610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376959910; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1376960210; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1376960510; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376960810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1376961110; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 141205.86666666667; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376961410; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6; 0.06666666666666667; 0.0 -1376961710; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376962010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1376962311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1376962611; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1376962911; 1; 2599.999334; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1376963211; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1376963511; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1376963811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1376964111; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1376964411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 -1376964711; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 153789.86666666667; 0.0; 13.4; 0.06666666666666667; 0.4666666666666667 -1376965011; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376965311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.6; 0.0; 0.0 -1376965611; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1376965911; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1376966211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376966511; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1376966811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1376967111; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 -1376967411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376967711; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1376968011; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 131419.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376968311; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 162177.86666666667; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1376968611; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.06666666666666667; 0.6666666666666666; 0.0; 0.0 -1376968911; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1376969211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1376969511; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1376969811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376970111; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1376970411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 -1376970711; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376971011; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376971311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1376971611; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 130021.6; 12.733333333333333; 13.466666666666667; 0.3333333333333333; 0.2 -1376971911; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 156586.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1376972211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376972512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376972812; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1376973112; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 156585.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1376973412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 149594.93333333332; 0.0; 0.6; 0.0; 0.0 -1376973712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1376974012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.13333333333333333; 0.0 -1376974312; 1; 2599.999626; 28.599995886000002; 1.1; 2097152.0; 62912.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1376974612; 1; 2599.999626; 19.066663923999997; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376974912; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376975212; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 -1376975512; 1; 2599.999626; 19.066663923999997; 0.7333333333333333; 2097152.0; 191537.86666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1376975812; 1; 2599.999334; 28.363629098181818; 1.0909090909090908; 2097152.0; 83884.0; 0.0; 0.9; 0.0; 0.0 -1376976112; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1376976412; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 -1376976712; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 -1376977012; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1376977312; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1376977612; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 6.8; 0.2; 0.13333333333333333 -1376977912; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116040.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1376978212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376978512; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1376978812; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376979112; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 185945.6; 0.0; 2.0; 0.06666666666666667; 0.5333333333333333 -1376979412; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 148197.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1376979712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 -1376980012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376980312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.26666666666666666; 0.13333333333333333 -1376980612; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 146799.2; 0.0; 2.2; 0.06666666666666667; 0.0 -1376980912; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1376981212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376981512; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1376981812; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.2; 0.0 -1376982112; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.6; 0.2; 0.0 -1376982412; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 128623.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1376982712; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 150994.4; 0.06666666666666667; 2.8666666666666667; 2.3333333333333335; 0.4666666666666667 -1376983012; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.06666666666666667; 6.533333333333333; 0.2; 0.13333333333333333 -1376983312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.8; 0.0; 0.0 -1376983612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1376983912; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1376984212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1376984512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1376984812; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111845.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1376985112; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1376985412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1376985712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1376986012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 -1376986312; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 150993.06666666668; 0.0; 2.2666666666666666; 0.13333333333333333; 0.5333333333333333 -1376986612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 144003.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1376986912; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376987212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1376987512; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 1.3333333333333333; 4.0; 0.0; 0.0 -1376987812; 1; 2599.999334; 45.066655122666674; 1.7333333333333334; 2097152.0; 232082.4; 181.86666666666667; 31.2; 0.5333333333333333; 0.4 -1376988112; 1; 2599.999334; 41.59998934400001; 1.6; 2097152.0; 844450.9333333333; 0.0; 5.2; 0.0; 0.0 -1376988412; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 409641.3333333333; 31.8; 3.3333333333333335; 0.0; 0.0 -1376988712; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 244665.33333333334; 0.0; 2.533333333333333; 0.0; 0.0 -1376989012; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 184547.46666666667; 0.0; 7.666666666666667; 0.26666666666666666; 0.2 -1376989312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 174761.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376989612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.2666666666666666; 0.6666666666666666; 0.0 -1376989912; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 192935.73333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1376990212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1376990512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1376990812; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376991112; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1376991412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1376991712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 -1376992012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1376992312; 1; 2599.999334; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1376992612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1376992913; 1; 2599.999334; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1376993213; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104855.73333333334; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 -1376993513; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 178955.2; 0.06666666666666667; 1.8; 0.0; 0.0 -1376993813; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1376994123; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376994423; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1376994724; 1; 2599.999334; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1376995024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1376995324; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 183150.13333333333; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1376995624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1376995924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1376996224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1376996524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1376996824; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.4; 0.06666666666666667; 0.4666666666666667 -1376997124; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 153789.06666666668; 0.0; 1.9333333333333333; 0.0; 0.0 -1376997424; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1376997724; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1376998024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1376998324; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1376998624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1376998924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 149596.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1376999224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.3333333333333333; 0.2; 0.0 -1376999524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1376999824; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.13333333333333333; 0.0 -1377000124; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377000424; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.7333333333333333; 0.4666666666666667 -1377000724; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 149595.46666666667; 0.0; 1.6; 0.0; 0.0 -1377001024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377001324; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 146799.46666666667; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 -1377001624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137012.0; 0.0; 0.8; 0.0; 0.0 -1377001924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377002224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377002524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377002824; 1; 2599.999334; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1377003125; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377003425; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377003725; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377004025; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 124429.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.4666666666666667 -1377004325; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 159382.13333333333; 0.13333333333333333; 1.8666666666666667; 0.06666666666666667; 0.0 -1377004625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377004925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1377005225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1377005525; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377005825; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1377006125; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1377006425; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377006725; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377007025; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377007325; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 -1377007625; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 -1377007925; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 188741.86666666667; 0.06666666666666667; 7.733333333333333; 0.4666666666666667; 0.13333333333333333 -1377008225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.8; 0.0; 0.0 -1377008525; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 11.8; 0.06666666666666667; 0.0 -1377008825; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377009125; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 0.9333333333333333; 0.13333333333333333; 0.06666666666666667 -1377009425; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377009725; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377010025; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 120234.93333333333; 0.0; 0.7333333333333333; 1.0; 0.0 -1377010325; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.0; 0.0; 1.0; 0.2; 0.0 -1377010625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.13333333333333333; 0.0 -1377010925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377011226; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.4666666666666667 -1377011526; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 137013.06666666668; 0.0; 1.7333333333333334; 0.0; 0.0 -1377011826; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377012126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377012426; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377012726; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.06666666666666667; 0.0 -1377013026; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.06666666666666667; 0.0 -1377013326; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 -1377013626; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.2; 0.0 -1377013926; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 176159.2; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1377014226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377014526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377014825; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.06666666666666667; 0.4666666666666667 -1377015125; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 144003.73333333334; 0.0; 1.8666666666666667; 0.0; 0.0 -1377015425; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377015725; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377016025; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 -1377016325; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1377016625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377016925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377017225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377017526; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.2; 0.0 -1377017826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 162177.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377018126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146798.93333333332; 0.0; 0.8; 0.13333333333333333; 0.0 -1377018426; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.4666666666666667 -1377018726; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 171964.8; 0.06666666666666667; 1.9333333333333333; 0.0; 0.0 -1377019026; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377019326; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.06666666666666667; 7.0; 1.4; 0.13333333333333333 -1377019626; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377019926; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377020226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1377020526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377020826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377021126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 -1377021426; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1377021726; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377022026; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.4666666666666667 -1377022326; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 152391.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1377022626; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 120234.93333333333; 0.0; 0.8; 0.0; 0.0 -1377022926; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377023226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377023526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377023826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1377024126; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 -1377024426; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128624.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377024726; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 121633.06666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377025026; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1377025326; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 2.2666666666666666; 0.0 -1377025627; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.13333333333333333; 0.4666666666666667 -1377025927; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 163576.8; 0.0; 7.6; 0.26666666666666666; 0.13333333333333333 -1377026227; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 142605.6; 0.0; 0.6; 0.06666666666666667; 0.0 -1377026527; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 -1377026827; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377027127; 1; 2599.999334; 43.33332223333333; 1.6666666666666665; 2097152.0; 510304.5333333333; 161.0; 14.333333333333334; 0.0; 0.2 -1377027427; 1; 2599.999334; 0.0; 0.0; 2097152.0; 223694.4; 0.0; 1.2; 0.0; 0.0 -1377027727; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 222296.8; 31.8; 3.6; 0.0; 0.0 -1377028027; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 -1377028327; 1; 2599.999334; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377028627; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377028927; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377029227; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 -1377029527; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 201324.0; 0.06666666666666667; 1.7333333333333334; 0.0; 0.0 -1377029827; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377030127; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377030427; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377030727; 1; 2599.999334; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377031027; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377031327; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 124428.8; 12.8; 13.4; 0.3333333333333333; 0.13333333333333333 -1377031627; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 -1377031927; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377032227; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377032527; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377032827; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.4666666666666667 -1377033127; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 160780.53333333333; 0.0; 1.6666666666666667; 0.0; 0.0 -1377033427; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377033727; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377034027; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377034327; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377034627; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377034928; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377035228; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1377035528; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377035828; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1377036128; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377036428; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 162177.86666666667; 0.0; 1.3333333333333333; 0.06666666666666667; 0.4666666666666667 -1377036728; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 233480.8; 0.13333333333333333; 2.066666666666667; 0.0; 0.0 -1377037028; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 141207.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377037328; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 132817.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377037628; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.5333333333333333; 0.0; 0.0 -1377037928; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 120234.66666666667; 0.0; 1.6; 0.13333333333333333; 0.13333333333333333 -1377038229; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1377038529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377038829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377039129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377039429; 1; 2599.999334; 50.266653790666666; 1.9333333333333333; 2097152.0; 225093.06666666668; 161.0; 21.333333333333332; 0.06666666666666667; 0.4 -1377039729; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 724214.9333333333; 0.0; 2.2666666666666666; 0.0; 0.0 -1377040029; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 320164.0; 31.8; 4.0; 0.06666666666666667; 0.4666666666666667 -1377040329; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 229286.4; 0.06666666666666667; 2.2666666666666666; 0.0; 0.0 -1377040629; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.0; 1.8; 0.0; 0.0 -1377040929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377041229; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1377041529; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 120234.66666666667; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 -1377041829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377042129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377042429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.9333333333333333; 0.0; 0.0 -1377042729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377043029; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377043329; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1377043629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 -1377043929; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 153790.66666666666; 0.0; 1.9333333333333333; 0.0; 0.0 -1377044229; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1377044529; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377044829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1377045129; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.4; 0.0; 0.0 -1377045429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377045729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377046029; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377046329; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377046629; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 -1377046929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377047230; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 127225.86666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377047529; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 205517.86666666667; 0.0; 2.1333333333333333; 0.0; 0.0 -1377047829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377048129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377048429; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1377048729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377049029; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377049329; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 -1377049629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1377049929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377050229; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377050529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1377050829; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 72698.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377051129; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 167770.4; 0.0; 1.4666666666666666; 0.0; 0.0 -1377051429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377051729; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377052029; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 17.933333333333334; 0.26666666666666666; 0.13333333333333333 -1377052329; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 -1377052629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377052929; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377053229; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 135614.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377053529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377053830; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377054130; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377054430; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 109050.4; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1377054730; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 146799.2; 0.06666666666666667; 1.6666666666666667; 0.0; 0.0 -1377055030; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377055330; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377055630; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377055930; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377056230; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 -1377056530; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377056830; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1377057130; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104855.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377057430; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377057730; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377058030; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.06666666666666667; 7.2; 0.3333333333333333; 0.6666666666666666 -1377058330; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 176158.4; 0.0; 1.6666666666666667; 0.0; 0.0 -1377058630; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.06666666666666667; 0.0 -1377058930; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 -1377059230; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377059530; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377059830; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377060130; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377060430; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377060730; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377061030; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377061330; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377061631; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.06666666666666667; 0.4666666666666667 -1377061931; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 150994.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1377062231; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8; 0.0; 0.0 -1377062531; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377062831; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377063131; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1377063431; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377063731; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377064031; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1377064331; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 155187.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377064631; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377064931; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377065231; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.4666666666666666; 0.06666666666666667; 0.4666666666666667 -1377065531; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 180353.6; 0.26666666666666666; 1.7333333333333334; 0.0; 0.0 -1377065831; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377066131; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 -1377066431; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1377066731; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.06666666666666667; 0.8666666666666667; 0.06666666666666667; 0.06666666666666667 -1377067031; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.9333333333333333; 0.0; 0.0 -1377067331; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 50328.8; 0.0; 1.4; 0.0; 0.0 -1377067631; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377067931; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.2; 0.0 -1377068231; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.2; 0.0 -1377068531; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.7333333333333334; 0.06666666666666667; 0.0 -1377068831; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.4666666666666667 -1377069131; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 146798.4; 0.0; 1.7333333333333334; 0.0; 0.0 -1377069432; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1377069732; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.6; 0.13333333333333333 -1377070032; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1377070332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377070632; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1377070932; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377071232; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 -1377071532; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377071832; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1377072132; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 -1377072432; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.4666666666666667 -1377072732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 2.2666666666666666; 0.0; 0.0 -1377073032; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377073332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.06666666666666667; 0.0 -1377073632; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1377073932; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377074232; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.6; 0.0; 0.0 -1377074532; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377074832; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377075132; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377075432; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377075732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 -1377076032; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.13333333333; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 -1377076332; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 176159.2; 0.0; 1.6666666666666667; 0.0; 0.0 -1377076632; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377076932; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 141207.46666666667; 0.0; 6.8; 0.2; 0.13333333333333333 -1377077232; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377077532; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377077832; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377078132; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 152390.13333333333; 20.2; 2.3333333333333335; 0.0; 0.06666666666666667 -1377078432; 1; 2599.999334; 24.266660450666663; 0.9333333333333332; 2097152.0; 138410.4; 0.0; 4.133333333333334; 0.0; 0.0 -1377078732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 125827.2; 0.2; 2.466666666666667; 0.0; 0.0 -1377079032; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377079332; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377079632; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 96467.2; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1377079932; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 150993.33333333334; 0.0; 1.4; 0.0; 0.0 -1377080232; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377080532; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377080832; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 92272.8; 0.0; 1.7333333333333334; 0.0; 0.0 -1377081132; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377081432; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377081732; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377082032; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1377082332; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 -1377082632; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377082932; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1377083232; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 124429.33333333333; 0.0; 7.533333333333333; 0.26666666666666666; 0.6666666666666666 -1377083532; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 206916.26666666666; 0.0; 1.8; 0.0; 0.0 -1377083832; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377084132; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377084432; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377084732; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377085032; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377085332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1377085632; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1377085932; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377086232; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377086532; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377086832; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 -1377087132; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 146799.2; 0.0; 1.6; 0.0; 0.0 -1377087432; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 0.8; 0.2; 0.0 -1377087732; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377088032; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377088332; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377088633; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377088933; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377089233; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 131419.73333333334; 12.733333333333333; 13.6; 0.4; 0.13333333333333333 -1377089533; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377089833; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377090133; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377090433; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 -1377090733; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 169169.33333333334; 0.06666666666666667; 1.4; 0.06666666666666667; 0.0 -1377091033; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377091333; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1377091633; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377091933; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377092233; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.6; 0.0; 0.0 -1377092533; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377092833; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377093133; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377093433; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377093733; 1; 2599.999334; 62.399984016; 2.4; 2097152.0; 388670.93333333335; 161.06666666666666; 21.533333333333335; 0.13333333333333333; 0.4 -1377094033; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 581607.7333333333; 0.0; 4.2; 0.06666666666666667; 0.5333333333333333 -1377094333; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 320163.4666666667; 31.8; 4.333333333333333; 0.0; 0.0 -1377094633; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 216703.2; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.13333333333333333 -1377094933; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1377095233; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 142604.53333333333; 0.0; 0.8; 0.0; 0.0 -1377095533; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 150993.6; 0.06666666666666667; 11.866666666666667; 0.06666666666666667; 0.06666666666666667 -1377095833; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 156586.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 -1377096133; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1377096433; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377096733; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377097033; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377097333; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377097633; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.5333333333333333 -1377097933; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 215305.06666666668; 0.0; 1.8; 0.0; 0.0 -1377098234; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377098534; 1; 2599.999334; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377098834; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1377099134; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 -1377099434; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.13333333333333333; 0.0 -1377099734; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377100034; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377100334; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377100634; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.06666666666666667; 0.0 -1377100934; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 3.6666666666666665; 0.0 -1377101234; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.2; 0.4666666666666667 -1377101534; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 156586.13333333333; 0.06666666666666667; 8.2; 0.26666666666666666; 0.13333333333333333 -1377101834; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377102134; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1377102434; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 -1377102734; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377103034; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377103334; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377103634; 1; 2599.999334; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377103934; 1; 2599.999334; 0.0; 0.0; 2097152.0; 54523.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377104234; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377104534; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 88078.4; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1377104834; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.4666666666666667 -1377105134; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 155187.2; 0.0; 0.8; 0.0; 0.0 -1377105434; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 -1377105735; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1377106035; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377106335; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 54523.2; 0.0; 0.6; 0.06666666666666667; 0.0 -1377106635; 1; 2599.999334; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8; 0.0; 0.0 -1377106935; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1377107235; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 74097.06666666667; 0.0; 6.8; 0.26666666666666666; 0.2 -1377107535; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377107835; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377108135; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377108435; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.26666666666; 0.0; 1.4; 0.06666666666666667; 0.4666666666666667 -1377108735; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 187342.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377109035; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377109335; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377109635; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377109935; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1377110235; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377110535; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1377110835; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377111135; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 1.0; 0.0; 0.0 -1377111435; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1377111735; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377112036; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 -1377112336; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 1.8; 0.0; 0.0 -1377112636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377112935; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.5333333333333334; 0.06666666666666667; 0.0 -1377113235; 1; 2599.999334; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377113535; 1; 2599.999334; 46.799988012; 1.8; 2097152.0; 466963.73333333334; 161.2; 20.266666666666666; 0.2; 0.3333333333333333 -1377113835; 1; 2599.999334; 0.0; 0.0; 2097152.0; 255851.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1377114135; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 167771.46666666667; 31.8; 3.6666666666666665; 0.0; 0.0 -1377114435; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377114735; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 134215.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377115035; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377115335; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 47532.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377115635; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 74097.06666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377115935; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 -1377116235; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377116535; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377116835; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 -1377117135; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377117435; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377117735; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1377118036; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377118336; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1377118636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377118936; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377119236; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 9.066666666666666; 0.4; 0.6 -1377119536; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1377119836; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377120136; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377120436; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.2; 0.0 -1377120736; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377121036; 1; 2599.999334; 0.0; 0.0; 2097152.0; 152392.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377121336; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.4; 0.0; 1.0; 0.0; 0.0 -1377121636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377121936; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377122236; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1377122537; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377122837; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 2.1333333333333333; 0.2; 0.4666666666666667 -1377123137; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 185945.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377123437; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377123737; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377124037; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377124337; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 1.6; 0.06666666666666667; 0.13333333333333333 -1377124637; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 -1377124937; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377125237; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 135614.13333333333; 169.73333333333332; 186.0; 0.2; 0.13333333333333333 -1377125537; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 260044.53333333333; 0.0; 0.8; 0.0; 0.0 -1377125837; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377126137; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.7333333333333333; 1.2; 0.0; 0.0 -1377126437; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377126737; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 176158.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1377127037; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377127337; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377127637; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377127937; 1; 2599.999334; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377128237; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377128537; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377128837; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377129137; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377129437; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377129737; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377130037; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 97864.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377130337; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 215304.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377130637; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 167770.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1377130937; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377131237; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377131537; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377131837; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377132138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377132438; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 113244.8; 0.0; 6.8; 0.2; 0.13333333333333333 -1377132738; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377133038; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377133338; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377133638; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1377133938; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377134238; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377134538; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377134838; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377135138; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377135438; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377135738; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 58717.6; 0.0; 1.0; 0.0; 0.0 -1377136038; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1377136338; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377136638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377136938; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377137238; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 -1377137538; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 170565.86666666667; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1377137838; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1377138138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377138438; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377138738; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 124429.86666666667; 0.06666666666666667; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1377139038; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377139338; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 11.8; 0.0; 0.0 -1377139638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377139938; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1377140238; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377140538; 1; 2599.999334; 67.59998268400001; 2.6; 2097152.0; 669688.5333333333; 161.06666666666666; 22.0; 0.06666666666666667; 0.4 -1377140838; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 408244.26666666666; 0.0; 3.533333333333333; 0.0; 0.4666666666666667 -1377141138; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 258645.86666666667; 31.8; 3.533333333333333; 0.0; 0.0 -1377141438; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 149596.0; 0.0; 2.2666666666666666; 0.0; 0.0 -1377141738; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 160781.06666666668; 0.0; 1.9333333333333333; 0.0; 0.0 -1377142038; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 145400.8; 0.0; 0.8; 0.0; 0.0 -1377142338; 1; 2599.999334; 0.0; 0.0; 2097152.0; 148197.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377142638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128624.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377142938; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1377143238; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377143538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377143838; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8; 0.0; 0.0 -1377144138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 -1377144438; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 152391.73333333334; 0.0; 8.4; 0.26666666666666666; 0.6 -1377144738; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377145039; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377145339; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377145638; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1377145938; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377146238; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377146538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377146838; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377147138; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1377147438; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377147738; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377148038; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 2.4; 0.0; 0.5333333333333333 -1377148338; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 173362.93333333332; 0.06666666666666667; 0.7333333333333333; 0.0; 0.0 -1377148638; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377148938; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377149238; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377149538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377149839; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377150139; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377150439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377150739; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377151039; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 173363.46666666667; 12.8; 13.4; 0.26666666666666666; 0.13333333333333333 -1377151339; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 142604.26666666666; 0.0; 1.4; 0.0; 0.0 -1377151639; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.0; 0.0; 2.2; 0.0; 0.4666666666666667 -1377151939; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 209712.26666666666; 0.0; 0.6; 0.0; 0.0 -1377152239; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377152539; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377152839; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377153139; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.13333333333333333 -1377153439; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 164973.86666666667; 0.0; 1.7333333333333334; 0.0; 0.0 -1377153739; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1377154039; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377154339; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1377154639; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 -1377154939; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377155239; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1377155539; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 132817.86666666667; 0.06666666666666667; 1.0; 0.13333333333333333; 0.0 -1377155839; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377156139; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377156439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377156739; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377157039; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377157339; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 8.2; 0.26666666666666666; 0.13333333333333333 -1377157639; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377157939; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.13333333333333333; 0.0 -1377158239; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377158539; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.06666666666666667; 0.0 -1377158839; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 -1377159140; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 178955.46666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377159440; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377159740; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377160040; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377160340; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 -1377160640; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377160940; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377161240; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377161540; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 -1377161840; 1; 2599.999334; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.6; 0.0; 0.0 -1377162140; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 -1377162439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.2; 2.6666666666666665; 0.0; 0.4666666666666667 -1377162739; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 162177.86666666667; 0.0; 0.6; 0.0; 0.0 -1377163039; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1377163339; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 -1377163639; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 -1377163939; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 7.0; 0.2; 0.13333333333333333 -1377164239; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1377164539; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377164840; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377165140; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377165440; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377165740; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377166040; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.53333333334; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377166340; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 184546.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377166640; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377166940; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377167240; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377167540; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377167840; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377168140; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 4.733333333333333; 0.0 -1377168440; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377168740; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377169040; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377169340; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377169640; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 -1377169940; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377170240; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377170540; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377170840; 1; 2599.999334; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377171140; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 -1377171440; 1; 2599.999334; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377171740; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377172041; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1377172341; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377172641; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377172941; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1377173241; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 83884.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377173541; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 159381.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377173841; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377174141; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377174441; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377174741; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377175041; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377175341; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 -1377175641; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377175941; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 149594.66666666666; 0.0; 1.0; 0.0; 0.0 -1377176241; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377176541; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377176841; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377177141; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 142604.8; 0.0; 7.0; 0.26666666666666666; 0.2 -1377177441; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377177741; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377178041; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377178341; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1377178641; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377178941; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1377179241; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377179541; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377179841; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1377180141; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377180441; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 142604.8; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 -1377180741; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 -1377181041; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377181341; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377181641; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377181941; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 -1377182241; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 142604.0; 0.0; 0.8; 0.0; 0.0 -1377182542; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377182842; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 85282.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 -1377183142; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377183442; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 -1377183742; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377184042; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 110448.53333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1377184342; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 155187.2; 0.0; 0.7333333333333333; 0.2; 0.0 -1377184642; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377184942; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377185242; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377185542; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377185842; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1377186142; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 -1377186442; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377186742; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377187042; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377187342; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1377187642; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 88078.4; 0.13333333333333333; 2.4; 0.06666666666666667; 0.4666666666666667 -1377187942; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 -1377188242; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377188542; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1377188842; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377189142; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377189442; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377189742; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377190042; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377190342; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377190643; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.13333333333333333; 0.0 -1377190943; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377191243; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.06666666666666667; 2.1333333333333333; 0.13333333333333333; 0.4666666666666667 -1377191543; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377191843; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377192143; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377192443; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377192743; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377193043; 1; 2599.999297; 27.999992429230765; 1.0769230769230769; 2097152.0; 77431.07692307692; 0.0; 0.8333333333333334; 0.08333333333333333; 0.0 -1377193343; 1; 2599.999297; 17.33332864666667; 0.6666666666666667; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377193643; 1; 2599.999297; 34.66665729333334; 1.3333333333333335; 2097152.0; 100661.06666666667; 161.13333333333333; 20.6; 0.06666666666666667; 0.4 -1377193943; 1; 2599.999297; 55.46665166933333; 2.1333333333333333; 2097152.0; 746584.8; 0.0; 3.6666666666666665; 0.0; 0.0 -1377194243; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 327154.13333333336; 31.8; 3.4; 0.06666666666666667; 0.0 -1377194543; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 181752.53333333333; 0.0; 2.466666666666667; 0.0; 0.0 -1377194843; 1; 2599.999297; 20.799994376; 0.8; 2097152.0; 121633.6; 0.0; 9.2; 0.26666666666666666; 0.6666666666666666 -1377195143; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 181751.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377195443; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1377195743; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1377196043; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377196343; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377196643; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377196943; 1; 2599.999297; 15.599995781999999; 0.6; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377197243; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377197543; 1; 2599.999297; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377197843; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377198143; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 111845.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377198443; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 103457.33333333333; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1377198743; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 157982.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1377199043; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377199343; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1377199643; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 107651.46666666666; 0.0; 0.9333333333333333; 0.2; 0.0 -1377199943; 1; 2599.999297; 45.06665448133334; 1.7333333333333334; 2097152.0; 392864.0; 161.06666666666666; 14.4; 0.06666666666666667; 0.2 -1377200243; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 290802.6666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1377200543; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 243268.0; 31.8; 4.466666666666667; 0.0; 0.0 -1377200843; 1; 2599.999297; 12.133330052666665; 0.4666666666666666; 2097152.0; 171965.06666666668; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1377201143; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1377201443; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377201743; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377202043; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 3.1333333333333333; 0.0; 0.4666666666666667 -1377202343; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 160779.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377202643; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1377202943; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377203243; 1; 2599.999306; 18.571423614285717; 0.7142857142857143; 2097152.0; 101860.0; 0.0; 0.9230769230769231; 1.9230769230769231; 0.0 -1377203543; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377203844; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377204144; 1; 2599.999306; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 1.0; 0.0; 0.0 -1377204444; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377204744; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377205044; 1; 2599.999306; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377205344; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.1333333333333333; 2.466666666666667; 0.0 -1377205644; 1; 2599.999306; 5.199998612000001; 0.2; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377205944; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 170566.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377206244; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.2; 0.0 -1377206844; 1; 2599.999306; 8.666664353333335; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1377207144; 1; 2599.999306; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377207444; 1; 2599.999306; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377208044; 1; 2599.999306; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377208344; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377208644; 1; 2599.999306; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377208944; 1; 2599.999306; 8.666664353333335; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377209245; 1; 2599.999306; 5.199998612000001; 0.2; 2097152.0; 134216.0; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1377209845; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 -1377210145; 1; 2599.999601; 25.99999601; 1.0; 2097152.0; 102059.73333333334; 0.0; 0.8571428571428571; 0.0; 0.0 -1377210445; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377210745; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 130021.6; 0.06666666666666667; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 -1377211045; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1377211345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377211645; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377211945; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377212245; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377212545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377212845; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377213145; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 177557.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377213445; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.13333333333333333 -1377213745; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1377214045; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377214345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377214645; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377214945; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377215245; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 -1377215545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377215845; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377216145; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1377216445; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 99263.46666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377216745; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377217045; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377217345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377217645; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 131419.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377217945; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109049.6; 0.06666666666666667; 1.4666666666666666; 0.0; 0.0 -1377218245; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377218545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377218845; 1; 2599.999601; 12.133331471333332; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 1.0; 0.0; 0.0 -1377219145; 1; 2599.999601; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377219445; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377219745; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1377220045; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 118837.33333333333; 0.13333333333333333; 2.4; 0.0; 0.5333333333333333 -1377220345; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 163576.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377220646; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 85282.13333333333; 0.06666666666666667; 1.7333333333333334; 0.0; 0.0 -1377220946; 1; 2599.999601; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377221246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377221546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377221846; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377222146; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377222446; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377222746; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1377223046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377223346; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377223646; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.8666666666666667; 0.0; 0.4666666666666667 -1377223946; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 141206.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377224246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377224546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377224846; 1; 2599.999601; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377225146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377225446; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377225746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377226046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377226346; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377226646; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 11.733333333333333; 0.0; 0.0 -1377226946; 1; 2599.999601; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377227246; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 107652.0; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1377227546; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 183148.53333333333; 0.0; 1.0; 0.0; 0.0 -1377227846; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377228146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377228446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377228746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377229046; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377229346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1377229646; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 -1377229946; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377230246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377230546; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377230846; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 83884.0; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1377231146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377231446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377231746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377232046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377232346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377232646; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377232946; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 170566.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377233246; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377233547; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 155187.2; 0.2; 6.933333333333334; 0.2; 0.13333333333333333 -1377233847; 1; 2599.999309; 15.166662635833333; 0.5833333333333334; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1377234147; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377234447; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1377234747; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 171964.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377235047; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377235347; 1; 2599.999309; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1377235647; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1377235947; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377236247; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1377236547; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377236847; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 1.0; 0.06666666666666667; 0.0 -1377237147; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1377237447; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1377237747; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 -1377238047; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 -1377238347; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 146798.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377238647; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377238947; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377239247; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 150992.8; 0.0; 6.666666666666667; 0.3333333333333333; 0.13333333333333333 -1377239547; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.06666666666666667 -1377239847; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 121633.6; 0.0; 1.8; 0.0; 0.0 -1377240147; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 149595.46666666667; 0.0; 1.6666666666666667; 0.13333333333333333; 0.0 -1377240447; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.0; 0.0 -1377240747; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377241047; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377241347; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.4; 0.0; 0.0 -1377241647; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 -1377241947; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 192936.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377242247; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377242547; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377242848; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 -1377243148; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377243448; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377243748; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377244048; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377244347; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.06666666666666667; 0.0 -1377244647; 1; 2599.999309; 57.199984798; 2.2; 2097152.0; 736797.0666666667; 161.0; 21.866666666666667; 0.13333333333333333; 0.4 -1377244947; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 394262.4; 0.0; 2.466666666666667; 0.06666666666666667; 0.0 -1377245247; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 247461.6; 32.06666666666667; 4.8; 0.0; 0.4666666666666667 -1377245547; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 197130.4; 0.0; 2.4; 0.06666666666666667; 0.0 -1377245847; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 -1377246147; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 6.666666666666667; 0.3333333333333333; 0.2 -1377246447; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 1.4; 1.2666666666666666; 0.0 -1377246748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377247048; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377247348; 1; 2599.999309; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.6; 0.0; 0.0 -1377247648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377247948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377248248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1377248548; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377248848; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377249148; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 176158.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377249448; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377249748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377250048; 1; 2599.999309; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377250348; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377250648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377250948; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 -1377251248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377251548; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377251848; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377252148; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.06666666666666667; 0.0 -1377252448; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1377252748; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377253048; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377253348; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377253648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1377253948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377254248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377254548; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377254848; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377255148; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377255448; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377255748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377256048; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1377256348; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 1.2; 0.0; 0.0 -1377256648; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377256948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377257249; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377257549; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1377257849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377258149; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377258449; 1; 2599.999309; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377258749; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377259049; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 -1377259349; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377259649; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 -1377259949; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 155186.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1377260249; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 117438.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377260549; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 156585.86666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1377260849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.8666666666666667; 0.0 -1377261149; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 82.06666666666666; 0.0 -1377261449; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377261749; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377262049; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377262349; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1377262649; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377262949; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377263249; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377263549; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 197130.4; 0.0; 1.0; 0.0; 0.0 -1377263849; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377264149; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 -1377264449; 1; 2599.999309; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377264749; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 113244.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377265049; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377265349; 1; 2599.999309; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1377265649; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 116041.06666666667; 0.0; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 -1377265949; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1377266249; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 -1377266549; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377266849; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 107651.73333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377267149; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 188742.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377267449; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 -1377267749; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377268049; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377268349; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 90874.66666666667; 0.06666666666666667; 1.4; 0.06666666666666667; 0.13333333333333333 -1377268649; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377268949; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1377269249; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377269549; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377269849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377270149; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 11.933333333333334; 0.13333333333333333; 0.0 -1377270449; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 93670.4; 0.4666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377270749; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 137012.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377271049; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377271349; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377271649; 1; 2599.999309; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377271950; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377272250; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377272550; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 12.733333333333333; 16.733333333333334; 0.3333333333333333; 0.13333333333333333 -1377272850; 1; 2599.999309; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.6; 0.0; 0.0 -1377273150; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 -1377273450; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377273750; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377274050; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1377274350; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 114642.4; 0.0; 1.0; 0.0; 0.0 -1377274650; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 144002.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377274950; 1; 2599.999309; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377275250; 1; 2599.999309; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377275550; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130021.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377275850; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 132818.4; 0.0; 1.2; 0.0; 0.0 -1377276150; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377276450; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377276750; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377277050; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377277350; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130021.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377277650; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 131420.26666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377277950; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 142604.0; 0.0; 0.8; 0.0; 0.0 -1377278250; 1; 2599.999309; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377278550; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1377278850; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377279150; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 -1377279450; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 128624.26666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 -1377279750; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377280050; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377280350; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377280650; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377280950; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377281250; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 99262.93333333333; 0.0; 2.533333333333333; 0.13333333333333333; 0.4666666666666667 -1377281551; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 171964.0; 0.06666666666666667; 1.0666666666666667; 0.06666666666666667; 0.0 -1377281851; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 153790.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377282151; 1; 2599.999309; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 -1377282451; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377282751; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377283051; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377283351; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 178955.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377283651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377283951; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377284251; 1; 2599.999309; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.13333333333333333; 0.0 -1377284551; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 65708.26666666666; 0.0; 0.8; 0.0; 0.0 -1377284851; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377285151; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 159382.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377285451; 1; 2599.999309; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377285751; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377286051; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1377286351; 1; 2599.999309; 38.13332319866666; 1.4666666666666666; 2097152.0; 430614.4; 161.53333333333333; 14.333333333333334; 0.0; 0.2 -1377286651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 394262.6666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1377286951; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 197129.86666666667; 31.8; 3.933333333333333; 0.0; 0.0 -1377287251; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 155187.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 -1377287551; 1; 2599.999309; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377287851; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377288151; 1; 2599.999309; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377288451; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 139808.8; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377288751; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 181750.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377289051; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 -1377289351; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377289651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377289951; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377290251; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377290551; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377290852; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.6666666666666667; 0.0; 0.0 -1377291152; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377291452; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377291752; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 110448.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377292052; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 139808.26666666666; 0.0; 8.466666666666667; 0.3333333333333333; 0.6 -1377292352; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 177556.0; 0.0; 1.2; 0.0; 0.0 -1377292652; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 149596.26666666666; 0.0; 0.8; 0.0; 0.0 -1377292952; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377293251; 1; 2599.999309; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377293551; 1; 2599.999309; 55.46665192533332; 2.1333333333333333; 2097152.0; 268433.6; 161.0; 21.533333333333335; 0.06666666666666667; 0.4 -1377293851; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 717224.2666666667; 0.0; 2.6666666666666665; 0.0; 0.0 -1377294151; 1; 2599.999309; 12.133330108666664; 0.4666666666666666; 2097152.0; 317366.93333333335; 31.8; 3.6; 0.0; 0.0 -1377294451; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 212508.53333333333; 0.0; 2.1333333333333333; 0.0; 0.0 -1377294751; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 121633.6; 0.0; 1.8; 0.0; 0.0 -1377295051; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 -1377295352; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377295652; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1377295952; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 153789.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377296252; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 -1377296552; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377296852; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377297152; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 -1377297452; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1377297752; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377298052; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377298352; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377298652; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377298952; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377299252; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 127225.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377299552; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 166371.73333333334; 0.0; 0.8; 0.0; 0.0 -1377299852; 1; 2599.999309; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377300152; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377300452; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377300752; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377301052; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.26666666666666666; 0.0 -1377301352; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377301652; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377301952; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377302252; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377302552; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1377302852; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1377303152; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 188741.6; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1377303452; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377303752; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377304052; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377304352; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 157984.26666666666; 0.06666666666666667; 1.4; 0.0; 0.0 -1377304652; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377304953; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 -1377305253; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1377305553; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377305853; 1; 2599.999309; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1377306153; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377306453; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377306753; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377307053; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 120234.66666666667; 0.0; 0.8; 0.0; 0.0 -1377307353; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 -1377307653; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377307953; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1377308253; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1377308553; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377308853; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377309153; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1377309453; 1; 2599.999309; 0.0; 0.0; 2097152.0; 149596.0; 0.0; 0.6; 0.0; 0.0 -1377309753; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 114642.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377310053; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 121633.33333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377310353; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 171965.06666666668; 0.0; 1.2; 0.0; 0.0 -1377310653; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377310953; 1; 2599.999309; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 -1377311253; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 -1377311553; 1; 2599.999309; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377311853; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377312153; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377312453; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377312753; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6; 0.0; 0.0 -1377313053; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377313353; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377313653; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 162178.13333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1377313953; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 164974.4; 0.0; 11.6; 0.0; 0.0 -1377314253; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377314553; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377314853; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377315154; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377315454; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377315754; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 139807.73333333334; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 -1377316054; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 -1377316354; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 -1377316654; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 -1377316954; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377317254; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 124429.6; 0.13333333333333333; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377317554; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 180353.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377317854; 1; 2599.999309; 0.0; 0.0; 2097152.0; 144003.2; 0.0; 0.8; 0.0; 0.0 -1377318154; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377318454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1377318754; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377319054; 1; 2599.999309; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1377319354; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1377319654; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377319954; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377320254; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377320554; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377320854; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.06666666666666667; 2.0; 0.06666666666666667; 0.4666666666666667 -1377321154; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 171963.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377321454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377321754; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377322054; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 128624.26666666666; 0.0; 6.6; 0.26666666666666666; 0.13333333333333333 -1377322354; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 -1377322655; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1377322955; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377323255; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1377323555; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377323855; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377324155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377324455; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 109050.4; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1377324755; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377325055; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377325355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377325655; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377325955; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.06666666666666667 -1377326255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 146799.2; 0.0; 1.9333333333333333; 0.0; 0.0 -1377326554; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 134216.8; 0.0; 1.7333333333333334; 0.0; 0.0 -1377326854; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1377327154; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377327454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377327755; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377328055; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 134216.8; 0.06666666666666667; 8.6; 0.26666666666666666; 0.6 -1377328355; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 146800.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377328655; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377328955; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377329255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377329555; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377329855; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377330155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1377330455; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 -1377330755; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377331055; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377331355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377331655; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.06666666666666667; 1.9333333333333333; 0.13333333333333333; 0.5333333333333333 -1377331955; 1; 2599.999309; 12.133330108666664; 0.4666666666666666; 2097152.0; 176158.4; 0.0; 1.0; 0.0; 0.0 -1377332255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377332555; 1; 2599.999309; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377332855; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377333155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377333455; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377333755; 1; 2599.999309; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377334055; 1; 2599.999309; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377334355; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 132818.66666666666; 12.733333333333333; 14.066666666666666; 0.3333333333333333; 0.2 -1377334655; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 -1377334955; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377335255; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 2.6666666666666665; 0.0; 0.4666666666666667 -1377335555; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 150993.6; 0.0; 1.7333333333333334; 0.0; 0.0 -1377335855; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377336155; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377336455; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377336755; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1377337055; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377337355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377337655; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377337955; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377338255; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377338555; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1377338855; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377339156; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377339456; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 -1377339756; 1; 2599.999309; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377340056; 1; 2599.999309; 0.0; 0.0; 2097152.0; 57319.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377340356; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377340656; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377340956; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377341256; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377341556; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377341856; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377342156; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377342456; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 107652.0; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377342756; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 180353.6; 0.0; 1.0; 0.0; 0.0 -1377343056; 1; 2599.999309; 64.13331628866666; 2.466666666666667; 2097152.0; 328552.5333333333; 161.06666666666666; 21.533333333333335; 0.2; 0.4 -1377343356; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 658504.0; 0.0; 2.533333333333333; 0.0; 0.0 -1377343656; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 268433.6; 31.8; 3.7333333333333334; 0.0; 0.0 -1377343956; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 167771.2; 0.0; 2.1333333333333333; 0.0; 0.0 -1377344256; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1377344556; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 1.0; 0.0; 0.0 -1377344856; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377345156; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377345456; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377345756; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377346056; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 -1377346356; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 159381.6; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1377346656; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377346956; 1; 2599.999309; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1377347256; 1; 2599.999601; 11.999998158461537; 0.4615384615384615; 2097152.0; 79044.30769230769; 0.0; 0.9166666666666666; 0.0; 0.0 -1377347556; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 107652.26666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 -1377347856; 1; 2599.99931; 25.9999931; 1.0; 2097152.0; 116840.0; 0.0; 0.8461538461538461; 0.0; 0.0 -1377348156; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377348456; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377348757; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377349057; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377349357; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 -1377349657; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 142605.06666666668; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377349957; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 162178.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377350257; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377350557; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1377350857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377351157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377351457; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377351757; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 139808.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377352057; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377352357; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377352657; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377352957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377353257; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1377353557; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 169169.33333333334; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1377353857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377354157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377354457; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377354757; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.06666666666666667; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 -1377355057; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377355357; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.8; 0.26666666666666666; 0.0 -1377355657; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 -1377355957; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377356257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1377356557; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377356857; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 2.2; 0.0; 0.4666666666666667 -1377357157; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 146798.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1377357457; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 11.933333333333334; 0.0; 0.0 -1377357757; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377358057; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1377358357; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377358658; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1377358957; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1377359257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1377359557; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377359857; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377360157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1377360457; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1377360757; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377361057; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377361357; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377361657; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377361957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377362257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1377362557; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377362857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 -1377363157; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377363457; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377363757; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.0; 0.0 -1377364057; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 103457.06666666667; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 -1377364357; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 164974.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377364657; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1377364957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377365257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377365558; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377365858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377366158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377366458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377366758; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 145401.06666666668; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 -1377367058; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377367358; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377367658; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377367958; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377368258; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377368558; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377368858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.5333333333333333; 0.0; 0.0 -1377369158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377369458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.6666666666666666; 0.26666666666666666; 0.0 -1377369758; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.9333333333333333; 0.0 -1377370058; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 -1377370358; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377370658; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377370958; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 -1377371258; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 86680.26666666666; 0.0; 2.4; 0.0; 0.4666666666666667 -1377371558; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 174761.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 -1377371858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377372158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377372458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377372758; 1; 2599.99931; 41.59998896; 1.6; 2097152.0; 369097.3333333333; 161.0; 14.266666666666667; 0.0; 0.2 -1377373058; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 426419.2; 0.0; 7.2; 0.2; 0.13333333333333333 -1377373358; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 208315.46666666667; 31.8; 3.4; 0.06666666666666667; 0.0 -1377373658; 1; 2599.99931; 0.0; 0.0; 2097152.0; 178954.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1377373958; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377374259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1377374559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377374859; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1377375159; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.8; 0.0; 0.0 -1377375459; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377375759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377376059; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377376359; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377376659; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377376959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377377259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377377559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377377859; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377378159; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96467.2; 0.6666666666666666; 1.5333333333333334; 0.0; 0.0 -1377378459; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 100661.33333333333; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1377378759; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159381.86666666667; 0.0; 0.8; 0.0; 0.0 -1377379059; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377379359; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 75495.2; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 -1377379659; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1377379959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.5333333333333334; 0.0; 0.0 -1377380259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377380559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377380859; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377381159; 1; 2599.99931; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.8; 0.0; 0.0 -1377381459; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377381759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377382059; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99262.66666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377382359; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 184547.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377382659; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377382959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377383259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377383559; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 -1377383859; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1377384159; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377384459; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377384759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377385059; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1377385360; 1; 2599.99931; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 0.6; 0.0; 0.0 -1377385660; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138411.2; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1377385960; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377386260; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377386560; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1377386860; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8; 0.0; 0.0 -1377387160; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 0.8; 0.0; 0.0 -1377387460; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377387760; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377388060; 1; 2599.99931; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.0; 0.0; 0.0 -1377388360; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377388660; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377388960; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 -1377389260; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 130021.86666666667; 0.0; 2.8; 0.0; 0.4666666666666667 -1377389560; 1; 2599.99931; 0.0; 0.0; 2097152.0; 178954.13333333333; 0.0; 0.8; 0.0; 0.0 -1377389860; 1; 2599.99931; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 -1377390160; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377390460; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377390760; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 61513.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1377391060; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377391360; 1; 2599.99931; 57.19998482000001; 2.2; 2097152.0; 357911.73333333334; 161.0; 21.733333333333334; 0.06666666666666667; 0.3333333333333333 -1377391660; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 665494.4; 0.0; 2.2666666666666666; 0.0; 0.0 -1377391961; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 247461.06666666668; 44.6; 15.8; 0.3333333333333333; 0.2 -1377392261; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 178954.66666666666; 0.0; 2.466666666666667; 0.0; 0.0 -1377392561; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1377392861; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.33333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377393161; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 174760.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377393461; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 -1377393761; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.0; 0.0 -1377394061; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 -1377394361; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377394661; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 -1377394961; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377395261; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1377395561; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 -1377395861; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377396161; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377396461; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 120235.46666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377396761; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 162178.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377397061; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377397361; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.2; 0.0; 0.0 -1377397661; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377397961; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377398261; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377398561; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 148197.06666666668; 0.0; 7.2; 0.2; 0.13333333333333333 -1377398861; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377399161; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377399461; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377399761; 1; 2599.99931; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377400061; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 71300.8; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1377400362; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377400662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377400962; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 11.733333333333333; 0.0; 0.0 -1377401262; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377401562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377401862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377402162; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377402462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377402762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1377403062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377403362; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377403662; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 148197.33333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377403962; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 205519.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377404262; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1377404562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377404862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377405162; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377405462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377405762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 -1377406062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377406362; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1377406662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377406962; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377407262; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 83884.0; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1377407562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.06666666666666667; 1.0666666666666667; 0.0; 0.0 -1377407862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377408162; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377408462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377408762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377409062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377409362; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377409662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377409962; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 -1377410262; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377410562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377410862; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 159382.4; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.6 -1377411162; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377411462; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1377411763; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377412063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377412363; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 -1377412663; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 2.066666666666667; 0.0; 0.0 -1377412963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.4666666666666666; 0.0; 0.0 -1377413263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1377413563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 61513.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377413863; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377414163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377414463; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 -1377414763; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 176158.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377415063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377415363; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377415663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377415963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377416263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377416563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 -1377416863; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1377417163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377417463; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1377417763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377418063; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 90874.66666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377418363; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377418663; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377418963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104855.2; 0.0; 0.8; 0.0; 0.0 -1377419263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377419564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377419864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377420164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377420464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377420764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1377421064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377421364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377421664; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 125827.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377421964; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 205519.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377422264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377422564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.8; 0.0; 0.0 -1377422864; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377423164; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377423464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377424064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377424364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.6; 0.0; 0.0 -1377424663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377424963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377425263; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.06666666666666667; 2.933333333333333; 0.0; 0.4666666666666667 -1377425563; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377425863; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377426163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377426463; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1377426763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377427063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377427363; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377427663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377427963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377428263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377428563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8; 0.0; 0.0 -1377428863; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 81087.73333333334; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 -1377429163; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377429463; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377429763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377430063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377430363; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377430664; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1377430964; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377431264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.2; 0.0; 0.0 -1377431564; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377431864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377432164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 -1377432464; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377432764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 -1377433064; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 156585.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377433364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377433664; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377433964; 1; 2599.99931; 0.0; 0.0; 2097152.0; 166372.26666666666; 0.0; 0.8; 0.0; 0.0 -1377434264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125826.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377434564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1377434864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377435164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1377435464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377435764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377436064; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377436364; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 195731.46666666667; 0.0; 1.2; 0.0; 0.0 -1377436664; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377436964; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377437264; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 -1377437564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377437864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377438164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377438464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377438764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.5333333333333333; 0.0; 0.0 -1377439064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377439364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377439664; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138411.2; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1377439964; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 157984.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377440264; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377440564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377440864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377441164; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.06666666666666667; 0.06666666666666667 -1377441464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 0.8; 0.0; 0.0 -1377441764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1377442064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377442364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 -1377442665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.5333333333333333; 0.0; 0.0 -1377442965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377443265; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 -1377443565; 1; 2599.99931; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377443865; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377444165; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1377444465; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 -1377444765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.0; 11.533333333333333; 0.0; 0.0 -1377445065; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377445365; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377445665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377445965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377446265; 1; 2599.99931; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377446565; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1377446865; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 144002.4; 0.0; 1.9333333333333333; 0.0; 0.4666666666666667 -1377447165; 1; 2599.99931; 62.39998344000001; 2.4; 2097152.0; 454381.6; 161.0; 21.733333333333334; 0.0; 0.4 -1377447465; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 671087.2; 0.0; 2.533333333333333; 0.0; 0.0 -1377447765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 264238.93333333335; 31.8; 3.3333333333333335; 0.0; 0.0 -1377448065; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 150993.33333333334; 0.0; 2.2666666666666666; 0.0; 0.0 -1377448365; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1377448665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1377448965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 -1377449265; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159382.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377449565; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 -1377449865; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377450165; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 130021.86666666667; 12.733333333333333; 13.333333333333334; 0.3333333333333333; 0.13333333333333333 -1377450465; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 233481.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 -1377450765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 194334.66666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1377451065; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377451365; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1377451665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377451965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377452265; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377452566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377452866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1377453166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1377453466; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377453766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377454066; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.4; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1377454366; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 171964.53333333333; 0.0; 0.8; 0.0; 0.0 -1377454666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377454966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377455266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377455566; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377455866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377456166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377456466; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377456766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1377457066; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 141207.46666666667; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1377457366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377457666; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377457966; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 174760.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377458266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377458566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377458866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377459166; 1; 2599.99931; 36.39999034; 1.4; 2097152.0; 297793.6; 161.0; 14.333333333333334; 0.0; 0.13333333333333333 -1377459466; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 466963.2; 0.0; 1.0; 0.0; 0.0 -1377459766; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 211110.66666666666; 31.8; 3.8; 0.0; 0.0 -1377460066; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 169169.06666666668; 0.0; 1.0; 0.0; 0.0 -1377460366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377460666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377460966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 -1377461266; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 120234.66666666667; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 -1377461566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 173362.4; 0.0; 0.8; 0.0; 0.0 -1377461866; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 0.5333333333333333; 0.0; 0.0 -1377462166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1377462466; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 76893.33333333333; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 -1377462766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1377463066; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377463366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377463666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1377463966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 -1377464266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377464566; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 -1377464866; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 2.2; 0.0; 0.4666666666666667 -1377465167; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 -1377465467; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377465767; 1; 2599.99931; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1377466067; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 -1377466367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377466667; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377466967; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377467267; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104855.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377467567; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377467867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377468167; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377468467; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1377468767; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 144002.13333333333; 0.0; 0.6; 0.0; 0.0 -1377469067; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1377469367; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 137013.06666666668; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1377469667; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377469967; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.4; 0.06666666666666667; 0.06666666666666667 -1377470267; 1; 2599.99931; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 -1377470567; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1377470867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1377471167; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377471467; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377471767; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377472067; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128624.26666666666; 0.2; 2.8; 0.0; 0.4666666666666667 -1377472367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377472667; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377472967; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377473267; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377473567; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377473867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377474167; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.0; 0.0; 0.0 -1377474467; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1377474767; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 -1377475067; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377475367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377475667; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96466.93333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377475967; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 176158.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377476267; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377476567; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377476867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377477168; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1377477468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377477768; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377478068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377478368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377478668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377478968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377479268; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1377479568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377479868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377480168; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377480468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377480768; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1377481068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377481368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377481668; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377481968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377482268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377482568; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377482868; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1377483168; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 145401.86666666667; 0.0; 1.0; 0.0; 0.0 -1377483468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377483768; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377484068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377484368; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377484668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1377484968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377485268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377485568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 160780.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377485868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377486168; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 85282.13333333333; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 -1377486468; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.2; 0.0; 0.4666666666666667 -1377486768; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 190139.73333333334; 0.0; 0.8; 0.0; 0.0 -1377487068; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377487368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111845.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377487668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377487968; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377488269; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 -1377488569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377488869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1377489169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377489469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377489769; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.6666666666666667; 0.0; 0.0 -1377490068; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1377490368; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 180353.6; 0.0; 1.0; 0.0; 0.0 -1377490668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.8; 0.0; 0.0 -1377490968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377491268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377491568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377491868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377492168; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377492468; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.0; 0.0 -1377492768; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377493068; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1377493368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1377493668; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1377493968; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 176157.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377494268; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377494569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377494869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377495169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377495469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377495769; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1377496069; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377496369; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377496669; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377496969; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1377497269; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107651.46666666666; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1377497569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377497869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377498169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377498469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377498769; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 61513.86666666667; 0.06666666666666667; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 -1377499069; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 58717.6; 0.0; 1.8; 0.0; 0.0 -1377499369; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.5333333333333334; 0.0; 0.0 -1377499669; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 6.8; 0.2; 0.13333333333333333 -1377499969; 1; 2599.99931; 60.666650566666675; 2.3333333333333335; 2097152.0; 359311.4666666667; 161.0; 21.733333333333334; 0.06666666666666667; 0.4 -1377500269; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 654309.6; 0.0; 2.6; 0.0; 0.0 -1377500569; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 310376.8; 31.8; 3.4; 0.0; 0.0 -1377500869; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 192935.2; 0.0; 3.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1377501169; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 192936.0; 0.0; 1.8666666666666667; 0.0; 0.0 -1377501470; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377501770; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377502070; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377502370; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377502670; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.0; 0.06666666666666667; 0.0 -1377502970; 1; 2599.99931; 36.39999034; 1.4; 2097152.0; 92272.8; 0.0; 1.2; 104.86666666666666; 0.0 -1377503270; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377503570; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377503870; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.4; 0.0 -1377504170; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377504470; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99262.66666666667; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1377504770; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 0.8; 0.0; 0.0 -1377505070; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.06666666666666667; 0.0 -1377505370; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1377505670; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377505970; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377506270; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377506570; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377506870; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377507170; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377507470; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377507770; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 -1377508070; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 142605.6; 0.13333333333333333; 2.466666666666667; 0.0; 0.4666666666666667 -1377508370; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 142605.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377508670; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1377508970; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377509270; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377509570; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1377509870; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377510170; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377510470; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377510771; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377511071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377511371; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 152391.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377511671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.06666666666666667; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 -1377511971; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 156586.13333333333; 12.733333333333333; 12.933333333333334; 0.4666666666666667; 0.2 -1377512271; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377512571; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1377512871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377513171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377513471; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.4; 0.0; 0.0 -1377513771; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377514071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377515571; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377515871; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 -1377516171; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1377516471; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377516771; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 3.1333333333333333; 0.0 -1377517071; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1377517371; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377517671; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377517971; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377518271; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 -1377518571; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 -1377518871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1377519171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 169168.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377519472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377519772; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377520072; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377520372; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377520672; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377520972; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377521272; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377521572; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 134216.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377521872; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1377522172; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.6; 0.0; 0.0 -1377522472; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377522771; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 204121.06666666668; 0.0; 0.8; 0.0; 0.0 -1377523071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377523371; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377523671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377523971; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377524271; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.6666666666666667; 0.0; 0.0 -1377524571; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 100661.6; 0.0; 7.4; 0.6; 0.2 -1377524871; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377525171; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377525471; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 -1377525771; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377526071; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1377526371; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377526671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377526971; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377527271; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377527571; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 -1377527871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377528171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377528472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377528772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.5333333333333333; 0.0 -1377529072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377529372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377529672; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 150992.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377529972; 1; 2599.99931; 0.0; 0.0; 2097152.0; 171965.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377530272; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377530572; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 6.6; 0.2; 0.13333333333333333 -1377530872; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377531172; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377531472; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1377531772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 150994.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377532072; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 12.066666666666666; 0.06666666666666667; 0.0 -1377532372; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 1.8; 0.0 -1377532672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 2.2666666666666666; 0.0 -1377532972; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377533272; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 121633.6; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1377533572; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1377533872; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377534172; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 4.2; 0.0 -1377534472; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377534772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377535072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377535372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1377535672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377535972; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 -1377536272; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377536572; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377536872; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.46666666666; 0.13333333333333333; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377537172; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 155188.0; 0.0; 7.2; 0.2; 0.13333333333333333 -1377537472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377537772; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377538072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1377538372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 2.2666666666666666; 0.0 -1377538672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377538972; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377539272; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377539572; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 -1377539873; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 142604.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1377540173; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1377540473; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1377540773; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 169169.33333333334; 0.0; 0.8; 0.0; 0.0 -1377541073; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377541373; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377541673; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377541973; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 111846.13333333333; 0.0; 0.8; 0.6; 0.0 -1377542273; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 -1377542573; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8; 3.2; 0.0 -1377542873; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1377543173; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377543473; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 173363.2; 0.0; 6.8; 0.2; 0.13333333333333333 -1377543773; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377544073; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1377544373; 1; 2599.99931; 0.0; 0.0; 2097152.0; 156585.33333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377544673; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377544973; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8; 0.0; 0.0 -1377545273; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377545573; 1; 2599.99931; 50.26665332666667; 1.9333333333333333; 2097152.0; 233481.6; 161.2; 14.6; 0.06666666666666667; 0.2 -1377545873; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 486537.06666666665; 0.0; 1.2666666666666666; 0.0; 0.0 -1377546173; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 208314.66666666666; 31.8; 3.6666666666666665; 0.0; 0.0 -1377546473; 1; 2599.99931; 0.0; 0.0; 2097152.0; 201324.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1377546773; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377547073; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377547373; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377547673; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377547973; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 190140.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377548273; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377548573; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 1.8666666666666667; 0.0 -1377548873; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 -1377549173; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1377549473; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377549774; 1; 2599.99931; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1377550074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377550374; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377550674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377550974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377551274; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 132817.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377551574; 1; 2599.99931; 60.666650566666675; 2.3333333333333335; 2097152.0; 423622.93333333335; 161.0; 21.6; 0.5333333333333333; 0.4 -1377551874; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 608172.0; 0.0; 2.533333333333333; 0.0; 0.0 -1377552174; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 232082.13333333333; 31.8; 3.533333333333333; 0.0; 0.0 -1377552474; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 149595.2; 0.0; 2.533333333333333; 0.0; 0.0 -1377552774; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 116041.06666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1377553074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377553374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377553674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.33333333333; 0.0; 1.2; 0.0; 0.0 -1377553974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377554274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377554574; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 1.5333333333333334; 0.0 -1377554874; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 2.4; 0.0; 0.4666666666666667 -1377555174; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.0; 0.0; 1.2; 0.06666666666666667; 0.0 -1377555474; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377555774; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1377556074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377556374; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.06666666666666667; 1.8; 0.13333333333333333; 0.06666666666666667 -1377556674; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377556974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1377557274; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377557574; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377557874; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.9333333333333333; 0.0; 0.0 -1377558174; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377558474; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106253.6; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377558774; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 157984.0; 0.0; 0.8; 0.0; 0.0 -1377559074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1377559374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377559674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377559974; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377560274; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377560574; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377560874; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1377561174; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377561474; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377561774; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1377562074; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.73333333334; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1377562374; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 148197.06666666668; 0.0; 0.7333333333333333; 0.0; 0.0 -1377562674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377562974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377563274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377563574; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1377563874; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377564174; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377564474; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377564774; 1; 2599.99931; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377565074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377565374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377565674; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 123031.2; 0.06666666666666667; 2.0; 0.06666666666666667; 0.4666666666666667 -1377565974; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 177557.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1377566274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377566574; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377566874; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377567175; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1377567475; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377567775; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377568075; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377568375; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377568675; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377568975; 1; 2599.99931; 0.0; 0.0; 2097152.0; 148198.13333333333; 0.0; 1.2; 0.0; 0.0 -1377569275; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102059.73333333334; 0.2; 2.066666666666667; 0.0; 0.4666666666666667 -1377569575; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 164974.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 -1377569875; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377570175; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1377570475; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377570775; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377571075; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377571375; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377571675; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 96466.93333333333; 0.0; 1.0; 0.0; 0.0 -1377571975; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377572275; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377572575; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377572875; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 162177.86666666667; 12.8; 14.466666666666667; 0.4; 0.6 -1377573175; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 152391.73333333334; 0.0; 1.4; 0.0; 0.0 -1377573475; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377573776; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377574076; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377574376; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377574676; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377574976; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377575276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377575576; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128624.26666666666; 0.0; 11.8; 0.0; 0.0 -1377575876; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377576176; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1377576476; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102058.66666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377576776; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 170566.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 -1377577076; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 -1377577376; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1377577676; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377577976; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377578276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377578576; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377578876; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 97865.33333333333; 0.0; 7.066666666666666; 0.4; 0.13333333333333333 -1377579176; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 148196.53333333333; 0.0; 0.8; 0.0; 0.0 -1377579476; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377579776; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377580076; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113243.73333333334; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1377580376; 1; 2599.99931; 0.0; 0.0; 2097152.0; 198528.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377580676; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377580976; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377581276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377581576; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377581876; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377582176; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377582476; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377582776; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1377583077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107651.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377583377; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 65708.26666666666; 0.06666666666666667; 1.2; 0.0; 0.0 -1377583677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 92272.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1377583977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377584277; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377584577; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377584877; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 -1377585177; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.8666666666666667; 0.26666666666666666; 0.06666666666666667 -1377585477; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 145401.06666666668; 0.0; 1.5333333333333334; 0.0; 0.0 -1377585777; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1377586077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377586377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377586677; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1377586977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377587277; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.0; 0.0; 2.2; 0.2; 0.4666666666666667 -1377587577; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 170566.13333333333; 0.0; 0.6; 0.26666666666666666; 0.0 -1377587877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 -1377588177; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159382.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377588477; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 132818.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1377588776; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 148198.13333333333; 0.0; 0.6; 0.13333333333333333; 0.0 -1377589076; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377589376; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1377589676; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1377589976; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 5.2; 0.0 -1377590277; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 118837.33333333333; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 -1377590577; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377590877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.8; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377591177; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 181751.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1377591477; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.6; 0.13333333333333333; 0.0 -1377591777; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377592077; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1377592377; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377592677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377592977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 149595.46666666667; 0.0; 0.6; 0.0; 0.0 -1377593277; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377593577; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377593877; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377594177; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 -1377594477; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.2; 2.066666666666667; 0.13333333333333333; 0.4666666666666667 -1377594777; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.5333333333333333; 0.0 -1377595077; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.6; 9.4; 0.0 -1377595377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377595677; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377595977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377596277; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 6.8; 0.3333333333333333; 0.13333333333333333 -1377596577; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377596877; 1; 2599.99931; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377597177; 1; 2599.99931; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.8; 0.0; 0.0 -1377597477; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377597777; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1377598077; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 2.4; 0.0; 0.5333333333333333 -1377598377; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 137012.26666666666; 0.06666666666666667; 0.9333333333333333; 1.2666666666666666; 0.0 -1377598677; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 -1377598977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 -1377599277; 1; 2599.99931; 64.13331631333334; 2.466666666666667; 2097152.0; 603977.0666666667; 161.0; 22.8; 0.0; 0.4 -1377599577; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 394262.4; 0.0; 4.8; 0.0; 0.0 -1377599877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 190140.0; 31.8; 3.533333333333333; 0.0; 0.0 -1377600177; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 156586.13333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.0 -1377600477; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.5333333333333334; 0.0; 0.0 -1377600777; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377601077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377601377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377601677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 2.0; 0.0; 0.4666666666666667 -1377601977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377602278; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 113244.8; 0.0; 1.8666666666666667; 0.0; 0.0 -1377602578; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377602878; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1377603178; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377603478; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377603778; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377604078; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 -1377604378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 1.1333333333333333; 0.0 -1377604678; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 2.6666666666666665; 0.0 -1377604978; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377605278; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121632.8; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 -1377605578; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 187343.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1377605878; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377606178; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377606478; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377606778; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377607078; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377607378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377607678; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 74097.06666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1377607978; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377608278; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.7333333333333333; 0.0 -1377608578; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377608878; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 138410.4; 0.06666666666666667; 2.2666666666666666; 80.73333333333333; 0.4666666666666667 -1377609178; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 170566.66666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1377609478; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138410.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377609778; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377610078; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377610378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1377610678; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377610978; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377611278; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377611578; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377611878; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377612178; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 142604.8; 0.0; 0.8; 10.6; 0.0 -1377612478; 1; 2599.998991; 40.44442874888888; 1.5555555555555554; 2097152.0; 130486.66666666667; 0.0; 3.875; 0.125; 0.875 -1377612778; 1; 2599.998991; 19.066659267333332; 0.7333333333333333; 2097152.0; 201324.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377613078; 1; 2599.998991; 17.33332660666667; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377613378; 1; 2599.999334; 25.99999334; 1.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1377613678; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377613978; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.13333333333333333; 0.13333333333333333 -1377614279; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377614579; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 -1377614879; 1; 2599.999602; 34.666661360000006; 1.3333333333333335; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1377615179; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377615479; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377615779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1377616079; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 150993.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 -1377616379; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 184547.2; 0.0; 1.0; 0.06666666666666667; 0.0 -1377616679; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377616979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377617279; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377617579; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377617879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8; 0.06666666666666667; 0.0 -1377618179; 1; 2599.999602; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377618479; 1; 2599.999602; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.2; 0.0; 0.0 -1377618779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377619079; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377619379; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 11.733333333333333; 0.0; 0.0 -1377619679; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 -1377619979; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 153789.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377620279; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377620579; 1; 2599.999602; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377620879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377621179; 1; 2599.999602; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377621479; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 90874.66666666667; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1377621779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377622079; 1; 2599.999602; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377622379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377622679; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377622979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377623279; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 121633.6; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1377623579; 1; 2599.999602; 0.0; 0.0; 2097152.0; 171964.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377623879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377624179; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 -1377624479; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377624779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377625079; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377625379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377625679; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 150994.4; 0.0; 0.9333333333333333; 0.6; 0.0 -1377625979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8; 0.0; 0.0 -1377626279; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377626579; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377626879; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1377627179; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 -1377627479; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159381.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377627779; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 113244.8; 0.0; 7.266666666666667; 0.26666666666666666; 0.2 -1377628079; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377628379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377628679; 1; 2599.999602; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377628979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1377629279; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377629580; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377629880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1377630180; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377630480; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 -1377630780; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377631080; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377631380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377631680; 1; 2599.999602; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377631980; 1; 2599.999602; 39.866660564; 1.5333333333333334; 2097152.0; 181751.73333333334; 161.06666666666666; 14.266666666666667; 0.13333333333333333; 0.2 -1377632280; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 536869.6; 0.0; 1.2; 0.0; 0.0 -1377632580; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 184548.0; 31.8; 3.8; 0.0; 0.0 -1377632880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 213908.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377633180; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 -1377633480; 1; 2599.999602; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377633780; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377634080; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 131419.46666666667; 0.06666666666666667; 2.933333333333333; 0.0; 0.5333333333333333 -1377634380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 176159.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377634680; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 171964.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 -1377634980; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.0; 0.0; 0.0 -1377635280; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1377635580; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377635880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377636180; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377636480; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377636780; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377637080; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377637380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377637680; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 -1377637980; 1; 2599.999602; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 1.0; 0.0; 0.0 -1377638280; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377638581; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 -1377638881; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377639181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377639481; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377639781; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377640081; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377640381; 1; 2599.999602; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 -1377640681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377640981; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 81087.73333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1377641281; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377641581; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 171963.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377641881; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377642181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1377642481; 1; 2599.999602; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377642781; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 109050.4; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 -1377643081; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377643381; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377643681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377643981; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1377644281; 1; 2599.999602; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377644581; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377644881; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1377645181; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 152392.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377645481; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 -1377645781; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377646081; 1; 2599.999602; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377646381; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 1.0; 0.0; 0.0 -1377646681; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377646981; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 7.733333333333333; 0.2; 0.13333333333333333 -1377647281; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.06666666666666667; 0.0 -1377647581; 1; 2599.999602; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377647881; 1; 2599.999602; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377648181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1377648481; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 102059.73333333334; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1377648781; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 160779.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377649081; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 1.1333333333333333; 0.0 -1377649381; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377649681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377649982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 -1377650282; 1; 2599.999602; 60.66665738; 2.3333333333333335; 2097152.0; 592792.2666666667; 161.06666666666666; 21.8; 0.06666666666666667; 0.4 -1377650582; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 596986.9333333333; 0.0; 2.8666666666666667; 0.06666666666666667; 0.0 -1377650882; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 241868.8; 31.8; 3.533333333333333; 0.13333333333333333; 0.0 -1377651182; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 171964.53333333333; 0.0; 2.2666666666666666; 0.06666666666666667; 0.0 -1377651482; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 -1377651782; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377652082; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 82485.33333333333; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 -1377652382; 1; 2599.999602; 0.0; 0.0; 2097152.0; 137012.53333333333; 0.0; 0.8; 0.0; 0.0 -1377652682; 1; 2599.999602; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377652982; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 -1377653282; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377653582; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 121633.06666666667; 0.06666666666666667; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1377653882; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377654182; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.2; 0.0 -1377654482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 -1377654782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377655082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.5333333333333333; 0.0; 0.0 -1377655382; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377655682; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 145401.33333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377655982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 144003.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1377656282; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377656582; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 -1377656882; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159381.6; 0.0; 0.6; 0.0; 0.0 -1377657182; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377657482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377657782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 -1377658082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377658382; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377658682; 1; 2599.999602; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377658982; 1; 2599.999602; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377659282; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377659582; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 135614.13333333333; 0.0; 1.0; 0.0; 0.0 -1377659882; 1; 2599.999602; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 -1377660182; 1; 2599.999602; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377660482; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 135614.93333333332; 0.0; 6.733333333333333; 0.26666666666666666; 0.2 -1377660782; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377661082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377661382; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1377661682; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 -1377661982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6; 3.8666666666666667; 0.0 -1377662282; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 125828.0; 0.06666666666666667; 1.6666666666666667; 0.06666666666666667; 0.0 -1377662582; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1377662882; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 116040.0; 0.13333333333333333; 13.133333333333333; 0.06666666666666667; 0.4666666666666667 -1377663182; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 166372.0; 0.0; 0.8; 0.0; 0.0 -1377663482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 1.0; 0.0 -1377663782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.6; 0.0; 0.0 -1377664082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377664382; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377664683; 1; 2599.999602; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 -1377664983; 1; 2599.999602; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377665283; 1; 2599.999602; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377665583; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377665883; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377666183; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377666483; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 127225.06666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1377666783; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 209713.33333333334; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1377667083; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377667383; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377667683; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377667983; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377668283; 1; 2599.999602; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.9333333333333333; 0.8666666666666667; 0.0 -1377668583; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109049.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377668883; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.7333333333333333; 0.0 -1377669183; 1; 2599.999602; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377669483; 1; 2599.999602; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377669783; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.3333333333333333; 0.0 -1377670083; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 81087.73333333334; 0.0; 2.7333333333333334; 0.0; 0.4666666666666667 -1377670383; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377670683; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377670983; 1; 2599.999602; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377671283; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.2; 0.0 -1377671583; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 2.1333333333333333; 0.13333333333333333; 0.13333333333333333 -1377671883; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.5333333333333334; 0.3333333333333333; 0.0 -1377672183; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 137013.06666666668; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377672483; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142604.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377672783; 1; 2599.9993; 25.999993; 1.0; 2097152.0; 62912.0; 0.0; 1.125; 0.0; 0.0 -1377673083; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377673383; 1; 2599.9993; 12.133330066666666; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 7.0; 0.26666666666666666; 0.2 -1377673683; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 123030.93333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377673983; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377674283; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377674583; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377674883; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377675183; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377675483; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.06666666666666667; 0.0 -1377675783; 1; 2599.9993; 0.0; 0.0; 2097152.0; 61513.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377676083; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.06666666666666667; 0.0 -1377676383; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377676684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377676984; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377677284; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 135614.13333333333; 0.2; 2.4; 0.0; 0.5333333333333333 -1377677584; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377677884; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377678184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1377678484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377678784; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377679084; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1377679384; 1; 2599.9993; 17.33332866666667; 0.6666666666666667; 2097152.0; 74097.06666666667; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377679684; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 150993.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377679984; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377680284; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377680584; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377680884; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 120234.66666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1377681184; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377681484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377681784; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377682084; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377682384; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377682684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1377682984; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 123030.66666666667; 0.0; 1.8666666666666667; 0.0; 0.06666666666666667 -1377683284; 1; 2599.9993; 24.266660133333332; 0.9333333333333332; 2097152.0; 184548.0; 0.0; 3.6666666666666665; 0.0; 0.0 -1377683584; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.8666666666666667; 0.0; 0.0 -1377683884; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 -1377684184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377684484; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377684784; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 153789.86666666667; 0.0; 7.0; 0.2; 0.13333333333333333 -1377685084; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377685384; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377685684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377685984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377686284; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.06666666666666667; 0.0 -1377686584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377686884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377687184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377687484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377687784; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377688084; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 100661.6; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1377688384; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377688684; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377688984; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377689284; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377689584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377689884; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377690184; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377690484; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377690784; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 157983.46666666667; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 -1377691084; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 130020.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377691384; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.5333333333333334; 0.0; 0.0 -1377691684; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 109050.4; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377691984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 -1377692284; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377692584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377692884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1377693184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377693484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1377693784; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377694084; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377694384; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377694684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377694984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1377695284; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 120234.93333333333; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377695584; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 170567.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377695884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.13333333333333333; 0.0 -1377696184; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377696484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.2; 0.0 -1377696785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1377697085; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 124429.06666666667; 12.933333333333334; 13.133333333333333; 0.4666666666666667; 0.13333333333333333 -1377697385; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 -1377697685; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1377697985; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377698285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377698585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377698885; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 121633.6; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1377699185; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155188.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377699485; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 -1377699785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377700085; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377700385; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 149595.46666666667; 0.06666666666666667; 1.4666666666666666; 0.13333333333333333; 0.06666666666666667 -1377700685; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377700985; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377701285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1377701585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377701885; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377702185; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377702485; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 107652.26666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377702785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1377703085; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1377703385; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377703685; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377703985; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 123031.73333333334; 0.0; 6.8; 0.2; 0.13333333333333333 -1377704285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377704585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1377704885; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1377705185; 1; 2599.9993; 74.53331326666667; 2.8666666666666667; 2097152.0; 657105.6; 161.33333333333334; 22.2; 0.26666666666666666; 0.4 -1377705485; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 374688.26666666666; 0.0; 5.133333333333334; 1.2666666666666666; 0.0 -1377705785; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 218101.33333333334; 31.8; 3.4; 0.0; 0.0 -1377706085; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 160780.53333333333; 0.0; 3.8; 0.0; 0.5333333333333333 -1377706385; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.3333333333333333; 0.0; 0.0 -1377706685; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 139809.33333333334; 0.0; 11.533333333333333; 0.0; 0.0 -1377706986; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377707286; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1377707586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1377707886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 -1377708186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377708486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.06666666666666667; 0.0 -1377708786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1377709086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1377709386; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 102059.73333333334; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 -1377709686; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 152392.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377709986; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 -1377710286; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377710586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377710886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377711186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1377711486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377711786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377712086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377712386; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377712686; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 -1377712986; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377713286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 110448.26666666666; 0.2; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1377713586; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142604.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377713886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377714186; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 111846.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377714486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377714786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377715086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1377715386; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377715686; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130021.6; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1377715987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377716287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 -1377716587; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 -1377716887; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377717187; 1; 2599.9993; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377717487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 -1377717787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377718087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377718387; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 88078.4; 161.73333333333332; 13.333333333333334; 0.0; 0.06666666666666667 -1377718687; 1; 2599.9993; 38.13332306666666; 1.4666666666666666; 2097152.0; 517296.0; 0.0; 2.2666666666666666; 0.0; 0.06666666666666667 -1377718987; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 223694.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1377719286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 197129.33333333334; 31.8; 3.8666666666666667; 0.0; 0.0 -1377719586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 0.8; 0.0; 0.0 -1377719886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377720186; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 132818.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1377720486; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 141206.66666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377720786; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 169168.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377721086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377721386; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377721686; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 -1377721986; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377722286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 104856.0; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1377722586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377722886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377723186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377723486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377723787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377724087; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 88078.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1377724387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 148196.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377724687; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377724987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377725287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 162177.33333333334; 0.0; 0.8; 0.0; 0.0 -1377725587; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377725887; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 -1377726187; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377726487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377726787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377727087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377727387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377727687; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127225.86666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377727987; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 170566.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377728287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377728587; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 128624.26666666666; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1377728887; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377729187; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.06666666666666667 -1377729487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377729787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377730087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138409.86666666667; 0.0; 0.8; 0.0; 0.0 -1377730387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377730687; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1377730987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377731288; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.4666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 -1377731588; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377731888; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377732188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377732488; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 -1377732788; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377733088; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 67106.4; 0.0; 1.0; 0.0; 0.0 -1377733388; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 -1377733688; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1377733988; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377734288; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1377734588; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377734888; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 111846.66666666667; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377735188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 171964.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377735488; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 146799.2; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 -1377735788; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 -1377736088; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377736388; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130022.4; 0.0; 1.4; 0.0; 0.0 -1377736688; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377736988; 1; 2599.9993; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377737288; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377737588; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377738188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 -1377738489; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106253.33333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377738789; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 149594.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377739089; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377739389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377739689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 -1377739989; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377740289; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377740589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377740889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377741189; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 144002.66666666666; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1377741489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377741789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1377742089; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377742389; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377742689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377742989; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377743289; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377743589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377743889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377744189; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377744489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377744789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377745089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377745389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377745689; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 131420.53333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377745989; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 171964.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377746289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377746589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377746889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377747189; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377747489; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.2; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 -1377747789; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377748089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377748389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 -1377748690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377748990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 -1377749290; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1377749590; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377749890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377750190; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.0; 11.933333333333334; 0.0; 0.0 -1377750490; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377750790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377751090; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377751390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377751690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377751990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377752289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377752589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377752889; 1; 2599.9993; 12.133330066666666; 0.4666666666666666; 2097152.0; 142604.53333333333; 0.0; 8.8; 0.26666666666666666; 0.6666666666666666 -1377753189; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 171965.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377753489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377753789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377754089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377754389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1377754689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8; 0.0; 0.0 -1377754989; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377755289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377755589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377755890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377756190; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 -1377756490; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 103456.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377756790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 159381.6; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 -1377757090; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377757390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1377757690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377757990; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.9333333333333333; 0.06666666666666667; 0.06666666666666667 -1377758290; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.6; 0.0; 0.0 -1377758590; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1377758890; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 149594.66666666666; 12.733333333333333; 12.866666666666667; 0.26666666666666666; 0.13333333333333333 -1377759190; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.4; 0.0; 0.0 -1377759490; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377759790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377760090; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 -1377760390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 176158.4; 0.0; 0.8; 0.0; 0.0 -1377760690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8; 0.0; 0.0 -1377760990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377761290; 1; 2599.9993; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.0; 0.0; 0.0 -1377761590; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1377761890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377762190; 1; 2599.9993; 57.19998460000001; 2.2; 2097152.0; 634736.5333333333; 161.06666666666666; 22.533333333333335; 0.06666666666666667; 0.4 -1377762490; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 507508.8; 0.0; 2.7333333333333334; 0.0; 0.0 -1377762790; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 260044.8; 31.8; 3.8666666666666667; 0.0; 0.0 -1377763090; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 159382.4; 0.0; 2.2; 0.0; 0.0 -1377763390; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.0; 0.0 -1377763690; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377763990; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 163576.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377764290; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377764590; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377764890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377765191; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1377765491; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1377765791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377766091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 -1377766391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377766691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1377766991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377767291; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 180353.06666666668; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1377767591; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 216704.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377767891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377768191; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377768491; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377768791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377769091; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377769391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 -1377769691; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 57319.46666666667; 0.0; 1.2; 0.0; 0.0 -1377769991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 -1377770291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377770591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377770891; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 -1377771191; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 -1377771491; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377771791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377772091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.06666666666666667; 6.666666666666667; 0.2; 0.13333333333333333 -1377772391; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1377772691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377772991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.0; 0.0; 0.8; 0.0; 0.0 -1377773291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.13333333333; 0.0; 1.0; 0.0; 0.0 -1377773591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377773891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377774191; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 -1377774491; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.0; 2.2; 0.0; 0.4666666666666667 -1377774791; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 197130.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377775091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1377775391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377775691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377775991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377776291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377776591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377776892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 -1377777192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377777492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377777792; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1377778092; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377778392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1377778692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377778992; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1377779292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377779592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377779892; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377780192; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377780492; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.6666666666666667; 0.0; 0.0 -1377780792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377781092; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.6; 4.066666666666666; 0.0 -1377781392; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.6; 0.0; 0.0 -1377781692; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1377781992; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 166372.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377782292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.5333333333333333; 0.0; 0.0 -1377782592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.0; 0.0 -1377782892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377783192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377783492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1377783792; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377784092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377784392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377784692; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106254.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 -1377784992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 -1377785292; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377785591; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 159381.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377785891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377786192; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377786492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 -1377786792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 1.4; 0.06666666666666667; 0.13333333333333333 -1377787092; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377787392; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 -1377787692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377787992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377788292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377788592; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.06666666666666667; 1.0; 0.0; 0.0 -1377788892; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.26666666666666666; 0.4666666666666667 -1377789192; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 162177.86666666667; 0.0; 0.8; 0.0; 0.0 -1377789492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377789792; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377790092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377790392; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124429.06666666667; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1377790692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1377790992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377791292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 -1377791592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377791892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377792192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377792492; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.93333333333; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1377792792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 146798.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377793092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377793392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377793692; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 -1377793992; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377794292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377794592; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377794892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.0; 0.0 -1377795192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377795492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377795793; 1; 2599.9993; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377796093; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377796393; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 159381.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1377796693; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377796993; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377797293; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377797593; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377797893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377798193; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377798493; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1377798793; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377799093; 1; 2599.9993; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377799393; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377799693; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 81087.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1377799993; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377800293; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377800593; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377800893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 169168.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377801193; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377801493; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377801793; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1377802093; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377802393; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1377802693; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377802993; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377803293; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 99263.46666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377803593; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 160779.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377803893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377804194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377804494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377804794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.8; 0.0; 0.0 -1377805094; 1; 2599.9993; 39.866655933333334; 1.5333333333333334; 2097152.0; 436205.86666666664; 161.0; 14.2; 0.0; 0.2 -1377805394; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 257248.26666666666; 0.0; 1.4; 0.0; 0.0 -1377805694; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 184547.73333333334; 31.8; 3.7333333333333334; 0.0; 0.0 -1377805994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155187.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377806294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377806594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 -1377806894; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377807194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 153789.06666666668; 0.0; 0.5333333333333333; 0.0; 0.0 -1377807494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 169169.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377807794; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 131420.26666666666; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 -1377808094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130021.86666666667; 0.0; 0.6; 0.0; 0.0 -1377808394; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1377808694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377808994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377809294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 -1377809594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.0; 0.0 -1377809894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 -1377810194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 -1377810494; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124429.06666666667; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1377810794; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 180353.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377811094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1377811394; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 -1377811694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 -1377811994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377812294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1377812594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 163576.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377812894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377813194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377813494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377813794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377814094; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 92272.8; 0.0; 8.0; 0.3333333333333333; 0.6666666666666666 -1377814395; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1377814695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377814995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377815295; 1; 2599.9993; 17.33332866666667; 0.6666666666666667; 2097152.0; 160780.53333333333; 161.0; 20.6; 0.06666666666666667; 0.4 -1377815595; 1; 2599.9993; 48.533320266666664; 1.8666666666666665; 2097152.0; 781536.8; 0.0; 4.2; 0.06666666666666667; 0.13333333333333333 -1377815895; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 367698.93333333335; 31.8; 3.0; 0.0; 0.0 -1377816195; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 219500.0; 0.0; 2.6; 0.0; 0.0 -1377816495; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 -1377816795; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377817095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377817395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377817694; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.66666666667; 0.2; 2.7333333333333334; 0.0; 0.4666666666666667 -1377817994; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 157982.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1377818294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377818594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377818894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377819194; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.2; 1.0; 0.0; 0.0 -1377819494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377819794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377820094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 1.2; 0.0; 0.0 -1377820394; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 170566.66666666666; 12.733333333333333; 16.8; 0.4; 0.13333333333333333 -1377820694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1377820994; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377821294; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.13333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377821594; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 157983.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377821894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377822194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377822494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377822794; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 146800.0; 0.0; 1.4; 0.0; 0.0 -1377823094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377823394; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377823694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377823994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377824294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 -1377824595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377824895; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 117438.93333333333; 0.0; 3.2; 0.06666666666666667; 0.4666666666666667 -1377825195; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 145400.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377825495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377825795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377826095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377826395; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 7.2; 0.2; 0.13333333333333333 -1377826695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377826995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377827295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377827595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1377827895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 -1377828195; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377828495; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130021.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377828795; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 167771.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377829095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1377829395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377829695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377829995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377830295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377830595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377830895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377831195; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377831495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377831795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 -1377832095; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 125826.93333333333; 0.06666666666666667; 8.6; 0.2; 0.6 -1377832395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377832695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377832995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1377833295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377833595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 159382.13333333333; 0.0; 0.8; 0.0; 0.0 -1377833895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377834195; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1377834495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1377834795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377835095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 -1377835395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1377835695; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 103457.86666666667; 0.0; 2.2; 0.0; 0.4666666666666667 -1377835996; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377836296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377836596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377836896; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377837196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377837496; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 11.733333333333333; 0.0; 0.0 -1377837796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377838096; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127226.13333333333; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1377838396; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377838696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377838996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1377839296; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 89476.53333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 -1377839596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377839896; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377840196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1377840496; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377840796; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.86666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1377841096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 -1377841396; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377841696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377841996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377842296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1377842596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377842896; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 113244.8; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1377843196; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 159382.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377843496; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 -1377843796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377844096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106253.6; 0.0; 0.8; 0.0; 0.0 -1377844396; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 141205.86666666667; 0.0; 1.9333333333333333; 0.06666666666666667; 0.13333333333333333 -1377844696; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130022.4; 0.0; 1.4666666666666666; 0.0; 0.0 -1377844997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377845297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377845597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1377845897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1377846197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377846497; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377846797; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377847097; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377847397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1377847697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1377847997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377848297; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 -1377848597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1377848897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1377849197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377849497; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 -1377849797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377850097; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1377850397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 -1377850696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.06666666666666667; 0.0 -1377850996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1377851296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377851596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 -1377851896; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377852196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377852496; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1377852796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377853096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 -1377853396; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1377853696; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377853996; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 159383.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377854297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100660.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377854597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 -1377854897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377855197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377855497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377855797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.13333333333333333; 0.0 -1377856097; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 144003.73333333334; 0.2; 7.133333333333334; 0.2; 0.13333333333333333 -1377856397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.5333333333333333; 0.0; 0.0 -1377856697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.3333333333333333; 0.0 -1377856997; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1377857297; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127225.06666666667; 0.0; 1.8666666666666667; 0.0; 0.4666666666666667 -1377857597; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377857897; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377858197; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377858497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377858797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1377859097; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377859397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1377859697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377859997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377860297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 -1377860597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377860897; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 125827.46666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1377861197; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 192935.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377861497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 -1377861797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377862097; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 6.866666666666666; 0.4; 0.13333333333333333 -1377862397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377862698; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 -1377862998; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 -1377863298; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1377863598; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377863898; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377864198; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377864498; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 128624.26666666666; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1377864798; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 156586.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377865098; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1377865398; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377865698; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.2; 0.0 -1377865998; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377866298; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1377866598; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377866898; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 3.066666666666667; 0.0 -1377867198; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377867498; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377867798; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.2; 0.0 -1377868098; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 181750.93333333332; 0.06666666666666667; 8.533333333333333; 0.4; 0.6 -1377868398; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 208315.2; 0.0; 1.0; 0.13333333333333333; 0.0 -1377868698; 1; 2599.9993; 60.66665033333334; 2.3333333333333335; 2097152.0; 227889.33333333334; 161.06666666666666; 21.933333333333334; 0.06666666666666667; 0.4 -1377868998; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 673882.4; 0.0; 2.466666666666667; 0.06666666666666667; 0.0 -1377869298; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 285210.13333333336; 31.8; 4.466666666666667; 0.06666666666666667; 0.0 -1377869598; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 208314.4; 0.0; 2.2666666666666666; 0.0; 0.0 -1377869898; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 149596.26666666666; 0.0; 1.6; 0.0; 0.0 -1377870198; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377870498; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.26666666666666666; 0.0 -1377870798; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 139808.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1377871098; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377871398; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377871698; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 -1377871998; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 174760.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377872299; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377872599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377872899; 1; 2599.9993; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377873199; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.4; 0.06666666666666667; 0.06666666666666667 -1377873499; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1377873799; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1377874099; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377874399; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377874699; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 6.666666666666667; 0.0 -1377874999; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 6.0; 0.3333333333333333; 0.13333333333333333 -1377875299; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 150993.86666666667; 0.0; 3.2; 0.0; 0.5333333333333333 -1377875599; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 160780.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377875899; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 96467.2; 0.0; 0.8; 0.13333333333333333; 0.0 -1377876199; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377876499; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.4; 0.0 -1377876799; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377877099; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377877399; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1377877699; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1377877999; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1377878299; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377878599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377878899; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 95068.53333333334; 0.06666666666666667; 2.7333333333333334; 0.13333333333333333; 0.4666666666666667 -1377879199; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124428.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377879499; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377879799; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377880100; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377880400; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377880700; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377881000; 1; 2599.9993; 15.599995799999999; 0.6; 2097152.0; 128624.26666666666; 12.8; 23.933333333333334; 0.3333333333333333; 0.2 -1377881300; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1377881600; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 -1377881900; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377882200; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377882500; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 79689.6; 0.06666666666666667; 2.6; 0.2; 0.4666666666666667 -1377882800; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 -1377883100; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 109050.4; 0.0; 1.0; 0.13333333333333333; 0.0 -1377883399; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.06666666666666667; 0.0 -1377883699; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377883999; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377884299; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 -1377884599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377884899; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 -1377885199; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377885499; 1; 2599.9993; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377885799; 1; 2599.999602; 11.99999816307692; 0.4615384615384615; 2097152.0; 96789.84615384616; 0.0; 0.8333333333333334; 0.0; 0.0 -1377886099; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 162178.4; 0.06666666666666667; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 -1377886400; 1; 2599.999602; 0.0; 0.0; 2097152.0; 163575.46666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377886700; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 162178.66666666666; 0.0; 7.0; 0.26666666666666666; 0.2 -1377887000; 1; 2599.999602; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377887300; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377887600; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 119836.0; 0.0; 0.8461538461538461; 0.07692307692307693; 0.0 -1377887900; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377888200; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 -1377888500; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377888800; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.5333333333333333; 0.0 -1377889100; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1377889400; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377889700; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1377890000; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 157984.26666666666; 0.0; 0.8; 0.0; 0.0 -1377890300; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377890600; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377890900; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377891200; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1377891500; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 462770.4; 161.06666666666666; 14.533333333333333; 0.06666666666666667; 0.2 -1377891800; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 276821.6; 0.0; 1.4666666666666666; 0.0; 0.0 -1377892100; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 212510.13333333333; 31.8; 4.0; 0.0; 0.0 -1377892400; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150994.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377892700; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377893000; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 124429.86666666667; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 -1377893300; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142604.26666666666; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 -1377893600; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1377893900; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377894200; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377894500; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.4666666666666667; 0.0 -1377894800; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377895100; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 1.0666666666666667; 0.0 -1377895400; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377895700; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377896000; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377896300; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377896600; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377896901; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 141207.46666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1377897201; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 -1377897501; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1377897801; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1377898101; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377898401; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 79689.6; 0.0; 0.8; 0.2; 0.0 -1377898701; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1377899001; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377899301; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377899601; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377899901; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1377900201; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377900501; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.13333333333; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1377900801; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 159381.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377901101; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118836.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377901401; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106253.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377901701; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1377902001; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.06666666666666667; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 -1377902301; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377902601; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1377902901; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377903201; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1377903502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377903802; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377904102; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 156585.6; 0.26666666666666666; 2.0; 0.06666666666666667; 0.4666666666666667 -1377904402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 176159.46666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377904702; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377905002; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 7.0; 0.2; 0.13333333333333333 -1377905302; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139808.53333333333; 0.0; 1.2; 0.06666666666666667; 0.0 -1377905602; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377905902; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377906202; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1377906502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1377906802; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1377907102; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377907402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377907702; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 125827.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1377908002; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 169168.0; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1377908302; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377908602; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377908902; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377909202; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 -1377909502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377909802; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 -1377910102; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 -1377910402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377910702; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1377911002; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377911302; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 139808.0; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 -1377911602; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152391.2; 0.06666666666666667; 0.7333333333333333; 0.0; 0.0 -1377911902; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 123031.46666666666; 0.0; 7.2; 0.2; 0.13333333333333333 -1377912202; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377912502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1377912802; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377913102; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377913402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377913702; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1377914003; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 1.6; 0.0; 0.0 -1377914303; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377914603; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1377914903; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1377915203; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1377915503; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377915803; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 -1377916102; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1377916402; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377916702; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377917002; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377917302; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377917602; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377917902; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377918202; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120234.4; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 -1377918502; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1377918802; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377919102; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 5.133333333333334; 0.0 -1377919402; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377919702; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1377920002; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 -1377920302; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377920602; 1; 2599.999343; 67.59998291800001; 2.6; 2097152.0; 336940.0; 161.0; 21.8; 0.06666666666666667; 0.4 -1377920903; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 634736.0; 0.0; 2.7333333333333334; 0.0; 0.0 -1377921203; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 292201.3333333333; 31.8; 3.4; 0.06666666666666667; 0.0 -1377921503; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 205517.86666666667; 0.0; 2.3333333333333335; 0.0; 0.0 -1377921803; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.6; 0.0; 1.5333333333333334; 0.0; 0.0 -1377922103; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139808.53333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1377922403; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 166372.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377922703; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.6; 0.0; 0.0 -1377923003; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377923303; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 -1377923603; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377923903; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.6; 0.0; 0.0 -1377924203; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377924503; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 61513.86666666667; 0.0; 1.0; 0.0; 0.0 -1377924803; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 71300.8; 0.0; 11.666666666666666; 0.0; 0.0 -1377925103; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 6.2; 0.2; 0.13333333333333333 -1377925403; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.7333333333333334; 0.0; 0.0 -1377925703; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.6; 0.06666666666666667; 2.533333333333333; 0.13333333333333333; 0.5333333333333333 -1377926003; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 226490.13333333333; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1377926303; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.06666666666666667; 0.0 -1377926603; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 -1377926903; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377927203; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377927503; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 -1377927803; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1377928103; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377928403; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377928703; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1377929003; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1377929303; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134215.73333333334; 0.06666666666666667; 2.2666666666666666; 0.2; 0.5333333333333333 -1377929604; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1377929904; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377930204; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 -1377930504; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377930804; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 8.133333333333333; 0.26666666666666666; 0.2 -1377931104; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.4; 0.0; 0.0 -1377931404; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1377931704; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 -1377932004; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1377932304; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 -1377932604; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377932904; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377933204; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377933504; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377933804; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1377934104; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377934404; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377934704; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377935004; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1377935304; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1377935604; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1377935904; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377936204; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377936504; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130021.6; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377936804; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 152390.93333333332; 0.0; 6.8; 0.2; 0.13333333333333333 -1377937104; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.06666666666666667; 1.5333333333333334; 0.06666666666666667; 0.0 -1377937404; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1377937704; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377938004; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377938304; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1377938604; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377938905; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377939205; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 1.2; 0.0 -1377939505; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121632.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377939805; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377940105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 135613.6; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377940405; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 176160.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1377940705; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377941005; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1377941305; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377941605; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377941905; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377942205; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377942505; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 142604.8; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.2 -1377942805; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377943105; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377943405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377943705; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 103457.86666666667; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1377944005; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377944305; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377944605; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377944905; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377945205; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1377945505; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 0.8; 0.0; 0.0 -1377945805; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377946105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377946405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377946706; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 -1377947006; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377947306; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 -1377947606; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 188741.6; 0.0; 0.8; 0.0; 0.0 -1377947906; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 117439.2; 0.0; 1.0; 3.066666666666667; 0.0 -1377948206; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 64310.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377948506; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377948805; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1377949105; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 152391.73333333334; 0.0; 7.466666666666667; 0.26666666666666666; 0.13333333333333333 -1377949405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1377949705; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 118836.26666666666; 0.0; 1.0; 0.0; 0.0 -1377950005; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130021.33333333333; 0.0; 0.6; 0.0; 0.0 -1377950305; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377950605; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1377950905; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 125828.0; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1377951205; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 -1377951505; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377951805; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377952105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109049.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1377952405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1377952705; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377953005; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1377953306; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377953606; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1377953906; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377954206; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377954506; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142604.0; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1377954806; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 167770.4; 0.0; 1.0; 0.0; 0.0 -1377955106; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377955406; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1377955706; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377956006; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 118837.33333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1377956306; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 178954.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1377956606; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377956906; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1377957206; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1377957506; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1377957806; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377958106; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.33333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1377958406; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 173363.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1377958706; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377959006; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377959306; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1377959606; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.13333333333333333 -1377959906; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377960206; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377960506; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1377960806; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377961106; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377961406; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1377961706; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1377962006; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141206.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377962307; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1377962607; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 -1377962907; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 -1377963207; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1377963507; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1377963807; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377964107; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377964407; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121632.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377964707; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377965007; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 50328.8; 0.0; 0.8; 0.0; 0.0 -1377965307; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.86666666667; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 -1377965607; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 171964.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377965907; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377966207; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377966507; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377966807; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377967107; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377967407; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377967707; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1377968007; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 142604.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377968307; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 0.0; 17.666666666666668; 0.2; 0.13333333333333333 -1377968607; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377968907; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377969207; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 -1377969507; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1377969807; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377970107; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377970407; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1377970707; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1377971007; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1377971307; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 75495.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1377971607; 1; 2599.999343; 67.59998291800001; 2.6; 2097152.0; 232082.93333333332; 161.0; 21.866666666666667; 0.13333333333333333; 0.3333333333333333 -1377971907; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 727010.4; 0.0; 2.466666666666667; 0.0; 0.0 -1377972207; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 279618.4; 31.8; 3.6; 1.1333333333333333; 0.0 -1377972507; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 191537.6; 0.0; 3.6; 0.06666666666666667; 0.4666666666666667 -1377972807; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 164974.93333333332; 0.0; 1.6; 0.0; 0.0 -1377973107; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 -1377973407; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 -1377973707; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 -1377974008; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1377974308; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377974608; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377974908; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377975208; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1377975508; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1377975808; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1377976108; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 149595.46666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1377976408; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 181751.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377976708; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1377977008; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1377977308; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 -1377977608; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1377977908; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 387272.0; 161.06666666666666; 14.6; 0.0; 0.2 -1377978208; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 315969.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1377978508; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 155188.0; 31.8; 3.8666666666666667; 0.0; 0.0 -1377978808; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1377979108; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1377979408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377979708; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130021.06666666667; 0.06666666666666667; 3.0; 0.06666666666666667; 0.4666666666666667 -1377980008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1377980308; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 7.2; 0.2; 0.13333333333333333 -1377980608; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1377980908; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377981208; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377981508; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1377981808; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1377982108; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1377982408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1377982708; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1377983008; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1377983308; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.86666666667; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 -1377983608; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1377983908; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1377984208; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1377984508; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377984808; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377985108; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377985408; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1377985708; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 149596.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377986008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 155188.26666666666; 0.0; 0.8; 0.0; 0.0 -1377986308; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 131420.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377986608; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1377986908; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.7333333333333333 -1377987208; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1377987508; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 148197.33333333334; 169.66666666666666; 179.2; 0.0; 0.0 -1377987808; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 243268.0; 0.0; 1.2; 0.0; 0.0 -1377988108; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 145401.33333333334; 0.0; 1.0; 0.0; 0.0 -1377988408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 -1377988708; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377989008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 -1377989309; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1377989609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 1.0; 0.0; 0.0 -1377989909; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377990209; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1377990509; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1377990809; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1377991109; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1377991409; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1377991709; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1377992009; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1377992309; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1377992609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1377992909; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377993209; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1377993509; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1377993809; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1377994109; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 164974.66666666666; 0.0; 8.6; 0.26666666666666666; 0.6 -1377994409; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 185944.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1377994709; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1377995009; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86679.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1377995309; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 -1377995609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1377995909; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377996209; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1377996509; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1377996809; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1377997109; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 -1377997409; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.5333333333333333; 0.0; 0.0 -1377997709; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 -1377998009; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 -1377998310; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 -1377998610; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 -1377998910; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 -1377999210; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 1.0; 0.0; 0.0 -1377999510; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 -1377999810; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.06666666666666667; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1378000110; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1378000410; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378000710; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378001010; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 -1378001310; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 124428.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1378001610; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 177556.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378001910; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110447.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378002210; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1378002510; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 163576.53333333333; 0.0; 0.6; 0.0; 0.0 -1378002810; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.13333333333; 0.0; 1.5333333333333334; 0.13333333333333333; 0.0 -1378003110; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 -1378003410; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378003710; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1378004010; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 145400.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1378004310; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378004610; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 -1378004910; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127225.06666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 -1378005210; 1; 2599.999343; 327.599917218; 12.6; 2097152.0; 534072.8; 34.2; 753.7333333333333; 149.46666666666667; 32.13333333333333 -1378005510; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 322958.93333333335; 0.0; 1.4; 0.0; 0.0 -1378005810; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378006110; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378006410; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1378006711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 12.733333333333333; 13.133333333333333; 0.3333333333333333; 0.2 -1378007011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1378007311; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1378007611; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378007911; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378008211; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378008511; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.13333333333333333; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1378008811; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 199926.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378009111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 137012.26666666666; 0.0; 1.0; 0.0; 0.0 -1378009411; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378009711; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1378010011; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378010311; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1378010611; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378010911; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378011211; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378011511; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1378011811; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378012111; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 113243.46666666666; 0.13333333333333333; 13.533333333333333; 0.0; 0.4666666666666667 -1378012411; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174761.06666666668; 0.0; 6.133333333333334; 0.2; 0.13333333333333333 -1378012711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 156586.93333333332; 0.0; 1.9333333333333333; 0.0; 0.0 -1378013011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 1.2666666666666666; 0.0; 0.0 -1378013311; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378013611; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378013912; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378014211; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 -1378014511; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378014811; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378015111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378015411; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378015711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1378016011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 167771.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378016311; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378016611; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378016911; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378017211; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 2.6; 0.06666666666666667; 0.13333333333333333 -1378017511; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 159381.6; 0.0; 1.8666666666666667; 0.0; 0.0 -1378017811; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378018111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378018411; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1378018711; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 6.066666666666666; 0.2; 0.13333333333333333 -1378019011; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 2.066666666666667; 0.0; 0.0 -1378019312; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1378019612; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 -1378019912; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378020212; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378020512; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378020812; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378021112; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.3333333333333333; 0.0 -1378021412; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1378021712; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.2; 0.0 -1378022012; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141206.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378022312; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378022612; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378022912; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.2; 2.4; 0.06666666666666667; 0.5333333333333333 -1378023212; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378023512; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 0.13333333333333333; 0.0 -1378023812; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378024112; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1378024412; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.8; 0.13333333333333333; 0.0 -1378024712; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378025012; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378025312; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 6.266666666666667; 0.3333333333333333; 0.2 -1378025612; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 192936.0; 0.0; 2.1333333333333333; 0.0; 0.0 -1378025912; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378026212; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378026512; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 149596.26666666666; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378026812; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 171964.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378027112; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378027412; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378027713; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378028013; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378028313; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 156586.13333333333; 0.0; 1.2; 0.0; 0.0 -1378028613; 1; 2599.999343; 69.33331581333334; 2.666666666666667; 2097152.0; 422225.06666666665; 161.0; 21.933333333333334; 0.06666666666666667; 0.4 -1378028913; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 603977.6; 0.0; 2.6; 0.06666666666666667; 0.0 -1378029213; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 226489.6; 31.8; 3.6; 0.0; 0.0 -1378029513; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 184548.0; 0.8; 2.6; 0.0; 0.0 -1378029813; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.7333333333333334; 0.0; 0.0 -1378030113; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 2.3333333333333335; 1.4666666666666666; 0.5333333333333333 -1378030413; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 174761.33333333334; 0.0; 1.0; 0.0; 0.0 -1378030713; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378031013; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159381.6; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1378031313; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378031613; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378031913; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1378032213; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378032513; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378032813; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378033113; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 -1378033413; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378033713; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1378034013; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170566.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378034313; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1378034613; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.06666666666666667; 1.4; 0.13333333333333333; 0.0 -1378034913; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.0 -1378035214; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1378035514; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378035814; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 131419.73333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378036114; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378036414; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378036714; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1378037014; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378037314; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1378037614; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 -1378037914; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378038214; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378038514; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378038814; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378039114; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 -1378039414; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1378039714; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.0; 0.06666666666666667; 0.0 -1378040014; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 60115.73333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378040314; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1378040614; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378040914; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128623.73333333334; 0.0; 2.4; 0.13333333333333333; 0.5333333333333333 -1378041214; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 1.0; 0.0; 0.0 -1378041514; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378041814; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 -1378042114; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.33333333333; 0.0; 7.4; 0.2; 0.13333333333333333 -1378042414; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378042715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378043015; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378043315; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 -1378043615; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378043915; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378044215; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378044515; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.06666666667; 0.06666666666666667; 2.533333333333333; 0.13333333333333333; 0.4666666666666667 -1378044815; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 159382.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378045115; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378045415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378045715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378046015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 -1378046315; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 -1378046615; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378046915; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378047215; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 149594.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378047515; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.8666666666666667; 0.0; 0.0 -1378047815; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378048115; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 176157.86666666667; 0.0; 8.333333333333334; 0.26666666666666666; 0.6 -1378048415; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378048715; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1378049015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 -1378049315; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378049615; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 164974.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378049915; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378050215; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378050515; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.4; 0.0; 0.0 -1378050815; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378051115; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378051415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 164975.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378051715; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150992.8; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378052015; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378052315; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 -1378052615; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378052915; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378053215; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378053515; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378053815; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1378054115; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378054415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378054715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 72698.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378055015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125827.2; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378055315; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 167770.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378055615; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144002.93333333332; 0.0; 12.0; 0.0; 0.0 -1378055916; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378056216; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378056516; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378056816; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378057116; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378057416; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378057716; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378058016; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378058316; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378058616; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1378058916; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 176159.2; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1378059216; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 222296.0; 0.0; 0.8; 0.06666666666666667; 0.0 -1378059516; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1378059816; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378060116; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 -1378060416; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378060716; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.06666666666666667; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1378061016; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 160779.73333333334; 0.06666666666666667; 1.9333333333333333; 0.0; 0.0 -1378061316; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378061616; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378061916; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378062216; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 1.4; 1.3333333333333333; 0.0; 0.0 -1378062516; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1378062816; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378063116; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378063416; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1378063716; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378064017; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 163576.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1378064317; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 303386.4; 161.66666666666666; 14.466666666666667; 0.0; 0.2 -1378064617; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 373291.2; 0.0; 1.4; 0.0; 0.0 -1378064917; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 204120.53333333333; 31.8; 4.0; 0.0; 0.0 -1378065217; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 188741.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378065517; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378065817; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378066117; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 -1378066417; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378066717; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378067017; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378067317; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 150993.6; 12.866666666666667; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 -1378067617; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 184547.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378067917; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378068217; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1378068517; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1378068817; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 -1378069117; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 -1378069417; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378069717; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.2; 3.2; 0.06666666666666667; 0.4666666666666667 -1378070017; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.06666666666666667; 0.8; 0.0; 0.0 -1378070317; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378070617; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378070917; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1378071217; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 -1378071517; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.6; 0.0; 1.2; 0.0; 0.0 -1378071817; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378072117; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378072418; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 -1378072718; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 6.8; 0.2; 0.13333333333333333 -1378073018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 173362.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378073318; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144003.46666666667; 0.0; 2.4; 0.2; 0.4666666666666667 -1378073618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 153789.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 -1378073918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378074218; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378074518; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378074818; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.06666666667; 0.0; 1.4; 0.06666666666666667; 0.13333333333333333 -1378075118; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378075418; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 -1378075718; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 -1378076018; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378076318; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378076618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.2; 1.4; 0.0; 0.0 -1378076918; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139807.73333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378077218; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 223694.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378077518; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1378077818; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378078118; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1378078418; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 141207.46666666667; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 -1378078718; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378079018; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378079318; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 -1378079618; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1378079918; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378080218; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378080518; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 155188.0; 0.06666666666666667; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 -1378080818; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 149594.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378081118; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378081418; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378081718; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378082018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.6; 1.7333333333333334; 0.0; 0.0 -1378082318; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1378082618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378082918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378083218; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378083518; 1; 2599.999343; 51.99998686; 2.0; 2097152.0; 160779.73333333334; 161.0; 22.066666666666666; 0.2; 0.3333333333333333 -1378083818; 1; 2599.999343; 36.399990802; 1.4; 2097152.0; 598384.8; 0.0; 2.7333333333333334; 0.0; 0.0 -1378084118; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 282414.6666666667; 32.6; 5.066666666666666; 0.06666666666666667; 0.5333333333333333 -1378084418; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 209713.33333333334; 0.0; 2.6; 0.0; 0.0 -1378084718; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153790.66666666666; 0.0; 1.8666666666666667; 0.0; 0.0 -1378085018; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378085318; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1378085618; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 -1378085918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378086218; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378086518; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378086818; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378087118; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378087418; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378087718; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 167770.4; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1378088018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 192936.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378088319; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157985.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1378088619; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150994.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378088919; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 -1378089219; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378089519; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378089819; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 -1378090119; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1378090419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 142605.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1378090719; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 -1378091019; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378091319; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1378091619; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170567.46666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378091919; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.7333333333333334; 0.0; 0.0 -1378092219; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 71300.8; 0.0; 1.0; 0.13333333333333333; 0.0 -1378092519; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378092819; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378093119; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378093419; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 64310.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378093719; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378094019; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378094319; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 -1378094619; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.06666666666666667; 0.0 -1378094919; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.33333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1378095219; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153788.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378095519; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378095819; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378096119; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.2; 0.0 -1378096419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 -1378096719; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378097019; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 -1378097319; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 65708.26666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1378097619; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378097919; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1378098219; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378098519; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 141207.46666666667; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378098819; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378099119; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 11.866666666666667; 0.0; 0.0 -1378099419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378099719; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378100019; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378100319; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144003.73333333334; 0.0; 0.8; 0.0; 0.0 -1378100620; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378100920; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378101220; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378101520; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 -1378101820; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1378102120; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 -1378102420; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 -1378102720; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1378103020; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378103320; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378103620; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 103457.86666666667; 0.06666666666666667; 2.6; 0.2; 0.13333333333333333 -1378103920; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 1.7333333333333334; 0.0; 0.0 -1378104220; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.2666666666666666; 0.0; 0.0 -1378104520; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.26666666666666666; 7.466666666666667; 0.26666666666666666; 0.13333333333333333 -1378104820; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378105120; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378105420; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1378105720; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 164974.4; 0.0; 2.3333333333333335; 0.13333333333333333; 0.5333333333333333 -1378106020; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 188742.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1378106320; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 -1378106620; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.2; 0.0 -1378106920; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1378107220; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 -1378107520; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378107820; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 -1378108120; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 1.4; 0.06666666666666667; 0.0 -1378108420; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.4; 0.06666666666666667; 0.0 -1378108720; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378109020; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118836.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378109320; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135613.86666666667; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1378109620; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 137012.53333333333; 0.0; 1.0; 0.0; 0.0 -1378109921; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378110221; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378110521; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1378110820; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378111120; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 -1378111420; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378111720; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378112020; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378112320; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378112621; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378112921; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.0; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1378113221; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.0; 0.0 -1378113521; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378113821; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378114121; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378114421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1378114721; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378115021; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378115321; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.4; 0.0; 0.0 -1378115621; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378115921; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 0.8; 0.0; 0.0 -1378116221; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378116521; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1378116821; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 170566.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 -1378117121; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378117421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378117721; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1378118021; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378118321; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 -1378118621; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378118921; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378119221; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378119521; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134215.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1378119821; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378120121; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141206.66666666666; 0.0; 2.4; 0.2; 0.5333333333333333 -1378120421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 -1378120721; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1378121021; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378121321; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1378121622; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1378121922; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1378122222; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1378122522; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1378122822; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378123122; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 148197.33333333334; 0.0; 0.8; 0.0; 0.0 -1378123422; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 167770.13333333333; 0.0; 7.2; 0.2; 0.13333333333333333 -1378123722; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152392.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378124022; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 173362.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1378124322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378124622; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378124922; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 -1378125222; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378125522; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378125822; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 -1378126122; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378126422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378126722; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378127022; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378127322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170567.2; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1378127622; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 -1378127922; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1378128222; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378128522; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378128822; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1378129122; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139809.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378129422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378129722; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378130022; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1378130322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.2 -1378130622; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.06666666666666667; 1.5333333333333334; 0.0; 0.0 -1378130922; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.13333333333333333; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1378131222; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378131522; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378131822; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378132122; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378132422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.06666666666666667 -1378132722; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378133023; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 -1378133323; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378133623; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378133923; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378134223; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144003.73333333334; 0.0; 1.0; 0.0; 0.0 -1378134523; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 169168.8; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1378134823; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 180353.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378135123; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378135423; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378135723; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378136023; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378136323; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.8; 0.0; 0.0 -1378136623; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1378136923; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 -1378137223; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378137523; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378137823; 1; 2599.999343; 51.99998686; 2.0; 2097152.0; 152391.46666666667; 161.0; 21.866666666666667; 0.13333333333333333; 0.4 -1378138123; 1; 2599.999343; 43.333322383333325; 1.6666666666666665; 2097152.0; 713029.6; 0.8; 4.333333333333333; 0.06666666666666667; 0.5333333333333333 -1378138423; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 360708.0; 31.8; 3.533333333333333; 0.13333333333333333; 0.0 -1378138723; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 222296.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.0 -1378139023; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 1.8; 0.0; 0.0 -1378139323; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378139623; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378139923; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1378140223; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1378140523; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378140824; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378141124; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378141424; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378141724; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 125828.0; 0.6; 2.4; 0.06666666666666667; 0.5333333333333333 -1378142024; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 155187.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378142324; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1378142624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378142924; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 138410.4; 0.0; 12.0; 0.0; 0.0 -1378143224; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.53333333333; 0.0; 7.133333333333334; 0.7333333333333333; 0.13333333333333333 -1378143524; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 213906.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378143824; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378144124; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 67106.4; 0.0; 1.0; 0.0; 0.0 -1378144424; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 67106.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378144724; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378145024; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378145324; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 155187.2; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 -1378145624; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378145924; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378146224; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378146524; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378146824; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1378147124; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378147424; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378147724; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378148024; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378148324; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 -1378148624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378148924; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378149224; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 152390.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1378149524; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 6.933333333333334; 0.3333333333333333; 0.13333333333333333 -1378149824; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1378150124; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378150424; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378150724; 1; 2599.999343; 53.733319755333326; 2.0666666666666664; 2097152.0; 247462.4; 161.73333333333332; 14.333333333333334; 0.0; 0.2 -1378151024; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 364902.4; 0.0; 1.4666666666666666; 0.0; 0.0 -1378151324; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 167771.2; 31.8; 4.0; 0.0; 0.0 -1378151624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 176159.2; 0.0; 0.8; 0.0; 0.0 -1378151924; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378152224; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378152525; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.0; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 -1378152825; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 153789.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 -1378153125; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378153425; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378153725; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378154025; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378154325; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378154625; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378154925; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378155225; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1378155525; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378155825; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378156125; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.86666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1378156425; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378156725; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378157025; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378157325; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378157625; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378157925; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378158225; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 -1378158525; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378158825; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378159125; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378159425; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 132818.13333333333; 0.0; 2.066666666666667; 0.0; 0.0 -1378159725; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 166371.46666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378160025; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 -1378160325; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1378160625; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378160925; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378161225; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.06666666666666667; 1.8; 0.06666666666666667; 0.13333333333333333 -1378161525; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378161825; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378162125; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378162425; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 7.2; 0.26666666666666666; 0.13333333333333333 -1378162725; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378163025; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 171964.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378163325; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 170566.66666666666; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1378163625; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378163926; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378164226; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 61513.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378164526; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378164826; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378165126; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107651.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378165426; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378165726; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378166026; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378166326; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378166626; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1378166926; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 102059.73333333334; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 -1378167226; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378167526; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378167826; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.33333333333; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1378168126; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378168426; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.5333333333333333; 1.4666666666666666; 0.0; 0.0 -1378168726; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378169026; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378169326; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1378169627; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378169927; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1378170227; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378170527; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 131420.0; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1378170827; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 146798.93333333332; 0.0; 1.0; 0.0; 0.0 -1378171127; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378171427; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 162178.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378171727; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.6; 0.0; 0.0 -1378172027; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378172327; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378172627; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1378172927; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1378173227; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378173527; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378173827; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 159381.86666666667; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1378174127; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 137011.46666666667; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378174427; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 160780.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378174727; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378175027; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378175327; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378175627; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378175927; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378176227; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 78291.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378176527; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378176827; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1378177127; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378177427; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378177727; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378178027; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 184546.13333333333; 0.0; 1.0; 0.0; 0.0 -1378178327; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378178627; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378178927; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378179227; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378179527; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144003.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378179828; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106253.86666666667; 0.0; 1.0; 0.0; 0.0 -1378180128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 7.8; 0.2; 0.13333333333333333 -1378180428; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378180728; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.6; 0.0; 0.0 -1378181028; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378181328; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378181628; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 -1378181928; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378182228; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 -1378182528; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378182828; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378183128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378183428; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378183728; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378184028; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378184328; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1378184628; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 -1378184928; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 145401.33333333334; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1378185228; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 177556.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378185528; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1378185828; 1; 2599.999343; 69.33331581333334; 2.666666666666667; 2097152.0; 619357.0666666667; 161.0; 22.0; 0.06666666666666667; 0.4 -1378186128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 404049.3333333333; 0.0; 2.7333333333333334; 0.0; 0.0 -1378186428; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 234879.73333333334; 31.8; 14.466666666666667; 0.0; 0.0 -1378186728; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 190140.0; 0.0; 8.866666666666667; 0.2; 0.13333333333333333 -1378187028; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 178955.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1378187328; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.2; 0.0; 0.0 -1378187628; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1378187928; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1378188228; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157985.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1378188529; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 116041.06666666667; 0.4; 2.8; 0.06666666666666667; 0.5333333333333333 -1378188829; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378189129; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378189429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378189729; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378190029; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 146799.73333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.06666666666666667 -1378190329; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 138410.66666666666; 0.0; 1.7333333333333334; 0.0; 0.0 -1378190629; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378190929; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 153789.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378191229; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378191529; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378191829; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 -1378192129; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 139808.26666666666; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1378192429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 145401.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378192729; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 157984.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378193029; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378193329; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378193629; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378193929; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 135614.13333333333; 12.733333333333333; 13.666666666666666; 0.3333333333333333; 0.13333333333333333 -1378194229; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.6; 0.13333333333333333; 0.0 -1378194529; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.2; 0.06666666666666667; 0.0 -1378194829; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378195129; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.06666666666666667; 0.0 -1378195429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378195729; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1378196029; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378196329; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 -1378196629; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378196929; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1378197229; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378197529; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378197829; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378198129; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.0; 0.0 -1378198429; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378198730; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378199030; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1378199330; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 146800.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1378199630; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378199930; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378200230; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1378200530; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378200830; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378201130; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1378201430; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378201730; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378202030; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378202330; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378202630; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378202930; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378203230; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378203530; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378203830; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378204130; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378204430; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378204730; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378205030; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378205330; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 -1378205630; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378205930; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378206230; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378206530; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.26666666666; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1378206831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 141206.93333333332; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378207131; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 1.3333333333333333; 6.133333333333334; 0.0; 0.0 -1378207431; 1; 2599.999343; 32.93332501133333; 1.2666666666666666; 2097152.0; 171964.8; 21.6; 7.2; 0.06666666666666667; 0.0 -1378207731; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378208031; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141207.46666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1378208331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378208631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378208931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1378209231; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378209531; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378209831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1378210131; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150992.8; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 -1378210431; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174761.06666666668; 0.0; 1.0; 0.0; 0.0 -1378210731; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.2; 0.13333333333333333; 0.0 -1378211031; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378211331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378211631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378211931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 146799.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1378212231; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378212531; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378212831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.13333333333; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 -1378213131; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378213431; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378213731; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 137012.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378214031; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.6; 0.0; 1.0; 0.0; 0.0 -1378214331; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378214631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1378214931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378215231; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378215531; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378215831; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378216131; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378216431; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1378216731; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 -1378217031; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.26666666666; 0.0; 1.0; 0.0; 0.0 -1378217331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 152392.0; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 -1378217631; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 162178.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378217932; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378218232; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1378218532; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378218832; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 -1378219132; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 6.466666666666667; 0.2; 0.13333333333333333 -1378219432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.6666666666666667; 0.0; 0.0 -1378219732; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378220032; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378220332; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1378220632; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1378220932; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118836.53333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 -1378221232; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 176159.2; 0.0; 1.0; 0.2; 0.0 -1378221532; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378221832; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378222132; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378222432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378222732; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378223032; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378223332; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378223632; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 -1378223932; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378224232; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378224532; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.26666666666666666; 2.8; 0.06666666666666667; 0.4666666666666667 -1378224832; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.4666666666666667; 0.0 -1378225132; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378225432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 -1378225732; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 5.866666666666666; 0.26666666666666666; 0.13333333333333333 -1378226032; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 2.4; 0.3333333333333333; 0.0 -1378226332; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378226632; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378226932; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1378227232; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378227533; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378227833; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1378228133; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1378228433; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.4; 0.0; 1.0; 0.0; 0.0 -1378228733; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.4; 0.0; 0.0 -1378229033; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378229333; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378229633; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1378229933; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378230233; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 12.066666666666666; 0.0; 0.0 -1378230533; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378230833; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1378231133; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378231433; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1378231733; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378232033; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 164974.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378232333; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378232633; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378232933; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 -1378233233; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378233533; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1378233833; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378234133; 1; 2599.999343; 71.06664870866665; 2.733333333333333; 2097152.0; 789924.8; 161.06666666666666; 22.2; 0.06666666666666667; 0.4 -1378234433; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 331348.0; 0.0; 2.933333333333333; 0.0; 0.0 -1378234733; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 188741.6; 31.8; 3.466666666666667; 0.0; 0.0 -1378235033; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.6; 0.8; 2.3333333333333335; 0.06666666666666667; 0.0 -1378235333; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 188741.6; 0.06666666666666667; 3.466666666666667; 0.13333333333333333; 0.5333333333333333 -1378235633; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159382.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378235933; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378236233; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378236533; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378236834; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378237134; 1; 2599.999343; 46.799988174; 1.8; 2097152.0; 208315.73333333334; 161.8; 14.8; 0.0; 0.13333333333333333 -1378237434; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 469760.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1378237734; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 191538.4; 31.8; 4.066666666666666; 0.0; 0.0 -1378238034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 213908.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378238334; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378238634; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 7.0; 0.2; 0.13333333333333333 -1378238934; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 146798.4; 0.0; 2.066666666666667; 0.06666666666666667; 0.5333333333333333 -1378239234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378239534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378239834; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378240134; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378240434; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 -1378240734; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378241034; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378241334; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 -1378241634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378241934; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378242234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378242534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 2.6; 0.0; 0.5333333333333333 -1378242834; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378243134; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.0; 0.0; 0.8; 0.0; 0.0 -1378243434; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378243734; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378244034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378244334; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378244634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 7.2; 0.2; 0.13333333333333333 -1378244934; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378245234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378245534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 -1378245834; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378246134; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378246434; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1378246734; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378247034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378247334; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378247634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132817.86666666667; 0.06666666666666667; 1.5333333333333334; 0.0; 0.06666666666666667 -1378247935; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378248235; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378248535; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378248835; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378249135; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378249435; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378249735; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.33333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378250035; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378250335; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378250635; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1378250935; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1378251235; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 148198.13333333333; 0.0; 2.066666666666667; 0.0; 0.0 -1378251536; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 -1378251836; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378252136; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.6; 0.0; 0.0 -1378252436; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1378252736; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378253036; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378253336; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378253636; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163576.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1378253936; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150994.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378254236; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378254536; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378254836; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 114642.93333333333; 0.5333333333333333; 1.4666666666666666; 0.0; 0.0 -1378255136; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378255436; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378255736; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378256036; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378256336; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 -1378256636; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378256936; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 176159.2; 0.2; 2.533333333333333; 0.0; 0.5333333333333333 -1378257236; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150992.8; 0.06666666666666667; 1.0; 0.0; 0.0 -1378257536; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1378257836; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 12.8; 13.0; 0.4; 0.13333333333333333 -1378258136; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378258436; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 152391.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1378258736; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378259036; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1378259336; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378259636; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1378259936; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378260236; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378260537; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157983.46666666667; 0.0; 2.6; 0.0; 0.5333333333333333 -1378260837; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378261137; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 166373.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1378261437; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378261737; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378262037; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378262337; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378262637; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378262937; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378263237; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.0; 1.2; 0.0; 0.0 -1378263537; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110447.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378263837; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1378264137; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 2.2; 0.0; 0.4666666666666667 -1378264437; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1378264737; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163577.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378265037; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378265337; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378265637; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 -1378265937; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378266237; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1378266537; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378266837; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378267137; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.06666666666666667; 0.0 -1378267437; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 1.4666666666666666; 1.4; 0.0; 0.0 -1378267737; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 141206.66666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1378268037; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378268338; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1378268638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378268938; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378269238; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378269538; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1378269838; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.7333333333333334; 0.0; 0.0 -1378270138; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 -1378270438; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378270738; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1378271038; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378271338; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 166372.26666666666; 0.06666666666666667; 2.6; 0.0; 0.5333333333333333 -1378271638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 139809.33333333334; 0.0; 7.0; 0.26666666666666666; 0.2 -1378271938; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 146800.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1378272238; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1378272538; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378272838; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378273138; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 -1378273438; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378273738; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 11.666666666666666; 0.06666666666666667; 0.0 -1378274038; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378274338; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378274638; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1378274938; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378275238; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378275538; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1378275838; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378276138; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378276438; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.13333333333333333 -1378276738; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.5333333333333334; 0.0; 0.0 -1378277038; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 -1378277338; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378277638; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 6.933333333333334; 0.4666666666666667; 0.13333333333333333 -1378277938; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378278238; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378278538; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 156586.93333333332; 0.0; 2.6; 0.0; 0.5333333333333333 -1378278838; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 156584.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378279138; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 -1378279438; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124428.8; 0.0; 1.0; 0.0; 0.0 -1378279738; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1378280038; 1; 2599.999343; 32.93332501133333; 1.2666666666666666; 2097152.0; 164974.66666666666; 161.13333333333333; 20.4; 0.06666666666666667; 0.4 -1378280338; 1; 2599.999343; 53.733319755333326; 2.0666666666666664; 2097152.0; 759166.4; 0.0; 3.6666666666666665; 0.0; 0.0 -1378280638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 314570.4; 31.8; 3.7333333333333334; 0.0; 0.0 -1378280938; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 204119.46666666667; 0.0; 2.8; 0.0; 0.0 -1378281238; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 183149.06666666668; 0.0; 2.066666666666667; 0.0; 0.0 -1378281538; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 148197.86666666667; 0.0; 1.0; 0.0; 0.0 -1378281838; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.13333333333333333; 0.0 -1378282138; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163575.73333333334; 0.06666666666666667; 2.533333333333333; 0.0; 0.5333333333333333 -1378282438; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.66666666666; 0.0; 1.2; 0.0; 0.0 -1378282739; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378283039; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378283339; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378283639; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378283939; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1378284239; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378284539; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 -1378284839; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116040.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378285139; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378285439; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378285739; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1378286039; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.06666666668; 0.0; 1.0; 0.0; 0.0 -1378286339; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.06666666668; 0.0; 1.0; 0.0; 0.0 -1378286639; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 -1378286939; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378287239; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378287539; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378287839; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378288139; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 137013.06666666668; 20.4; 2.3333333333333335; 0.0; 0.06666666666666667 -1378288439; 1; 2599.999343; 29.466659220666667; 1.1333333333333333; 2097152.0; 135614.93333333332; 0.0; 3.933333333333333; 0.0; 0.0 -1378288739; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.466666666666667; 0.0; 0.0 -1378289039; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 152390.93333333332; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378289340; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 -1378289640; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 166372.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378289940; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1378290240; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 160780.53333333333; 0.0; 1.0; 0.0; 0.0 -1378290540; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1378290840; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378291140; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378291440; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378291740; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378292040; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378292340; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378292640; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378292940; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.06666666667; 0.13333333333333333; 2.6666666666666665; 0.06666666666666667; 0.5333333333333333 -1378293240; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 174760.8; 0.0; 1.0; 0.0; 0.0 -1378293540; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378293840; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378294140; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378294440; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378294740; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378295040; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378295340; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 -1378295640; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378295940; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 -1378296240; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 156585.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378296540; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 191538.13333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1378296840; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 194334.66666666666; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 -1378297140; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 181751.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378297441; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378297741; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1378298041; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378298341; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1378298641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378298941; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378299241; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378299541; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378299841; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 160780.0; 0.0; 1.0; 0.0; 0.0 -1378300141; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 162177.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378300441; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 1.2; 0.0; 0.0 -1378300741; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378301041; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 148198.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378301341; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378301641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.9333333333333333; 1.7333333333333334; 0.0; 0.0 -1378301941; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378302241; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378302541; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378302841; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378303141; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378303441; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 7.466666666666667; 0.2; 0.13333333333333333 -1378303741; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 160780.0; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1378304041; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 174760.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378304341; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378304642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1378304942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378305242; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 177557.06666666668; 0.2; 1.2; 0.06666666666666667; 0.13333333333333333 -1378305542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378305842; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378306142; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 -1378306442; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1378306742; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378307042; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 149595.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1378307342; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 138410.13333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378307641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378307941; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1378308241; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378308541; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378308841; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378309141; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1378309441; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.2; 0.0 -1378309741; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 148198.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378310041; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378310341; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 7.133333333333334; 0.4; 0.13333333333333333 -1378310641; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378310941; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 2.466666666666667; 0.8666666666666667; 0.5333333333333333 -1378311241; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 -1378311541; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 -1378311842; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1378312142; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378312442; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378312742; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378313042; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378313342; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1378313642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378313942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378314242; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.8666666666666667; 0.0; 0.0 -1378314542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1378314842; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174760.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378315142; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378315442; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378315742; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 86680.26666666666; 12.733333333333333; 13.533333333333333; 0.4666666666666667; 0.2 -1378316042; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 -1378316342; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378316642; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378316942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.8666666666666667; 0.0 -1378317242; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104855.2; 0.0; 11.866666666666667; 0.2; 0.0 -1378317542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378317842; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.4666666666666666; 0.0; 0.0 -1378318142; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.13333333333; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 -1378318442; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 138410.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378318742; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378319042; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378319342; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378319642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378319942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 148197.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378320243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378320543; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378320843; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 -1378321143; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 -1378321443; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378321743; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1378322043; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 178955.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378322343; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1378322643; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 148197.33333333334; 0.0; 1.2; 0.0; 0.0 -1378322943; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1378323243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378323543; 1; 2599.999343; 39.866656592666665; 1.5333333333333334; 2097152.0; 160779.73333333334; 161.0; 14.4; 0.0; 0.2 -1378323843; 1; 2599.999343; 27.733326325333334; 1.0666666666666667; 2097152.0; 443195.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 -1378324143; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 184547.2; 31.8; 4.066666666666666; 0.0; 0.0 -1378324443; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 192936.26666666666; 0.0; 1.0; 0.0; 0.0 -1378324743; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378325043; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378325343; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121632.8; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1378325643; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.2; 0.0; 0.0 -1378325943; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378326243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1378326543; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378326843; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 -1378327143; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378327443; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378327743; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378328043; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378328343; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.3333333333333333; 0.0; 0.0 -1378328643; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378328943; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159381.6; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1378329244; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 190139.46666666667; 0.0; 7.933333333333334; 0.2; 0.13333333333333333 -1378329544; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153790.13333333333; 0.0; 1.2; 0.0; 0.0 -1378329844; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1378330144; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378330444; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1378330744; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 149595.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378331044; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378331344; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378331644; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378331944; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378332244; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378332544; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127225.86666666667; 0.06666666666666667; 2.8; 0.06666666666666667; 0.5333333333333333 -1378332844; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.33333333333; 0.0; 1.0; 0.0; 0.0 -1378333144; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378333444; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 -1378333744; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378334044; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 -1378334344; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378334644; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 7.2; 0.2; 0.13333333333333333 -1378334944; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 145401.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 -1378335244; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 169169.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 -1378335544; 1; 2599.999343; 65.86665002266666; 2.533333333333333; 2097152.0; 485139.4666666667; 161.0; 21.333333333333332; 0.06666666666666667; 0.4 -1378335844; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 588599.4666666667; 1.0666666666666667; 3.066666666666667; 0.0; 0.0 -1378336144; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 306181.86666666664; 32.666666666666664; 5.6; 0.06666666666666667; 0.4666666666666667 -1378336444; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 236276.53333333333; 0.0; 2.466666666666667; 0.0; 0.0 -1378336744; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 169169.6; 0.0; 1.6666666666666667; 0.0; 0.0 -1378337045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 -1378337345; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 3.8; 1.4; 0.0; 0.0 -1378337645; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 156586.13333333333; 0.4; 3.2666666666666666; 0.0; 0.0 -1378337945; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378338245; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378338545; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378338845; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378339145; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378339445; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378339745; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 -1378340045; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378340345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128623.46666666666; 0.0; 0.8; 0.0; 0.0 -1378340645; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 -1378340945; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1378341245; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.6; 7.333333333333333; 0.2; 0.13333333333333333 -1378341545; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378341845; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1378342145; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378342445; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 -1378342745; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378343045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1378343345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 153789.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378343645; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378343945; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 152391.73333333334; 0.0; 1.0; 0.0; 0.0 -1378344245; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378344545; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1378344845; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 1.4666666666666666; 0.0; 0.0 -1378345145; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378345445; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1378345745; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1378346045; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378346345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378346645; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378346945; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378347245; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163576.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378347545; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 7.466666666666667; 0.3333333333333333; 0.13333333333333333 -1378347845; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123030.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378348145; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1378348445; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378348745; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378349045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378349345; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1378349645; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378349945; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378350245; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378350545; 1; 2599.999601; 25.99999601; 1.0; 2097152.0; 167772.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378350845; 1; 2599.999601; 19.066663740666666; 0.7333333333333333; 2097152.0; 167772.0; 0.0; 1.1333333333333333; 0.2; 0.0 -1378351145; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378351445; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378351745; 1; 2599.999601; 12.133331471333332; 0.4666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378352046; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 103457.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378352346; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 109049.86666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378352646; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378352946; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 -1378353246; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378353546; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1378353846; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.06666666666666667; 6.533333333333333; 0.26666666666666666; 0.13333333333333333 -1378354146; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 180353.6; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 -1378354446; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378354746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 1.0; 0.0; 0.0 -1378355046; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378355346; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378355646; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378355946; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 -1378356246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 -1378356546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378356846; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378357146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378357446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378357746; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378358046; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378358346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378358646; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378358947; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.6666666666666667; 0.0; 0.0 -1378359247; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378359547; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1378359847; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1378360147; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1378360447; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378360747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378361047; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 123031.73333333334; 0.0; 11.866666666666667; 0.0; 0.0 -1378361347; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 155186.93333333332; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1378361647; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 171965.6; 0.0; 0.8666666666666667; 4.4; 0.0 -1378361947; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 162177.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378362247; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 1.2; 0.26666666666666666; 0.0 -1378362547; 1; 2599.999601; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378362847; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 173362.13333333333; 0.06666666666666667; 2.8666666666666667; 0.13333333333333333; 0.13333333333333333 -1378363147; 1; 2599.999601; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 1.7333333333333334; 0.0; 0.0 -1378363447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378363747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378364047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378364347; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378364647; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378364947; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 149595.46666666667; 0.26666666666666666; 2.4; 0.06666666666666667; 0.5333333333333333 -1378365247; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 180352.8; 0.0; 1.0; 0.0; 0.0 -1378365547; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 134216.8; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1378365847; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378366147; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378366447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378366747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378367047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 155188.0; 0.0; 1.7333333333333334; 0.0; 0.0 -1378367347; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.2; 0.0 -1378367647; 1; 2599.999601; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.0; 0.0; 0.0 -1378367947; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378368247; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378368547; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 146799.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378368848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378369148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378369448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378369748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1378370048; 1; 2599.999601; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378370348; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1378370648; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378370948; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378371248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378371548; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378371848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378372148; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 141206.66666666666; 0.0; 8.2; 0.26666666666666666; 0.6666666666666666 -1378372448; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 1.2; 0.0; 0.0 -1378372748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150994.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378373047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378373347; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1378373647; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378373947; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1378374247; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378374547; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378374847; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378375147; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378375447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 -1378375747; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 117439.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1378376047; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378376347; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378376648; 1; 2599.999601; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1378376948; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378377248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378377548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378377848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378378148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378378448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378378748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378379048; 1; 2599.999601; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378379348; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 142605.6; 13.0; 18.6; 0.3333333333333333; 0.6 -1378379648; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 130021.6; 0.0; 1.2; 0.0; 0.0 -1378379948; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1378380248; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1378380548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109049.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378380848; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 54523.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378381148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1378381448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 -1378381748; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378382048; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378382348; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1378382648; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378382948; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 155187.2; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1378383248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378383548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378383848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378384149; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378384449; 1; 2599.998989; 51.999979780000004; 2.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378384749; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1378385049; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378385349; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378385649; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 139809.33333333334; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 -1378385949; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1378386249; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378386549; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.6; 0.0; 2.533333333333333; 0.13333333333333333; 0.5333333333333333 -1378386849; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 159381.86666666667; 0.0; 0.8; 0.0; 0.0 -1378387149; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 -1378387449; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378387749; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378388049; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1378388349; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1378388649; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1378388949; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378389249; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1378389549; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1378389849; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378390149; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 138410.4; 0.2; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378390449; 1; 2599.998989; 74.53330435133334; 2.8666666666666667; 2097152.0; 250258.93333333332; 161.0; 21.8; 0.06666666666666667; 0.3333333333333333 -1378390749; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 717224.5333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.0 -1378391049; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 359310.13333333336; 31.8; 3.6; 0.0; 0.0 -1378391949; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 145401.86666666667; 0.0; 1.0; 0.0; 0.0 -1378392249; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 6.4; 0.2; 0.13333333333333333 -1378392549; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378392849; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.2; 0.0 -1378393149; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378393449; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378393749; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 181751.46666666667; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 -1378394050; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 149595.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 -1378394350; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 -1378394650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 145401.06666666668; 0.0; 1.2; 0.0; 0.0 -1378394950; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 -1378395250; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 -1378395550; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1378395850; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378396150; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378396450; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378396750; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378397050; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378397350; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 131420.53333333333; 0.0; 2.7333333333333334; 0.13333333333333333; 0.5333333333333333 -1378397650; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 149595.46666666667; 0.0; 0.8; 0.0; 0.0 -1378397950; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378398250; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378398550; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378398850; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378399150; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 120234.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378399450; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1378399750; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 1.0; 0.13333333333333333; 0.0 -1378400050; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378400350; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378400650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378400950; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125827.2; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 -1378401250; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 150994.4; 0.0; 1.0; 0.0; 0.0 -1378401550; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 -1378401850; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378402150; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378402450; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378402750; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378403050; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1378403350; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.7333333333333334; 0.0; 0.0 -1378403650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378403951; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378404251; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 117439.2; 0.0; 1.6; 0.0; 0.0 -1378404551; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 146798.4; 0.0; 13.0; 0.06666666666666667; 0.4666666666666667 -1378404851; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 178954.66666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1378405151; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 163575.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378405451; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378405750; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138411.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378406050; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378406350; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378406650; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378406950; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378407250; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378407550; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378407850; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378408150; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 164974.13333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378408450; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 146799.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1378408751; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378409051; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378409351; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378409651; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378409951; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378410251; 1; 2599.998989; 51.999979780000004; 2.0; 2097152.0; 591395.2; 161.73333333333332; 14.2; 0.0; 0.2 -1378410551; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 272627.2; 0.0; 1.5333333333333334; 0.0; 0.0 -1378410851; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159383.2; 31.8; 3.533333333333333; 0.0; 0.0 -1378411151; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1378411451; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 4.466666666666667; 0.0 -1378411751; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 159382.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378412051; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 -1378412351; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378412651; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378412951; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1378413251; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 159382.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378413551; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1378413851; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378414151; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378414451; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 113244.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1378414751; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378415051; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378415351; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.13333333333333333; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1378415651; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378415951; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378416251; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378416551; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378416851; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378417152; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378417452; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378417752; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 78291.46666666666; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 -1378418052; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378418352; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 71300.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378418652; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1378418952; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.06666666666666667; 2.1333333333333333; 0.0; 0.4666666666666667 -1378419252; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378419552; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378419852; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378420152; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378420452; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 1.6; 0.06666666666666667; 0.13333333333333333 -1378420752; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378421052; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378421352; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378421652; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378421952; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378422252; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 -1378422552; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144002.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1378422852; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 -1378423152; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378423452; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378423752; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378424052; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378424352; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378424653; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.06666666666666667; 6.333333333333333; 0.2; 0.13333333333333333 -1378424953; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 2.1333333333333333; 0.0; 0.0 -1378425253; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378425553; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378425853; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378426153; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378426453; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 132817.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378426753; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378427053; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378427353; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378427653; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 146799.2; 0.5333333333333333; 1.4; 0.0; 0.0 -1378427953; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 116041.06666666667; 0.0; 1.4; 0.0; 0.0 -1378428253; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378428553; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378428853; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378429153; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 150994.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378429453; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 138410.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378429753; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1378430053; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 162178.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378430353; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378430653; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378430953; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378431253; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1378431553; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378431853; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378432153; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378432453; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378432753; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378433054; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1378433354; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 118836.8; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1378433654; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.66666666666; 0.0; 1.6666666666666667; 0.0; 0.0 -1378433954; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 167770.4; 0.0; 1.2; 0.0; 0.0 -1378434254; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 -1378434554; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378434854; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378435154; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378435454; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378435754; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378436054; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 -1378436354; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 -1378436654; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378436954; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 157983.73333333334; 0.4; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 -1378437254; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 208316.0; 12.733333333333333; 13.2; 0.3333333333333333; 0.13333333333333333 -1378437554; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378437854; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1378438154; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1378438454; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378438754; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378439053; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378439354; 1; 2599.998989; 69.33330637333334; 2.666666666666667; 2097152.0; 310376.8; 161.0; 22.266666666666666; 0.06666666666666667; 0.3333333333333333 -1378439654; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 666892.2666666667; 0.0; 2.466666666666667; 0.0; 0.0 -1378439954; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 279618.4; 31.8; 3.533333333333333; 0.0; 0.0 -1378440254; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 194334.66666666666; 0.8; 2.533333333333333; 0.0; 0.0 -1378440554; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 187343.46666666667; 0.0; 3.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378440854; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 195732.8; 0.0; 1.0; 0.0; 0.0 -1378441154; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378441454; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1378441754; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378442054; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378442354; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 121632.8; 0.0; 1.0; 0.0; 0.0 -1378442654; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 -1378442954; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378443254; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 153789.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378443554; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378443854; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 1.0; 0.0; 0.0 -1378444154; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 187343.73333333334; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 -1378444454; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159382.13333333333; 0.0; 1.0; 0.0; 0.0 -1378444754; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 156586.13333333333; 0.0; 1.0; 0.0; 0.0 -1378445054; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378445354; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378445654; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378445954; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 -1378446254; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378446554; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378446855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 1.0; 0.0; 0.0 -1378447155; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 -1378447455; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378447755; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.06666666666666667; 3.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378448055; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378448355; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132817.86666666667; 0.0; 11.933333333333334; 0.0; 0.0 -1378448655; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1378448955; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378449255; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 120235.46666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.13333333333333333 -1378449555; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 164974.93333333332; 0.0; 1.7333333333333334; 0.0; 0.0 -1378449855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 -1378450155; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.8666666666666667; 0.0; 0.0 -1378450455; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 -1378450755; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1378451055; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137012.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378451355; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.66666666666; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 -1378451655; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378451955; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1378452255; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1378452555; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378452855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127225.06666666667; 0.0; 1.2; 0.0; 0.0 -1378453155; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378453455; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 -1378453755; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 -1378454055; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1378454355; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378454655; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378454955; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 -1378455255; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378455555; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378455855; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378456155; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1378456456; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1378456756; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378457056; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378457356; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1378457656; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138410.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378457956; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378458256; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378458556; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 155186.93333333332; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 -1378458856; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 157983.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378459156; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127225.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378459456; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378459756; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378460056; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1378460356; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378460656; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378460956; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378461256; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378461556; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378461856; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378462156; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 132818.4; 0.06666666666666667; 2.2; 0.06666666666666667; 0.5333333333333333 -1378462456; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 152391.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378462756; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378463056; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1378463356; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1378463657; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378463957; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 -1378464257; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1378464557; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378464857; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378465157; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378465457; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.13333333333333333; 0.0 -1378465757; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 142605.33333333334; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1378466057; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 176159.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378466357; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 -1378466657; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378466957; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378467257; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378467557; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378467857; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378468157; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1378468457; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.2; 0.13333333333333333 -1378468757; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378469057; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378469657; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 180352.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378470257; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378470557; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.2; 0.0 -1378470857; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 -1378471157; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 1.2; 0.06666666666666667; 0.0 -1378472057; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378472657; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 -1378472957; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 137012.0; 0.06666666666666667; 2.6666666666666665; 0.13333333333333333; 0.4666666666666667 -1378473257; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130021.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378473557; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 1.2666666666666666; 0.2; 0.0 -1378473857; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378474157; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.2; 0.0 -1378474457; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.26666666666666666; 0.0 -1378474757; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 -1378475057; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1378475358; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 -1378475658; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.2; 0.0 -1378475958; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.13333333333333333; 0.0 -1378476258; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378476558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 160779.46666666667; 0.06666666666666667; 2.533333333333333; 0.2; 0.5333333333333333 -1378476858; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 162178.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378477158; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1378477458; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1378477758; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1378478058; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.06666666666666667; 1.2; 0.06666666666666667; 0.13333333333333333 -1378478358; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.2; 0.0; 0.0 -1378478658; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.2; 0.0 -1378478958; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 106253.33333333333; 0.0; 1.2; 0.06666666666666667; 0.0 -1378479258; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378479558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 1.2; 0.0 -1378479858; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378480158; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 128623.2; 0.0; 2.2; 0.26666666666666666; 0.5333333333333333 -1378480458; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118836.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 -1378480758; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378481058; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378481358; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378481658; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378481958; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378482258; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 2.466666666666667; 0.26666666666666666; 0.13333333333333333 -1378482558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 142604.8; 0.0; 5.933333333333334; 0.0; 0.0 -1378482858; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1378483158; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1378483459; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1378483759; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 113244.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378484059; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378484359; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378484659; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378484959; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378485259; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378485559; 1; 2599.998989; 64.13330839533334; 2.466666666666667; 2097152.0; 350922.4; 161.06666666666666; 22.0; 2.1333333333333333; 0.4 -1378485859; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 706038.4; 0.0; 2.8; 0.0; 0.0 -1378486159; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 290803.2; 31.8; 3.7333333333333334; 0.0; 0.0 -1378486459; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 198527.73333333334; 0.26666666666666666; 2.2666666666666666; 0.0; 0.0 -1378486759; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.6; 0.13333333333333333; 0.0 -1378487059; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378487359; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 128623.46666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 -1378487659; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 156586.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378487959; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378488259; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 171964.8; 0.0; 6.866666666666666; 0.5333333333333333; 0.13333333333333333 -1378488559; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378488859; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378489159; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378489459; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378489759; 1; 2599.998989; 0.0; 0.0; 2097152.0; 163576.53333333333; 0.0; 0.9333333333333333; 0.2; 0.0 -1378490059; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 152390.66666666666; 0.0; 1.0; 0.2; 0.0 -1378490359; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.13333333333333333; 0.0 -1378490659; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378490959; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 118837.06666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378491259; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 137012.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378491559; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1378491859; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 11.8; 0.0; 0.0 -1378492159; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.06666666667; 0.0; 0.8; 0.0; 0.0 -1378492459; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.6666666666666667; 0.0; 0.0 -1378492759; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 -1378493059; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 1.0; 0.0; 0.0 -1378493360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378493660; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128623.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378493960; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378494260; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 104856.0; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 -1378494560; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 183149.6; 0.06666666666666667; 2.4; 0.0; 0.5333333333333333 -1378494860; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 164974.4; 0.0; 1.7333333333333334; 0.0; 0.0 -1378495160; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378495460; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1378495760; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378496060; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378496360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378496660; 1; 2599.998989; 41.599983824; 1.6; 2097152.0; 450186.93333333335; 161.8; 14.733333333333333; 0.0; 0.2 -1378496960; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 205519.46666666667; 0.0; 1.6; 0.0; 0.0 -1378497260; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 194333.33333333334; 31.8; 3.6; 0.0; 0.0 -1378497560; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378497860; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1378498160; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 127225.06666666667; 0.0; 2.533333333333333; 0.0; 0.5333333333333333 -1378498460; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 156585.6; 0.0; 1.0; 0.0; 0.0 -1378498760; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 -1378499060; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378499360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378499660; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 162177.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378499960; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 12.733333333333333; 12.866666666666667; 0.4; 0.13333333333333333 -1378500260; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 1.3333333333333333; 0.0; 0.0 -1378500560; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378500860; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378501160; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1378501460; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378501760; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 156585.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 -1378502060; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 208314.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378502360; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 139809.33333333334; 0.0; 1.0; 0.0; 0.0 -1378502660; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378502960; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378503260; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378503560; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378503860; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378504160; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106253.86666666667; 0.0; 0.8; 0.0; 0.0 -1378504460; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378504760; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378505060; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 1.0; 0.0; 0.0 -1378505360; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 170566.4; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 -1378505660; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 183149.33333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1378505960; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378506260; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.0; 0.06666666666666667; 7.0; 0.3333333333333333; 0.13333333333333333 -1378506560; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1378506860; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 134216.0; 0.06666666666666667; 1.5333333333333334; 0.4666666666666667; 0.06666666666666667 -1378507160; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378507460; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378507761; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378508061; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 -1378508361; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378508661; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378508961; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 146799.2; 0.06666666666666667; 2.2; 0.0; 0.4666666666666667 -1378509261; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378509561; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378509861; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378510161; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1378510461; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378510761; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378511061; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 -1378511361; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378511661; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378511961; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378512261; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 138409.6; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378512561; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 138410.4; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1378512861; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 -1378513161; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378513461; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378513761; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378514061; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 124429.06666666667; 0.5333333333333333; 1.3333333333333333; 0.13333333333333333; 0.0 -1378514361; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378514661; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.4666666666666667; 0.0 -1378514961; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378515261; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 -1378515561; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 55921.333333333336; 0.0; 0.9333333333333333; 0.0; 0.0 -1378515861; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378516161; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 146798.93333333332; 0.0; 2.6; 0.0; 0.5333333333333333 -1378516461; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 167770.66666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378516761; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 135613.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378517061; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 71300.8; 0.0; 1.0; 0.0; 0.0 -1378517361; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 -1378517661; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378517961; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 -1378518261; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 78291.46666666666; 0.2; 6.4; 0.2; 0.13333333333333333 -1378518561; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 163577.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 -1378518861; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378519161; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.06666666666666667; 0.0 -1378519461; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378519761; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1378520061; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 159381.06666666668; 0.0; 0.8; 0.0; 0.0 -1378520361; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 -1378520662; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378520962; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 10.266666666666667; 0.0 -1378521262; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378521562; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 -1378521862; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 -1378522162; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378522462; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378522762; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378523062; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378523362; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124428.8; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 -1378523662; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 1.0; 0.0; 0.0 -1378523962; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378524262; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378524562; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 8.2; 0.0 -1378524862; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378525162; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 -1378525462; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 65708.26666666666; 0.0; 1.4; 0.0; 0.0 -1378525762; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 139809.33333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1378526062; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378526362; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378526662; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 74097.06666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1378527862; 1; 2599.998989; 16.714279215; 0.6428571428571429; 2097152.0; 107852.0; 0.0; 1.0714285714285714; 0.07692307692307693; 0.0 -1378528762; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.4; 0.0 -1378529062; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.0; 5.066666666666666; 0.0 -1378529362; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378529662; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1378529963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.6666666666666666; 0.0; 0.0 -1378530263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1378530563; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.93333333332; 0.06666666666666667; 8.333333333333334; 0.26666666666666666; 0.6 -1378530863; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378531163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 -1378531463; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378531763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378532063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1378532363; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378532663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.06666666666666667; 0.0 -1378532963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378533263; 1; 2599.998989; 60.66664307666668; 2.3333333333333335; 2097152.0; 406845.3333333333; 161.06666666666666; 21.533333333333335; 0.06666666666666667; 0.4 -1378533563; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 562034.4; 0.0; 2.533333333333333; 0.06666666666666667; 0.0 -1378533863; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 293599.2; 31.8; 4.333333333333333; 0.06666666666666667; 0.0 -1378534163; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 251656.0; 0.8; 3.933333333333333; 0.06666666666666667; 0.4666666666666667 -1378534463; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 167770.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1378534763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378535063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1378535363; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 -1378535663; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 13.4; 0.13333333333333333; 0.13333333333333333 -1378535963; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134215.2; 0.0; 1.4666666666666666; 0.13333333333333333; 0.0 -1378536263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1378536563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378536863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 -1378537163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378537463; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 7.0; 0.2; 0.13333333333333333 -1378537763; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378538063; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378538363; 1; 2599.998989; 0.0; 0.0; 2097152.0; 159383.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378538663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378538963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1378539263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378539563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378539863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 2.066666666666667; 0.06666666666666667; 0.0 -1378540163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378540463; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378540763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378541063; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.06666666666666667; 1.8666666666666667; 0.0; 0.0 -1378541363; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125827.2; 0.13333333333333333; 2.533333333333333; 0.0; 0.4666666666666667 -1378541663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378541963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378542263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378542563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378542863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378543163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0; 1.8666666666666667; 0.0 -1378543463; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1378543763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378544063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378544364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378544664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378544964; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 146799.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1378545264; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 149596.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378545564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378545864; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1378546164; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378546464; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378546764; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146798.93333333332; 0.0; 1.4; 0.0; 0.0 -1378547064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378547364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378547664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378547964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1378548264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378548564; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378548864; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 -1378549164; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378549464; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.06666666666666667; 0.0 -1378549764; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138410.4; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1378550064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378550364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378550664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378550964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378551264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378551564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378551864; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378552164; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138409.86666666667; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1378552464; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 213907.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378552764; 1; 2599.998989; 0.0; 0.0; 2097152.0; 155187.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378553064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378553364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 -1378553664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378553964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378554264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378554564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 -1378554865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378555165; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378555465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378555765; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.2; 0.06666666666666667; 8.733333333333333; 0.26666666666666666; 0.6 -1378556065; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.6; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1378556365; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 -1378556665; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378556965; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 4.2; 0.0 -1378557265; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378557565; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 -1378557865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378558165; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.06666666666666667; 0.0 -1378558465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 160779.46666666667; 0.0; 0.8; 0.0; 0.0 -1378558765; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 1.0; 0.0; 0.0 -1378559065; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 1.0; 0.0; 0.0 -1378559365; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 116040.53333333334; 0.0; 2.4; 0.0; 0.4666666666666667 -1378559665; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 148197.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1378559965; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378560265; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 -1378560565; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1378560865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378561165; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 146800.0; 12.733333333333333; 13.133333333333333; 0.3333333333333333; 0.2 -1378561465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 156585.33333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1378561765; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378562065; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378562366; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378562666; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118836.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378562966; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 2.466666666666667; 0.13333333333333333; 0.4666666666666667 -1378563266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378563566; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378563866; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378564166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378564466; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132817.86666666667; 0.0; 1.9333333333333333; 0.06666666666666667; 0.13333333333333333 -1378564766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378565066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378565366; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378565666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378565966; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104855.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378566266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378566566; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 145401.06666666668; 0.06666666666666667; 8.266666666666667; 0.2; 0.6 -1378566866; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 173363.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378567166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378567466; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 -1378567766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378568066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378568366; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378568666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378568966; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 -1378569266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378569566; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378569866; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 -1378570166; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 152391.2; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 -1378570466; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148197.6; 0.06666666666666667; 1.2; 0.0; 0.0 -1378570766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378571066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 -1378571366; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378571666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.13333333333333333; 0.0 -1378571966; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378572266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378572566; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378572866; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1378573166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 -1378573466; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1378573766; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 141206.13333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 -1378574066; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 141206.4; 0.0; 1.0; 0.0; 0.0 -1378574367; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.4; 0.0; 0.0 -1378574667; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378574967; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1378575267; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.26666666666; 0.0; 1.0; 0.0; 0.0 -1378575567; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378575867; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378576167; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378576467; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378576767; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378577067; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378577367; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 139808.53333333333; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378577667; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378577967; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.2; 7.0; 0.2; 0.13333333333333333 -1378578267; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378578567; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378578867; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378579167; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 107652.26666666666; 0.0; 11.933333333333334; 0.0; 0.0 -1378579467; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378579767; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378580067; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378580367; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1378580667; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378580967; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 128624.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 -1378581267; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 170566.66666666666; 0.0; 1.8666666666666667; 0.0; 0.0 -1378581567; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378581867; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378582167; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378582467; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378582767; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378583067; 1; 2599.998989; 38.133318505333335; 1.4666666666666666; 2097152.0; 436206.4; 161.73333333333332; 14.8; 0.0; 0.2 -1378583368; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 304784.5333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378583668; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 152390.93333333332; 31.8; 8.6; 0.2; 0.13333333333333333 -1378583968; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 188741.33333333334; 0.0; 2.3333333333333335; 0.0; 0.0 -1378584268; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378584568; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 128624.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1378584868; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 150993.06666666668; 0.0; 0.8; 0.0; 0.0 -1378585168; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1378585468; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378585768; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378586068; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1378586368; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378586668; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378586968; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 -1378587268; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378587568; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378587868; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 -1378588168; 1; 2599.998989; 25.999989890000002; 1.0; 2097152.0; 142604.53333333333; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 -1378588468; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 145401.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378588768; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378589068; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378589368; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1378589668; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139809.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378589968; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 137012.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378590268; 1; 2599.998989; 67.599973714; 2.6; 2097152.0; 595589.6; 161.06666666666666; 22.133333333333333; 0.06666666666666667; 0.4 -1378590568; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 433409.6; 0.0; 2.4; 0.0; 0.0 -1378590868; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 239072.8; 31.8; 3.933333333333333; 0.0; 0.0 -1378591168; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 192936.26666666666; 0.8666666666666667; 2.533333333333333; 0.0; 0.0 -1378591468; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 132818.66666666666; 0.0; 1.5333333333333334; 0.0; 0.0 -1378591768; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 146799.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378592068; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1378592368; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 -1378592668; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378592968; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378593269; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 134216.0; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 -1378593569; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378593869; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 -1378594169; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378594469; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378594769; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 -1378595069; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137012.8; 0.0; 1.2; 0.0; 0.0 -1378595369; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 171964.8; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378595669; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 195731.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378595969; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378596269; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378596569; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 6.0; 0.2; 0.13333333333333333 -1378596869; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 127226.13333333333; 0.0; 2.2; 0.0; 0.0 -1378597169; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378597469; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1378597769; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1378598069; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 -1378598369; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378598669; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1378598969; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 162176.8; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 -1378599269; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 153790.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378599569; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1378599869; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1378600169; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378600469; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 130022.4; 0.5333333333333333; 1.3333333333333333; 0.06666666666666667; 0.0 -1378600769; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.0; 0.0 -1378601069; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378601369; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378601669; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378601970; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378602269; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378602569; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 155188.0; 0.2; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 -1378602869; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 141207.46666666667; 0.0; 0.8; 0.0; 0.0 -1378603169; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 141206.93333333332; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 -1378603469; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378603769; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378604069; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137012.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378604369; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378604669; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378604969; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378605269; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378605569; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1378605869; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 -1378606169; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 141207.46666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1378606469; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.26666666666; 0.0; 0.8; 0.0; 0.0 -1378606769; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1378607069; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153790.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378607369; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378607669; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378607970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.8; 0.0; 0.0 -1378608270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1378608570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.06666666666666667; 0.0 -1378608870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378609170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378609470; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 121633.6; 0.8666666666666667; 1.3333333333333333; 0.06666666666666667; 0.0 -1378609770; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138411.2; 0.0; 2.2; 0.0; 0.4666666666666667 -1378610070; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155187.2; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1378610370; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378610670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 -1378610970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378611270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378611570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1378611870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.6666666666666667; 0.0; 0.0 -1378612170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378612470; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1378612770; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378613070; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378613370; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.86666666667; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 -1378613670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378613970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378614270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378614570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378614870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378615170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378615470; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378615770; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378616070; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 -1378616370; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 146799.2; 0.06666666666666667; 7.266666666666667; 0.2; 0.13333333333333333 -1378616670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378616970; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 120235.46666666666; 0.0; 2.2; 0.0; 0.4666666666666667 -1378617270; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 167770.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378617570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378617871; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 92272.0; 0.0; 0.8666666666666667; 7.6; 0.0 -1378618171; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1378618471; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378618771; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 -1378619071; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378619371; 1; 2599.998989; 0.0; 0.0; 2097152.0; 149596.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378619671; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 1.0; 0.0; 0.0 -1378619971; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378620271; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378620571; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378620871; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 213908.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378621171; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1378621471; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378621771; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378622071; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130021.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.06666666666666667 -1378622371; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.4666666666666666; 0.0; 0.0 -1378622671; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 11.866666666666667; 0.06666666666666667; 0.0 -1378622971; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 12.733333333333333; 13.666666666666666; 0.26666666666666666; 0.13333333333333333 -1378623271; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378623571; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378623871; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 -1378624171; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 96467.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 -1378624472; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378624772; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.2; 0.0 -1378625072; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1378625372; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378625672; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378625972; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.7333333333333334; 0.0; 0.0 -1378626272; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.6; 0.0; 0.0 -1378626572; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378626872; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378627172; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378627472; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378627772; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 153789.6; 0.2; 2.4; 0.06666666666666667; 0.4666666666666667 -1378628072; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 184548.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378628372; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378628672; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378628972; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1378629272; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 -1378629572; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378629872; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 1.2; 0.06666666666666667; 0.0 -1378630172; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378630472; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378630772; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1378631073; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378631373; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 134216.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1378631673; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378631973; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378632273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378632573; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 -1378632873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378633173; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 -1378633473; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 -1378633773; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378634073; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378634373; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378634673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 -1378634973; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 170566.4; 0.0; 8.4; 0.2; 0.6666666666666666 -1378635273; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 170566.4; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.0 -1378635573; 1; 2599.998989; 0.0; 0.0; 2097152.0; 171964.53333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378635873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378636173; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378636473; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378636773; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378637073; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378637373; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378637673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378637973; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378638273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378638573; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.2; 2.533333333333333; 0.0; 0.4666666666666667 -1378638873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378639173; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378639473; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378639773; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378640073; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378640373; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378640673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.4; 0.0; 0.0 -1378640973; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 120234.66666666667; 0.06666666666666667; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 -1378641273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 166373.06666666668; 0.0; 1.0; 0.0; 0.0 -1378641573; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 -1378641873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378642173; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 167770.66666666666; 0.0; 2.7333333333333334; 0.0; 0.4666666666666667 -1378642473; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 183149.6; 0.0; 0.8; 0.0; 0.0 -1378642774; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378643074; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378643374; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 173362.93333333332; 161.0; 21.866666666666667; 0.06666666666666667; 0.4 -1378643674; 1; 2599.998989; 55.46664509866667; 2.1333333333333333; 2097152.0; 708835.7333333333; 0.0; 2.8666666666666667; 0.06666666666666667; 0.0 -1378643974; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 318765.3333333333; 31.8; 3.6666666666666665; 0.0; 0.0 -1378644274; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 183148.53333333333; 0.8; 2.2; 0.0; 0.0 -1378644574; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 150992.53333333333; 0.0; 1.6; 0.0; 0.0 -1378644874; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378645174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1378645474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152390.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378645774; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 153790.13333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378646074; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 162177.6; 0.0; 1.0; 0.0; 0.0 -1378646374; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 -1378646674; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1378646974; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378647274; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378647574; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 148197.33333333334; 1.0; 1.7333333333333334; 0.0; 0.0 -1378647874; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 -1378648174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378648474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378648774; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378649074; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378649374; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 -1378649674; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 176159.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378649974; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378650274; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378650574; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 -1378650874; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155188.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 -1378651174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378651474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378651775; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378652075; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 -1378652375; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378652675; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 104856.0; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 -1378652975; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 149595.46666666667; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1378653275; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 -1378653575; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378653875; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378654175; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378654475; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1378654775; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378655075; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378655375; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378655675; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378655975; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146798.13333333333; 0.0; 1.0; 0.0; 0.0 -1378656275; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 -1378656575; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 2.2; 0.0; 0.5333333333333333 -1378656875; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 -1378657175; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378657475; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 -1378657775; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378658076; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1378658376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378658676; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378658976; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 0.8; 0.0; 0.0 -1378659276; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378659576; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 -1378659876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378660176; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148196.8; 0.0; 2.8; 0.0; 0.4666666666666667 -1378660476; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152391.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378660776; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378661076; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1378661376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378661676; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378661976; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378662276; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378662576; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378662876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378663176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 -1378663476; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378663776; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 148197.6; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 -1378664076; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 138410.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378664376; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378664676; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378664976; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378665276; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 150994.4; 0.0; 6.733333333333333; 0.26666666666666666; 0.2 -1378665576; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 -1378665876; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132817.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378666176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1378666476; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 11.8; 0.0; 0.0 -1378666776; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378667076; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 120234.93333333333; 0.0; 1.2; 0.0; 0.0 -1378667377; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 117439.2; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 -1378667677; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378667976; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378668276; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378668576; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.2; 0.0; 0.0 -1378668876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378669176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378669476; 1; 2599.998989; 39.86665116466667; 1.5333333333333334; 2097152.0; 321561.6; 161.73333333333332; 14.733333333333333; 0.0; 0.2 -1378669776; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 339736.26666666666; 0.0; 1.8666666666666667; 0.0; 0.0 -1378670076; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 162178.66666666666; 31.8; 3.7333333333333334; 0.0; 0.0 -1378670376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 -1378670676; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 7.0; 0.2; 0.13333333333333333 -1378670976; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142604.53333333333; 0.06666666666666667; 2.7333333333333334; 0.0; 0.5333333333333333 -1378671276; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1378671576; 1; 2599.998989; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378671876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378672176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1378672477; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378672777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 -1378673077; 1; 2599.998989; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378673377; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378673677; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378673977; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 -1378674277; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378674577; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 128624.26666666666; 0.13333333333333333; 2.533333333333333; 0.0; 0.4666666666666667 -1378674877; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 -1378675177; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378675477; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378675777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378676077; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1378676377; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.06666666666666667; 1.5333333333333334; 0.2; 0.13333333333333333 -1378676677; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 6.666666666666667; 0.0; 0.0 -1378676977; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378677277; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 -1378677577; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378677877; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 83884.0; 0.26666666666666666; 1.1333333333333333; 0.0; 0.0 -1378678177; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 138410.13333333333; 0.0; 2.533333333333333; 0.0; 0.5333333333333333 -1378678477; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124428.53333333334; 0.0; 1.0; 0.0; 0.0 -1378678777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378679077; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1378679377; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 -1378679677; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.8; 0.06666666666666667; 0.13333333333333333 -1378679977; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 166373.06666666668; 0.0; 0.8; 0.0; 0.0 -1378680277; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378680577; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 -1378680877; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1378681178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378681478; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.2; 1.0666666666666667; 0.0; 0.0 -1378681778; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 137013.06666666668; 0.0; 2.4; 0.0; 0.4666666666666667 -1378682078; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 -1378682378; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378682678; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.13333333333; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 -1378682978; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 145400.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378683278; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378683578; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 -1378683878; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.0; 0.0 -1378684178; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 -1378684478; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378684778; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 -1378685078; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378685378; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 184547.73333333334; 0.06666666666666667; 2.466666666666667; 0.0; 0.5333333333333333 -1378685678; 1; 2599.998989; 0.0; 0.0; 2097152.0; 213908.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378685978; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378686278; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378686578; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378686878; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 164974.4; 0.6; 1.2666666666666666; 0.0; 0.0 -1378687178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 164973.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378687478; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378687778; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378688078; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378688378; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378688678; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378688978; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 149596.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 -1378689278; 1; 2599.998989; 0.0; 0.0; 2097152.0; 162177.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378689578; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 7.2; 0.2; 0.13333333333333333 -1378689878; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 -1378690178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378690478; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378690778; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 -1378691079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378691379; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 -1378691679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378691979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378692279; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378692579; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 131419.73333333334; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1378692879; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155188.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378693179; 1; 2599.998989; 0.0; 0.0; 2097152.0; 148196.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378693479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378693779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378694079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378694379; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378694679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378694979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378695279; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 -1378695579; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 -1378695879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378696179; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 2.8; 0.0; 0.4666666666666667 -1378696479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378696779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378697079; 1; 2599.998989; 64.13330839533334; 2.466666666666667; 2097152.0; 426419.2; 161.2; 21.733333333333334; 0.06666666666666667; 0.4 -1378697379; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 539665.0666666667; 0.0; 2.8; 0.0; 0.0 -1378697679; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 246063.46666666667; 31.8; 3.6666666666666665; 0.0; 0.0 -1378697979; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 159382.4; 0.8; 2.6666666666666665; 0.0; 0.0 -1378698279; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.8666666666666667; 0.0; 0.0 -1378698579; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378698879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378699180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 1.0; 0.0; 0.0 -1378699480; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378699780; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.53333333333; 6.8; 2.533333333333333; 0.0; 0.4666666666666667 -1378700080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118836.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378700380; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378700679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378700979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378701279; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 142605.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.2 -1378701579; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378701879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378702179; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0; 0.0; 0.0 -1378702479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378702779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378703079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378703379; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 183149.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 -1378703680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 160780.53333333333; 0.0; 1.0; 0.0; 0.0 -1378703980; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378704280; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 111846.66666666667; 1.0; 2.0; 0.0; 0.0 -1378704580; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378704880; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378705180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378705480; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378705780; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378706080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378706380; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378706680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378706980; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 1.9333333333333333; 0.0; 0.4666666666666667 -1378707280; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 6.333333333333333; 0.26666666666666666; 0.13333333333333333 -1378707580; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 148196.53333333333; 0.0; 1.5333333333333334; 0.0; 0.0 -1378707880; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378708180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378708480; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.8; 0.06666666666666667; 0.06666666666666667 -1378708780; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.53333333333; 0.0; 1.8; 0.0; 0.0 -1378709080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0; 0.0; 0.0 -1378709380; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378709680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378709980; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 11.933333333333334; 0.0; 0.0 -1378710280; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378710580; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 135613.33333333334; 0.26666666666666666; 2.3333333333333335; 0.0; 0.4666666666666667 -1378710880; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 156585.6; 0.0; 1.0; 0.0; 0.0 -1378711180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378711481; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 -1378711781; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135613.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1378712081; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378712381; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378712681; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.9333333333333333; 0.0; 0.0 -1378712981; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378713281; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378713581; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378713881; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 -1378714181; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 174760.8; 0.0; 8.6; 0.2; 0.6666666666666666 -1378714481; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155187.46666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378714781; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 -1378715081; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 -1378715381; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 -1378715681; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378715981; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378716281; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378716581; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378716881; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378717181; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378717481; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378717782; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.0; 0.0; 2.4; 0.0; 0.4666666666666667 -1378718082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152391.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378718382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378718682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378718982; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378719282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378719582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 -1378719882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378720182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378720482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378720782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1378721082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378721382; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 145400.8; 0.0; 8.733333333333333; 0.2; 0.6 -1378721682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153788.53333333333; 0.0; 0.8; 0.0; 0.0 -1378721982; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378722282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1378722582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378722882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378723182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378723482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1378723782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 -1378724082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378724382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 1.0; 0.0; 0.0 -1378724682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 -1378724982; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378725282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 -1378725582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378725882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 -1378726182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.26666666666666666; 0.0 -1378726482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.0; 0.0 -1378726782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378727082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.4; 0.0; 0.0 -1378727382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 -1378727682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.26666666666; 0.0; 0.8; 0.13333333333333333; 0.0 -1378727983; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 208314.93333333332; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1378728283; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 -1378728583; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 156585.06666666668; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378728883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153790.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378729183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378729483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 -1378729783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 -1378730083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 -1378730383; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 -1378730683; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378730983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378731283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378731583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 -1378731883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378732183; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 162178.4; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 -1378732483; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378732783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 -1378733083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378733383; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 7.2; 0.26666666666666666; 0.2 -1378733683; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378733983; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378734283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 -1378734583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 -1378734883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378735183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378735483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.3333333333333333; 0.0 -1378735783; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 180352.8; 0.13333333333333333; 2.6; 0.0; 0.4666666666666667 -1378736083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378736383; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 -1378736683; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378736983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378737283; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 -1378737583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378737883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378738183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 1.0; 0.0; 0.0 -1378738483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.06666666666666667; 0.0 -1378738783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378739083; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 6.266666666666667; 0.2; 0.13333333333333333 -1378739383; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 181750.93333333332; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 -1378739683; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 157983.46666666667; 0.0; 1.0; 0.0; 0.0 -1378739983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167771.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378740283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.6666666666666666; 0.0 -1378740583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378740883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378741183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378741483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 -1378741783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 -1378742084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378742384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378742684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378742984; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138410.4; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 -1378743284; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378743584; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378743884; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378744184; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378744484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 -1378744784; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378745084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 -1378745384; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 12.733333333333333; 12.133333333333333; 0.4; 0.2 -1378745684; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 2.4; 0.0; 0.0 -1378745984; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.4666666666666666; 0.0; 0.0 -1378746284; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 1.4666666666666666; 1.2; 0.0; 0.0 -1378746584; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378746884; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378747184; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378747484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 -1378747784; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1378748084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378748384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378748684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378748984; 1; 2599.998989; 65.86664105466667; 2.533333333333333; 2097152.0; 468361.86666666664; 161.06666666666666; 21.733333333333334; 0.06666666666666667; 0.4 -1378749284; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 441797.6; 0.0; 2.8; 0.0; 0.0 -1378749584; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 248859.73333333334; 31.8; 3.7333333333333334; 0.0; 0.0 -1378749884; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 183149.06666666668; 0.8; 2.533333333333333; 0.0; 0.0 -1378750184; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 188742.4; 0.0; 3.466666666666667; 0.0; 0.4666666666666667 -1378750484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 -1378750784; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1378751084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378751384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378751684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378751984; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 160779.73333333334; 0.06666666666666667; 7.4; 0.2; 0.13333333333333333 -1378752284; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 -1378752585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1378752885; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378753185; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378753485; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378753785; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144003.73333333334; 0.0; 13.0; 0.0; 0.4666666666666667 -1378754085; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378754385; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378754685; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378754985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378755285; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 -1378755585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378755885; 1; 2599.998989; 39.86665116466667; 1.5333333333333334; 2097152.0; 293599.2; 161.73333333333332; 14.8; 0.0; 0.2 -1378756185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 378883.4666666667; 0.0; 1.4; 0.0; 0.0 -1378756485; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 155188.53333333333; 31.8; 3.533333333333333; 0.0; 0.0 -1378756785; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152390.93333333332; 0.0; 1.2; 0.0; 0.0 -1378757085; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378757385; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 156584.8; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 -1378757685; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 139809.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1378757985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378758285; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378758585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 1.2666666666666666; 0.0 -1378758885; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.13333333333; 0.13333333333333333; 7.066666666666666; 0.2; 0.13333333333333333 -1378759185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.4; 0.0; 1.9333333333333333; 0.0; 0.0 -1378759485; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 -1378759785; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 -1378760085; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378760385; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378760685; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378760985; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 139808.0; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 -1378761285; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378761585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1378761885; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 -1378762185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378762485; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378762785; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378763086; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1378763386; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378763686; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378763986; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 -1378764286; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 -1378764586; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.6; 0.0; 0.5333333333333333 -1378764886; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 -1378765186; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 -1378765486; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 -1378765786; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378766086; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 125827.46666666666; 0.06666666666666667; 1.6666666666666667; 0.06666666666666667; 0.13333333333333333 -1378766385; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116040.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378766685; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378766985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378767285; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378767585; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378767885; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378768185; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 163576.8; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 -1378768486; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378768786; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378769086; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378769386; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378769686; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 -1378769986; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 -1378770286; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 131419.73333333334; 0.0; 1.2; 0.0; 0.0 -1378770586; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378770886; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 -1378771186; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378771486; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 -1378771786; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 156585.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378772086; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 169168.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378772386; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378772686; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378772986; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378773286; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 113244.8; 0.5333333333333333; 1.3333333333333333; 0.0; 0.0 -1378773586; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378773886; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378774186; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378774486; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378774786; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 -1378775086; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1378775386; 1; 2599.998989; 25.999989890000002; 1.0; 2097152.0; 118837.33333333333; 0.0; 2.2; 0.0; 0.5333333333333333 -1378775686; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 146800.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378775986; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378776286; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378776586; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 -1378776886; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 141207.46666666667; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 -1378777186; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378777486; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378777787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378778087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378778387; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378778687; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378778987; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.06666666667; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 -1378779287; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378779587; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378779887; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378780187; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378780487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378780787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378781087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378781387; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378781687; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 -1378781987; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 -1378782287; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378782587; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 176158.66666666666; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 -1378782887; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 194334.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 -1378783187; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 153790.4; 0.0; 1.1333333333333333; 0.0; 0.0 -1378783487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378783787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378784087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378784387; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378784687; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.6; 0.0; 0.0 -1378784987; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378785287; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 -1378785587; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378785887; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378786187; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 145400.26666666666; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 -1378786487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 164973.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378786787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378787088; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378787388; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378787688; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 -1378787988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378788288; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 7.2; 0.2; 0.13333333333333333 -1378788588; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.0; 0.0 -1378788888; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1378789188; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378789488; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 -1378789788; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 132817.86666666667; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378790088; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 -1378790388; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 -1378790688; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378790988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378791288; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378791588; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 -1378791888; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 -1378792188; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378792488; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378792788; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 -1378793088; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 -1378793388; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 -1378793688; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 -1378793988; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378794288; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.0; 1.4; 0.0; 0.0 -1378794588; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378794889; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.06666666666666667; 8.4; 0.26666666666666666; 0.2 -1378795189; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.8; 0.0; 0.0 -1378795489; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378795789; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378796089; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 156586.93333333332; 0.0; 1.0; 0.0; 0.0 -1378796389; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 -1378796689; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 -1378796989; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 137012.0; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 -1378797289; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 145400.53333333333; 0.0; 11.866666666666667; 0.0; 0.0 -1378797589; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378797889; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 -1378798189; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1378798489; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378798789; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378799089; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1378799388; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378799688; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378799988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378800289; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.2; 0.0; 0.8; 0.0; 0.0 -1378800589; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 -1378800889; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 150993.6; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 -1378801189; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378801489; 1; 2599.998989; 72.799971692; 2.8; 2097152.0; 661300.2666666667; 161.2; 22.2; 0.06666666666666667; 0.4 -1378801789; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 500518.13333333336; 0.0; 18.933333333333334; 0.0; 0.0 -1378802089; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 237674.66666666666; 31.8; 3.6; 0.0; 0.0 -1378802389; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 148197.6; 5.066666666666666; 2.4; 0.0; 0.0 -1378802689; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.8; 0.0; 0.0 -1378802989; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378803289; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 -1378803589; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 -1378803889; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 67106.4; 0.0; 1.8666666666666667; 0.0; 0.0 -1378804189; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 148196.8; 3.8666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378804489; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 174761.06666666668; 0.0; 0.7333333333333333; 0.0; 0.0 -1378804789; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378805089; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378805389; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 69902.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378805689; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1378805989; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378806289; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378806589; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 -1378806889; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378807189; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 149596.26666666666; 0.0; 1.0; 0.0; 0.0 -1378807489; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 164974.13333333333; 12.933333333333334; 13.266666666666667; 0.3333333333333333; 0.2 -1378807789; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 155186.93333333332; 0.0; 2.4; 0.13333333333333333; 0.4666666666666667 -1378808089; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 146799.46666666667; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 -1378808389; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378808689; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 1.0; 1.6; 0.06666666666666667; 0.0 -1378808990; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 164974.66666666666; 0.0; 1.0; 0.0; 0.0 -1378809290; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137012.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1378809590; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378809890; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 -1378810190; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 -1378810490; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378810790; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378811090; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378811390; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127226.13333333333; 0.0; 2.4; 0.0; 0.5333333333333333 -1378811690; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 141206.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378811990; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378812290; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378812590; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 -1378812890; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 144003.46666666667; 0.0; 1.0; 0.0; 0.0 -1378813190; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 135614.13333333333; 0.0; 2.3333333333333335; 0.2; 0.13333333333333333 -1378813490; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 164974.4; 0.0; 6.2; 0.0; 0.0 -1378813790; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 -1378814090; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378814390; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378814690; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 1.4; 1.2666666666666666; 0.0; 0.0 -1378814990; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 160779.46666666667; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 -1378815290; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 153789.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1378815590; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378815890; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378816190; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378816490; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378816790; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378817090; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378817390; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 -1378817690; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 -1378817990; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378818290; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378818590; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125828.0; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 -1378818890; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 -1378819190; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.2; 6.333333333333333; 0.0 -1378819490; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 7.066666666666666; 0.4; 0.13333333333333333 -1378819791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 176159.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378820091; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378820391; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378820691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 104856.0; 0.0; 1.2; 0.13333333333333333; 0.0 -1378820991; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378821291; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378821591; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378821891; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378822191; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 128624.26666666666; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 -1378822491; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378822791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155188.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378823091; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.06666666666666667; 0.0 -1378823391; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378823691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.0; 1.2; 0.06666666666666667; 0.13333333333333333 -1378823991; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378824291; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.3333333333333333; 0.0 -1378824591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378824891; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378825191; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 155188.0; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 -1378825491; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378825791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 171964.53333333333; 0.0; 2.0; 0.13333333333333333; 0.4666666666666667 -1378826091; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.06666666666666667; 1.4; 0.0; 0.0 -1378826391; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378826691; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 -1378826991; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378827291; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378827591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 -1378827891; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378828191; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 145400.8; 0.0; 1.0; 0.0; 0.0 -1378828491; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378828791; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.2; 0.0 -1378829091; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378829391; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 117439.2; 0.13333333333333333; 2.4; 0.06666666666666667; 0.4666666666666667 -1378829691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378829991; 1; 2599.998989; 0.0; 0.0; 2097152.0; 176159.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378830291; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 -1378830591; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378830892; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378831192; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 -1378831492; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378831791; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 -1378832091; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 -1378832391; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132817.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378832691; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.06666666666666667; 0.0 -1378832991; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 -1378833291; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378833591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378833891; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378834191; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 -1378834492; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 -1378834792; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 -1378835092; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378835392; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378835692; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 -1378835992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 159383.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378836292; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 1.6; 0.0; 0.0 -1378836592; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 180352.8; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 -1378836892; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 159383.2; 0.0; 0.9333333333333333; 0.0; 0.0 -1378837192; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 138410.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 -1378837492; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 104856.0; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 -1378837792; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 -1378838092; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 -1378838392; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378838692; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378838992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378839292; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.4666666666666667; 0.0 -1378839592; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378839892; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.06666666666666667; 0.0 -1378840192; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 170566.93333333332; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 -1378840492; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 -1378840792; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 -1378841092; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 11.8; 0.0; 0.0 -1378841392; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 -1378841692; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378841992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 -1378842293; 1; 2599.998989; 41.599983824; 1.6; 2097152.0; 251656.8; 161.93333333333334; 14.8; 1.4; 0.2 -1378842593; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 418030.4; 0.0; 1.6; 0.0; 0.0 -1378842893; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 198528.53333333333; 31.8; 3.7333333333333334; 0.0; 0.0 -1378843193; 1; 2599.998989; 0.0; 0.0; 2097152.0; 199927.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378843493; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 157984.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378843793; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 194334.13333333333; 0.0; 2.4; 0.0; 0.4666666666666667 -1378844093; 1; 2599.998989; 0.0; 0.0; 2097152.0; 171965.33333333334; 0.0; 1.0; 0.0; 0.0 -1378844393; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127225.6; 0.0; 7.2; 0.4666666666666667; 0.13333333333333333 -1378844693; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.33333333333; 0.0; 1.0; 0.0; 0.0 -1378844993; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142605.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 -1378845293; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378845593; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.06666666666666667; 0.0 -1378845893; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.2; 0.0 -1378846193; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378846493; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378846793; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378847093; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 -1378847393; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 130021.6; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 -1378847693; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378847993; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378848293; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.8666666666666667; 0.0; 0.0 -1378848593; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378848893; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378849193; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378849493; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378849793; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378850093; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378850393; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378850693; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 1.5333333333333334; 0.2; 0.13333333333333333 -1378850993; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 146799.2; 0.0; 8.0; 0.06666666666666667; 0.4666666666666667 -1378851293; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 -1378851593; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378851893; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 -1378852193; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378852493; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.06666666666666667; 1.8; 0.06666666666666667; 0.13333333333333333 -1378852794; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378853094; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 248860.8; 169.66666666666666; 179.86666666666667; 0.0; 0.0 -1378853394; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 167770.93333333332; 0.0; 1.0; 0.0; 0.0 -1378853694; 1; 2599.998989; 69.33330637333334; 2.666666666666667; 2097152.0; 640328.5333333333; 161.06666666666666; 22.0; 0.0; 0.4 -1378853994; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 408243.73333333334; 0.0; 2.7333333333333334; 0.0; 0.0 -1378854294; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 233480.26666666666; 31.8; 3.6; 0.0; 0.0 -1378854594; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 152391.73333333334; 13.333333333333334; 3.7333333333333334; 0.0; 0.4666666666666667 -1378854894; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 145401.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 -1378855194; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 123031.2; 0.0; 1.0666666666666667; 0.0; 0.0 -1378855494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 103457.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378855794; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 -1378856094; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 131419.73333333334; 0.06666666666666667; 1.4; 0.0; 0.0 -1378856394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.2; 0.0; 0.0 -1378856694; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 144003.73333333334; 0.0; 7.666666666666667; 0.2; 0.13333333333333333 -1378856994; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 159382.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378857294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378857594; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378857894; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378858194; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 157984.0; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 -1378858494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.06666666666666667; 0.0 -1378858794; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378859094; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378859394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 -1378859694; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.5333333333333333; 1.3333333333333333; 0.0; 0.0 -1378859994; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 -1378860294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378860594; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378860894; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378861194; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378861494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 141206.93333333332; 0.0; 1.0; 0.0; 0.0 -1378861794; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 183149.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 -1378862094; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 152392.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378862394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378862694; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 -1378862994; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 124429.86666666667; 0.0; 7.066666666666666; 0.26666666666666666; 0.06666666666666667 -1378863294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378863595; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378863895; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 -1378864195; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 -1378864494; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1378864794; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 128623.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378865094; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 -1378865394; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 114642.93333333333; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 -1378865694; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 -1378865994; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 -1378866294; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378866594; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 -1378866894; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.0; 0.0 -1378867194; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378867494; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378867794; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 -1378868094; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378868394; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 1.2666666666666666; 0.0 -1378868694; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 137012.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378868994; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 178955.2; 12.8; 14.2; 0.3333333333333333; 0.7333333333333333 -1378869294; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 201325.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 -1378869594; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 171964.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378869894; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.0; 0.0; 0.8; 0.0; 0.0 -1378870194; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378870494; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 -1378870794; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378871094; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378871394; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 -1378871695; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378871995; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378872295; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378872595; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 157983.2; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 -1378872895; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 -1378873195; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378873495; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 -1378873795; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 -1378874095; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 -1378874395; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378874695; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378874995; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.06666666666666667; 0.0 -1378875295; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.6; 0.0; 0.8; 0.0; 0.0 -1378875595; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 7.2; 0.26666666666666666; 0.2 -1378875895; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378876195; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 -1378876495; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 157984.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378876795; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378877095; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378877395; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378877695; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378877995; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 -1378878295; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378878595; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378878895; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378879195; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378879495; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378879795; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 157983.73333333334; 0.06666666666666667; 2.066666666666667; 0.0; 0.4666666666666667 -1378880095; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 -1378880396; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378880696; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 -1378880996; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 148197.6; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 -1378881296; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.4; 0.0; 0.06666666666666667 -1378881596; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 2.1333333333333333; 0.0; 0.0 -1378881896; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378882196; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 -1378882496; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378882796; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378883096; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 1.4666666666666666; 1.4; 0.0; 0.0 -1378883396; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 195732.26666666666; 0.0; 2.2666666666666666; 0.0; 0.5333333333333333 -1378883696; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 199926.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 -1378883996; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 -1378884296; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 -1378884596; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 11.8; 1.7333333333333334; 0.0 -1378884896; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378885196; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 -1378885496; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.8; 0.0; 0.0 -1378885796; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378886096; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 -1378886396; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 -1378886696; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378886996; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 157983.2; 0.13333333333333333; 9.266666666666667; 0.26666666666666666; 0.6 -1378887296; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 178955.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 -1378887596; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.9333333333333333; 0.0 -1378887896; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378888196; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378888496; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 -1378888796; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 -1378889096; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.0; 0.0; 0.8666666666666667; 0.0; 0.0 -1378889396; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109049.86666666667; 0.0; 1.0; 0.0; 0.0 -1378889696; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 -1378889997; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 -1378890297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 -1378890597; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 156585.33333333334; 0.2; 2.4; 0.0; 0.4666666666666667 -1378890897; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378891197; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 -1378891497; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 2.0; 0.0 -1378891797; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378892097; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 -1378892397; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378892697; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 8.066666666666666; 0.2; 0.13333333333333333 -1378892997; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 -1378893297; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 146799.2; 20.4; 2.1333333333333333; 0.0; 0.06666666666666667 -1378893597; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 149596.26666666666; 0.0; 4.066666666666666; 0.0; 0.0 -1378893897; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 183149.86666666667; 0.0; 2.8; 0.0; 0.0 -1378894197; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148197.06666666668; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 -1378894497; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 -1378894797; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 -1378895097; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378895397; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 -1378895697; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378895997; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 -1378896297; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 -1378896597; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 -1378896897; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 -1378897197; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378897497; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 -1378897797; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 166372.26666666666; 0.0; 2.4; 0.0; 0.5333333333333333 -1378898097; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 173362.93333333332; 0.0; 1.2; 0.0; 0.0 -1378898397; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 -1378898697; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 7.2; 0.2; 0.13333333333333333 -1378898997; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 -1378899297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 -1378899597; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 -1378899897; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 160780.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 -1378900197; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 1.0666666666666667; 1.4; 0.0 -1378900497; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 -1378900797; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378901097; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 -1378901397; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130022.4; 0.06666666666666667; 2.533333333333333; 0.0; 0.5333333333333333 -1378901697; 1; 2599.998989; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 1.0; 0.0; 0.0 -1378901997; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 -1378902297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 -1378902598; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 -1378902898; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 -1378903198; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 -1378903498; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 -1378903798; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 -1378904098; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.06666666666666667; 0.0 -1378904398; 1; 2599.998989; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 -1378904698; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 -1378904998; 1; 2599.998989; 77.99996967000001; 3.0; 2097152.0; 450186.6666666667; 161.06666666666666; 107.6; 12.933333333333334; 1.2666666666666666 -1378905298; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 633338.4; 0.0; 45.13333333333333; 0.2; 0.13333333333333333 -1378905598; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 297792.8; 31.8; 3.466666666666667; 0.0; 0.0 -1378905898; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 162177.86666666667; 5.066666666666666; 2.2; 0.0; 0.0 -1378906198; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.8; 0.0; 1.6; 0.0; 0.0 -1378906498; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.3333333333333333; 0.0; 0.0 -1378906798; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 diff --git a/opendc-trace/opendc-trace-bitbrains/build.gradle.kts b/opendc-trace/opendc-trace-bitbrains/build.gradle.kts new file mode 100644 index 00000000..d195cbbb --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for GWF traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) + implementation(libs.jackson.dataformat.csv) +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt new file mode 100644 index 00000000..767ef919 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] in the Bitbrains format. + */ +internal class BitbrainsResourceStateTable(private val factory: CsvFactory, private val path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = + Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_STATE_CPU_USAGE -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_STATE_MEM_USAGE -> true + RESOURCE_STATE_DISK_READ -> true + RESOURCE_STATE_DISK_WRITE -> true + RESOURCE_STATE_NET_RX -> true + RESOURCE_STATE_NET_TX -> true + else -> false + } + } + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (partition, path) = it.next() + return BitbrainsResourceStateTableReader(partition, factory.createParser(path.toFile())) + } else { + null + } + } + + override fun toString(): String = "BitbrainsCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + return BitbrainsResourceStateTableReader(partition, factory.createParser(path.toFile())) + } + + override fun toString(): String = "BitbrainsResourceStateTable" +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt new file mode 100644 index 00000000..5687ac7f --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Bitbrains resource state table. + */ +internal class BitbrainsResourceStateTableReader(private val partition: String, private val parser: CsvParser) : TableReader { + /** + * The current parser state. + */ + private val state = RowState() + + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + // Reset the row state + state.reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "Timestamp [ms]" -> state.timestamp = Instant.ofEpochSecond(parser.longValue) + "CPU cores" -> state.cpuCores = parser.intValue + "CPU capacity provisioned [MHZ]" -> state.cpuCapacity = parser.doubleValue + "CPU usage [MHZ]" -> state.cpuUsage = parser.doubleValue + "CPU usage [%]" -> state.cpuUsagePct = parser.doubleValue + "Memory capacity provisioned [KB]" -> state.memCapacity = parser.doubleValue + "Memory usage [KB]" -> state.memUsage = parser.doubleValue + "Disk read throughput [KB/s]" -> state.diskRead = parser.doubleValue + "Disk write throughput [KB/s]" -> state.diskWrite = parser.doubleValue + "Network received throughput [KB/s]" -> state.netReceived = parser.doubleValue + "Network transmitted throughput [KB/s]" -> state.netTransmitted = parser.doubleValue + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_STATE_CPU_USAGE -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_STATE_MEM_USAGE -> true + RESOURCE_STATE_DISK_READ -> true + RESOURCE_STATE_DISK_WRITE -> true + RESOURCE_STATE_NET_RX -> true + RESOURCE_STATE_NET_TX -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> partition + RESOURCE_STATE_TIMESTAMP -> state.timestamp + RESOURCE_STATE_NCPUS -> state.cpuCores + RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity + RESOURCE_STATE_CPU_USAGE -> state.cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsagePct + RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity + RESOURCE_STATE_MEM_USAGE -> state.memUsage + RESOURCE_STATE_DISK_READ -> state.diskRead + RESOURCE_STATE_DISK_WRITE -> state.diskWrite + RESOURCE_STATE_NET_RX -> state.netReceived + RESOURCE_STATE_NET_TX -> state.netTransmitted + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_STATE_NCPUS -> state.cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity + RESOURCE_STATE_CPU_USAGE -> state.cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsagePct + RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity + RESOURCE_STATE_MEM_USAGE -> state.memUsage + RESOURCE_STATE_DISK_READ -> state.diskRead + RESOURCE_STATE_DISK_WRITE -> state.diskWrite + RESOURCE_STATE_NET_RX -> state.netReceived + RESOURCE_STATE_NET_TX -> state.netTransmitted + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * The current row state. + */ + private class RowState { + var timestamp: Instant? = null + var cpuCores = -1 + var cpuCapacity = Double.NaN + var cpuUsage = Double.NaN + var cpuUsagePct = Double.NaN + var memCapacity = Double.NaN + var memUsage = Double.NaN + var diskRead = Double.NaN + var diskWrite = Double.NaN + var netReceived = Double.NaN + var netTransmitted = Double.NaN + + /** + * Reset the state. + */ + fun reset() { + timestamp = null + cpuCores = -1 + cpuCapacity = Double.NaN + cpuUsage = Double.NaN + cpuUsagePct = Double.NaN + memCapacity = Double.NaN + memUsage = Double.NaN + diskRead = Double.NaN + diskWrite = Double.NaN + netReceived = Double.NaN + netTransmitted = Double.NaN + } + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("Timestamp [ms]", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU cores", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU capacity provisioned [MHZ]", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU usage [MHZ]", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU usage [%]", CsvSchema.ColumnType.NUMBER) + .addColumn("Memory capacity provisioned [KB]", CsvSchema.ColumnType.NUMBER) + .addColumn("Memory usage [KB]", CsvSchema.ColumnType.NUMBER) + .addColumn("Disk read throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Disk write throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Network received throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Network transmitted throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .setUseHeader(true) + .setColumnSeparator(';') + .build() + } +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt new file mode 100644 index 00000000..5a2d4243 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the Bitbrains format. + */ +public class BitbrainsTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + + return BitbrainsResourceStateTable(factory, path) + } + + override fun toString(): String = "BitbrainsTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt new file mode 100644 index 00000000..55b11fe3 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the GWF trace format. + */ +public class BitbrainsTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "bitbrains" + + /** + * The [CsvFactory] used to create the parser. + */ + private val factory = CsvFactory() + .enable(CsvParser.Feature.ALLOW_COMMENTS) + .enable(CsvParser.Feature.TRIM_SPACES) + + /** + * Open a Bitbrains trace. + */ + override fun open(url: URL): BitbrainsTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return BitbrainsTrace(factory, path) + } +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..f18135d0 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.bitbrains.BitbrainsTraceFormat diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt new file mode 100644 index 00000000..550805d3 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.RESOURCE_STATE_CPU_USAGE +import org.opendc.trace.RESOURCE_STATE_TIMESTAMP +import org.opendc.trace.TABLE_RESOURCE_STATES +import java.net.URL + +/** + * Test suite for the [BitbrainsTraceFormat] class. + */ +class BitbrainsTraceFormatTest { + @Test + fun testTraceExists() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + assertDoesNotThrow { + format.open(url) + } + } + + @Test + fun testTraceDoesNotExists() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + assertThrows { + format.open(URL(url.toString() + "help")) + } + } + + @Test + fun testTables() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + val trace = format.open(url) + + assertEquals(listOf(TABLE_RESOURCE_STATES), trace.tables) + } + + @Test + fun testTableExists() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + val trace = format.open(url) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + @Test + fun testSmoke() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals(1376314846, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) }, + { assertEquals(19.066, reader.getDouble(RESOURCE_STATE_CPU_USAGE), 0.01) } + ) + + reader.close() + } +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/resources/bitbrains.csv b/opendc-trace/opendc-trace-bitbrains/src/test/resources/bitbrains.csv new file mode 100644 index 00000000..f5e300e8 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/test/resources/bitbrains.csv @@ -0,0 +1,8620 @@ +Timestamp [ms]; CPU cores; CPU capacity provisioned [MHZ]; CPU usage [MHZ]; CPU usage [%]; Memory capacity provisioned [KB]; Memory usage [KB]; Disk read throughput [KB/s]; Disk write throughput [KB/s]; Network received throughput [KB/s]; Network transmitted throughput [KB/s] +1376314846; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1376315146; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376315446; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376315746; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376316046; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376316346; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1376316646; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 128624.26666666666; 0.06666666666666667; 8.733333333333333; 0.3333333333333333; 0.6 +1376316946; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 134216.8; 0.0; 1.2; 0.0; 0.0 +1376317246; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376317546; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1376317846; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376318146; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.06666666666666667; 1.6; 0.06666666666666667; 0.13333333333333333 +1376318446; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376318746; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376319046; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1376319346; 1; 2599.999626; 38.99999439; 1.5; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376319646; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1376319946; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1376320246; 1; 2599.999626; 41.599994016000004; 1.6; 2097152.0; 150993.6; 0.0; 2.7333333333333334; 67.46666666666667; 0.5333333333333333 +1376320546; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376320846; 1; 2599.999626; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376321146; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1376321446; 1; 2599.999626; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376321746; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376322046; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376322346; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.6; 0.0 +1376322647; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376322947; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376323247; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 117439.2; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376323547; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1376323847; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 146800.0; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 +1376324147; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.2; 1.5333333333333334; 0.0; 0.0 +1376324447; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.5333333333333334; 0.0; 0.0 +1376324747; 1; 2599.999626; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376325047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376325347; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1376325647; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.2; 0.0; 0.0 +1376325947; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376326247; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376326547; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376326847; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376327147; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376327447; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 198527.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376327747; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376328047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376328347; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376328647; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 +1376328947; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376329247; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1376329547; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1376329847; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376330147; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 125828.0; 0.2; 7.466666666666667; 0.2; 0.13333333333333333 +1376330447; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376330747; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 155188.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376331047; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 167771.2; 0.0; 2.466666666666667; 0.3333333333333333; 0.4666666666666667 +1376331347; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 132817.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1376331647; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376331947; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376332247; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376332547; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376332847; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.6; 0.0; 0.0 +1376333147; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376333447; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376333747; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376334047; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376334347; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376334647; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 170565.86666666667; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1376334947; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 128624.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376335247; 1; 2599.999626; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1376335547; 1; 2599.999626; 46.799993268; 1.8; 2097152.0; 341134.4; 161.73333333333332; 14.666666666666666; 0.0; 0.2 +1376335847; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 216702.93333333332; 0.0; 7.733333333333333; 0.26666666666666666; 0.13333333333333333 +1376336147; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 160780.53333333333; 31.8; 3.8666666666666667; 0.0; 0.0 +1376336447; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 1.3333333333333333; 0.26666666666666666; 0.0 +1376336747; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376337047; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1376337347; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1376337647; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376337947; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.0; 0.0 +1376338248; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 205518.66666666666; 0.0; 3.066666666666667; 0.0; 0.4666666666666667 +1376338548; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 138410.93333333332; 0.06666666666666667; 1.5333333333333334; 0.0; 0.0 +1376338848; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376339148; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376339448; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376339748; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376340048; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.2; 0.0; 0.0 +1376340348; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.6666666666666666; 0.0 +1376340648; 1; 2599.999626; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376340948; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376341248; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376341548; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1376341848; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 127225.33333333333; 0.2; 2.6666666666666665; 0.0; 0.4666666666666667 +1376342148; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1376342448; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 +1376342748; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 +1376343048; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376343348; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.13333333333333333; 0.0 +1376343648; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.3333333333333333; 0.0 +1376343948; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 149594.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1376344248; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 1.1333333333333333; 0.6; 0.0 +1376344548; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376344848; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376345148; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1376345448; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 162177.86666666667; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376345748; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376346048; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1376346348; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376346648; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 74097.06666666667; 2.6666666666666665; 1.4666666666666666; 0.13333333333333333; 0.0 +1376346948; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1376347248; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 +1376347548; 1; 2599.999626; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376347848; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376348148; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 7.466666666666667; 0.26666666666666666; 0.2 +1376348448; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376348749; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376349049; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376349349; 1; 2599.999626; 41.599994016000004; 1.6; 2097152.0; 187343.73333333334; 161.0; 21.6; 0.06666666666666667; 0.4 +1376349649; 1; 2599.999626; 22.533330092; 0.8666666666666667; 2097152.0; 577414.1333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1376349949; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 234878.4; 31.8; 3.6666666666666665; 0.0; 0.0 +1376350249; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 178954.4; 0.8; 2.466666666666667; 0.0; 0.06666666666666667 +1376350549; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1376350849; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376351149; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.06666666666666667; 0.0 +1376351449; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376351749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376352049; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 82485.86666666667; 1.4666666666666666; 1.6666666666666667; 0.0; 0.0 +1376352349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376352649; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 178954.13333333333; 3.8666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1376352949; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 141206.4; 0.0; 1.0; 0.0; 0.0 +1376353249; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376353549; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376353849; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.6; 12.4; 0.0; 0.0 +1376354149; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 192936.0; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.13333333333333333 +1376354449; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 130022.4; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1376354749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.4; 0.0; 0.0 +1376355049; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376355349; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 +1376355649; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1376355949; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376356249; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 138410.66666666666; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376356549; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 121633.33333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1376356849; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1376357149; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376357449; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376357749; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376358049; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376358349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376358649; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1376358949; 1; 2599.999626; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376359250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376359550; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 138411.2; 0.0; 7.4; 0.2; 0.13333333333333333 +1376359850; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 160780.53333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1376360150; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376360450; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376360750; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376361050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1376361350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376361650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.4; 0.06666666666666667; 0.0 +1376361950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.4666666666666666; 0.0; 0.0 +1376362250; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376362550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376362849; 1; 2599.999626; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 +1376363149; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1376363449; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 169168.53333333333; 0.06666666666666667; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 +1376363749; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 +1376364049; 1; 2599.999626; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376364349; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 +1376364650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 135614.66666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376364950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376365250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1376365550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1376365850; 1; 2599.999626; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376366150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.4666666666666666; 0.0; 0.0 +1376366450; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.06666666666666667; 7.466666666666667; 0.2; 0.13333333333333333 +1376366750; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376367050; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 2.6; 0.4; 0.5333333333333333 +1376367350; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 139809.33333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376367650; 1; 2599.999626; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376367950; 1; 2599.999626; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 +1376368250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376368550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376368850; 1; 2599.999626; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 1.6; 0.0; 0.0 +1376369150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376369450; 1; 2599.999626; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.26666666666666666; 0.0 +1376369750; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376370050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 58717.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376370350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376370650; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 142604.0; 0.06666666666666667; 3.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376370950; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.6666666666666666; 0.0 +1376371250; 1; 2599.999626; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.2; 0.0 +1376371550; 1; 2599.999626; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376371850; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 167770.13333333333; 0.0; 7.066666666666666; 0.3333333333333333; 0.13333333333333333 +1376372150; 1; 2599.999626; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 1.2; 0.0; 0.0 +1376372450; 1; 2599.999626; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376372750; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.4; 0.0; 0.0 +1376373050; 1; 2599.999626; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1376373350; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376373651; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1376373951; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376374251; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 163575.46666666667; 0.06666666666666667; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376374551; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 128623.73333333334; 0.0; 1.2; 0.0; 0.0 +1376374851; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376375151; 1; 2599.999626; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376375451; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376375751; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 3.0; 0.13333333333333333; 0.13333333333333333 +1376376051; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 2.066666666666667; 0.06666666666666667; 0.0 +1376376351; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376376651; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 127225.33333333333; 0.0; 1.2; 0.0; 0.0 +1376376951; 1; 2599.999626; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 +1376377251; 1; 2599.999626; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376377551; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376377851; 1; 2599.999626; 12.133331587999999; 0.4666666666666666; 2097152.0; 180353.6; 0.6; 2.6666666666666665; 0.13333333333333333; 0.4666666666666667 +1376378151; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376378451; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 116041.06666666667; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 +1376378751; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376379051; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376379351; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376379651; 1; 2599.999626; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376379951; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 2.0; 0.0; 0.0 +1376380251; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376380551; 1; 2599.999626; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376380851; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376381151; 1; 2599.999626; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376381451; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 144003.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376381751; 1; 2599.999626; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1376382051; 1; 2599.999626; 0.0; 0.0; 2097152.0; 138409.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376382351; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1376382651; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 81087.73333333334; 0.0; 1.4; 0.0; 0.0 +1376382951; 1; 2599.999626; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376383251; 1; 2599.999626; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.0; 0.0 +1376383551; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376383851; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.4; 0.0; 0.0 +1376384151; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376384451; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1376384752; 1; 2599.999626; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376385052; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1376385352; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376385652; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 95069.06666666667; 0.0; 7.0; 1.0666666666666667; 0.2 +1376385952; 1; 2599.999626; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376386252; 1; 2599.999626; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376386552; 1; 2599.999626; 0.0; 0.0; 2097152.0; 127225.86666666667; 0.0; 1.2; 0.0; 0.0 +1376386852; 1; 2599.999626; 0.0; 0.0; 2097152.0; 132818.4; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376387152; 1; 2599.999626; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376387452; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.2; 0.0 +1376387752; 1; 2599.999626; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1376388052; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376388352; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376388652; 1; 2599.999626; 10.399998504000001; 0.4; 2097152.0; 169168.26666666666; 0.0; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 +1376388952; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.2; 0.0; 0.0 +1376389252; 1; 2599.999626; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376389552; 1; 2599.999626; 3.4666661679999997; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.4; 0.0; 0.0 +1376389852; 1; 2599.999626; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376390152; 1; 2599.999626; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376390452; 1; 2599.999626; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376390752; 1; 2599.999626; 5.1999992520000005; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376391052; 1; 2599.999626; 1.7333330839999999; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376391352; 1; 2599.999626; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376391652; 1; 2599.999626; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376391952; 1; 2599.999626; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1376392252; 1; 2599.999626; 6.933332335999999; 0.26666666666666666; 2097152.0; 191537.33333333334; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376392552; 1; 2599.999626; 8.666665420000001; 0.33333333333333337; 2097152.0; 163576.0; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1376392853; 1; 2599.999626; 0.0; 0.0; 2097152.0; 138409.6; 0.0; 1.2; 0.13333333333333333; 0.0 +1376393153; 1; 2599.999602; 38.999994029999996; 1.5; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376393453; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 109049.6; 0.0; 1.5333333333333334; 0.0; 0.0 +1376393753; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376394053; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376394353; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 111846.66666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1376394653; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376394953; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 60115.73333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376395253; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1376395552; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376395852; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1376396152; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 103457.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376396452; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376396752; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376397052; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376397352; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376397652; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 97865.33333333333; 0.0; 12.533333333333333; 0.0; 0.0 +1376397952; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376398252; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376398552; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376398853; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 7.2; 7.2; 0.13333333333333333 +1376399153; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 1.4; 0.0; 0.0 +1376399453; 1; 2599.999602; 22.533329884; 0.8666666666666667; 2097152.0; 178955.46666666667; 0.0; 2.6666666666666665; 0.06666666666666667; 0.5333333333333333 +1376399753; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376400053; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376400353; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 74097.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376400653; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 92272.8; 0.0; 1.6666666666666667; 0.0; 0.0 +1376400953; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 2.0; 0.0; 0.0 +1376401253; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 69902.66666666667; 0.0; 1.2; 0.0; 0.0 +1376401553; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376401853; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 130022.4; 0.0; 1.4; 0.0; 0.0 +1376402153; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1376402453; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376402753; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376403053; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 113244.8; 0.0; 3.1333333333333333; 0.0; 0.4666666666666667 +1376403353; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376403653; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376403953; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376404253; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 74097.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1376404553; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.13333333333333333 +1376404853; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376405153; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 65708.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376405453; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1376405753; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 106254.13333333333; 0.0; 7.4; 0.2; 0.13333333333333333 +1376406053; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376406353; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1376406653; 1; 2599.999602; 74.53332192399999; 2.8666666666666667; 2097152.0; 630542.1333333333; 161.13333333333333; 23.266666666666666; 0.06666666666666667; 0.8666666666666667 +1376406954; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 369096.8; 0.3333333333333333; 20.2; 0.0; 0.0 +1376407254; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 237674.93333333332; 31.8; 3.933333333333333; 0.0; 0.0 +1376407554; 1; 2599.999602; 19.066663748; 0.7333333333333333; 2097152.0; 141207.46666666667; 4.266666666666667; 2.533333333333333; 0.06666666666666667; 0.0 +1376407854; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.7333333333333334; 0.0; 0.0 +1376408154; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376408454; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376408754; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.5333333333333334; 0.2; 0.0 +1376409054; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376409354; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376409654; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 +1376409954; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376410254; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 149595.46666666667; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376410554; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1376410854; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376411154; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376411454; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1376411754; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 100661.6; 12.733333333333333; 13.466666666666667; 0.3333333333333333; 0.2 +1376412054; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.6666666666666667; 0.0; 0.0 +1376412354; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376412654; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1376412954; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1376413255; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376413555; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376413855; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 138409.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 +1376414155; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 96467.2; 0.0; 1.4666666666666666; 0.0; 0.0 +1376414455; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376414755; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376415055; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376415355; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376415655; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376415955; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376416255; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376416555; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376416855; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 82485.86666666667; 1.0666666666666667; 1.9333333333333333; 0.0; 0.0 +1376417155; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.4666666666666666; 0.0; 0.0 +1376417455; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 195732.26666666666; 0.0; 2.4; 0.0; 0.5333333333333333 +1376417755; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376418055; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376418355; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1376418655; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376418955; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376419255; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376419555; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 1.2; 0.0; 0.0 +1376419855; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 64310.13333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376420155; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 +1376420455; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.6; 0.0; 0.06666666666666667 +1376420755; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376421055; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 202721.86666666667; 0.0; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 +1376421355; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 100661.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1376421655; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376421955; 1; 2599.999602; 45.066659768; 1.7333333333333334; 2097152.0; 360707.73333333334; 161.73333333333332; 14.466666666666667; 0.0; 0.2 +1376422255; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 282414.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1376422555; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 194334.13333333333; 31.8; 3.8666666666666667; 0.0; 0.0 +1376422856; 1; 2599.999602; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376423156; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1376423456; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376423756; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1376424056; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1376424356; 1; 2599.999602; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1376424656; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 153790.13333333333; 0.06666666666666667; 8.933333333333334; 0.26666666666666666; 0.6 +1376424956; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 +1376425256; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 82485.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376425556; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 +1376425856; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1376426156; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1376426456; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 83884.0; 0.0; 1.4; 0.0; 0.0 +1376426756; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376427056; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.0; 0.06666666666666667; 0.0 +1376427356; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376427656; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.06666666666666667; 0.0 +1376427956; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376428256; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 199926.4; 0.06666666666666667; 3.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376428556; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 163576.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376428856; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376429156; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376429456; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1376429756; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 1.2; 0.0; 0.0 +1376430056; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376430356; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376430656; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376430956; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1376431256; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 121633.6; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376431556; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.2; 0.0; 0.0 +1376431856; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1376432156; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.4; 0.0; 0.0 +1376432456; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 +1376432756; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376433056; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 131419.73333333334; 0.06666666666666667; 2.7333333333333334; 0.0; 0.0 +1376433356; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 137013.06666666668; 0.0; 1.6666666666666667; 0.4666666666666667; 0.13333333333333333 +1376433656; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 +1376433956; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376434256; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376434556; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376434856; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376435156; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 103457.86666666667; 0.0; 1.6; 0.0; 0.0 +1376435456; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 178955.46666666667; 0.13333333333333333; 3.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376435756; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376436056; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 1.2; 0.0; 0.0 +1376436356; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.4; 0.0; 0.0 +1376436656; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376436956; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376437256; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 +1376437556; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.06666666666666667; 7.8; 0.3333333333333333; 0.13333333333333333 +1376437856; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376438156; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376438456; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376438756; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1376439056; 1; 2599.999602; 15.599997612; 0.6; 2097152.0; 197130.4; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376439356; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 1.2; 0.0; 0.0 +1376439656; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376439956; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.2; 0.0 +1376440256; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 67106.4; 0.0; 1.8; 0.0; 0.0 +1376440557; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 69902.66666666667; 0.0; 1.4; 0.0; 0.0 +1376440857; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1376441157; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 12.0; 0.06666666666666667; 0.0 +1376441457; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376441757; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1376442057; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 134216.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376442357; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1376442657; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 180353.6; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1376442957; 1; 2599.99945; 31.777771055555554; 1.2222222222222223; 2097152.0; 97865.33333333333; 0.0; 0.625; 0.0; 0.0 +1376443257; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 156585.33333333334; 0.0; 7.2; 0.3333333333333333; 0.13333333333333333 +1376443557; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 146800.0; 0.0; 1.2; 0.0; 0.0 +1376443857; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1376444157; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 114642.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376444457; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 148197.33333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1376444757; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 1.4666666666666666; 0.0; 0.0 +1376445057; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376445357; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376445657; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 96467.2; 0.0; 1.8666666666666667; 10.933333333333334; 0.0 +1376445957; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376446257; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 134216.0; 0.0; 2.933333333333333; 0.06666666666666667; 0.4666666666666667 +1376446557; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376446857; 1; 2599.99945; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376447157; 1; 2599.99945; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376447457; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 141206.66666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1376447757; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 153789.6; 0.0; 1.2; 0.13333333333333333; 0.0 +1376448057; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376448357; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376448657; 1; 2599.99945; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376448957; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 103457.86666666667; 0.0; 1.6; 0.3333333333333333; 0.0 +1376449257; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1376449558; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376449858; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 152390.93333333332; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1376450158; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 137012.8; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1376450458; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1376450758; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376451058; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376451358; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376451658; 1; 2599.99945; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1376451958; 1; 2599.99945; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.4; 0.0; 0.0 +1376452258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376452558; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376452858; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376453158; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1376453458; 1; 2599.99945; 13.866663733333333; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.6; 0.2; 0.4666666666666667 +1376453758; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 104856.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376454058; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376454358; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 +1376454658; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376454958; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1376455258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376455558; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 89476.53333333334; 0.0; 6.933333333333334; 0.3333333333333333; 0.2 +1376455858; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 116041.06666666667; 0.0; 2.1333333333333333; 0.0; 0.0 +1376456158; 1; 2599.99945; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1376456458; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376456758; 1; 2599.99945; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1376457058; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1376457359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376457659; 1; 2599.99945; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376457959; 1; 2599.99945; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376458259; 1; 2599.99945; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376458559; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.5333333333333334; 0.06666666666666667; 0.0 +1376458859; 1; 2599.99945; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376459159; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376459459; 1; 2599.99945; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376459759; 1; 2599.99945; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1376460059; 1; 2599.99945; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.4; 0.0; 0.0 +1376460359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.3333333333333333; 1.6; 0.0 +1376460659; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 150993.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 +1376460959; 1; 2599.99945; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376461258; 1; 2599.99945; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1376461558; 1; 2599.99945; 3.466665933333333; 0.13333333333333333; 2097152.0; 75495.2; 0.06666666666666667; 6.8; 0.26666666666666666; 0.2 +1376461858; 1; 2599.99945; 124.79997359999999; 4.8; 2097152.0; 524285.86666666664; 161.46666666666667; 170.26666666666668; 20.866666666666667; 1.0666666666666667 +1376462158; 1; 2599.99945; 17.333329666666668; 0.6666666666666667; 2097152.0; 541063.2; 5.066666666666666; 12.2; 0.13333333333333333; 0.06666666666666667 +1376462458; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 243267.2; 31.8; 4.6; 0.06666666666666667; 0.0 +1376462758; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 187343.2; 0.0; 2.8666666666666667; 0.0; 0.0 +1376463059; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1376463359; 1; 2599.99945; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1376463659; 1; 2599.99945; 20.7999956; 0.8; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1376463959; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376464259; 1; 2599.999602; 28.599995622; 1.1; 2097152.0; 188740.0; 0.0; 1.4444444444444444; 0.1111111111111111; 0.0 +1376464559; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 125827.46666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1376464859; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1376465159; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376465459; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376465759; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376466059; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376466359; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 125828.0; 0.0; 1.6; 0.0; 0.0 +1376466659; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 +1376466959; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376467259; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 107651.46666666666; 0.0; 1.2; 0.0; 0.0 +1376467559; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376467859; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 152391.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1376468159; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376468459; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 131420.53333333333; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 +1376468759; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376469059; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376469359; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376469659; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.6; 0.0; 0.0 +1376469959; 1; 2599.999602; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376470259; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376470559; 1; 2599.999602; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376470859; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.3333333333333333; 0.9333333333333333; 0.0 +1376471159; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376471459; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 159381.6; 0.06666666666666667; 2.8; 0.13333333333333333; 0.4666666666666667 +1376471759; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1376472059; 1; 2599.999602; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.2; 0.0; 0.0 +1376472359; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 1.4; 0.0; 0.0 +1376472659; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376472959; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 150993.6; 20.6; 2.2666666666666666; 0.0; 0.06666666666666667 +1376473260; 1; 2599.999602; 20.799996815999997; 0.8; 2097152.0; 114642.93333333333; 0.0; 4.2; 0.0; 0.0 +1376473560; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 110448.53333333334; 0.0; 2.933333333333333; 0.0; 0.0 +1376473860; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 142604.53333333333; 12.733333333333333; 13.666666666666666; 0.26666666666666666; 0.13333333333333333 +1376474160; 1; 2599.999602; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1376474460; 1; 2599.999602; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376474760; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376475060; 1; 2599.999602; 12.133331475999999; 0.4666666666666666; 2097152.0; 162177.86666666667; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376475360; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1376475660; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376475960; 1; 2599.999602; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376476260; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1376476560; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376476860; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1376477160; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376477460; 1; 2599.999602; 0.0; 0.0; 2097152.0; 148197.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1376477760; 1; 2599.99945; 31.199993399999997; 1.2; 2097152.0; 134216.8; 0.0; 1.2222222222222223; 0.0; 0.0 +1376478060; 1; 2599.99945; 13.866663733333333; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1376478360; 1; 2599.99945; 15.599996699999998; 0.6; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376478660; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 174760.0; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1376478960; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 121632.8; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376479260; 1; 2599.99945; 17.333329666666668; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.6; 0.06666666666666667; 0.0 +1376479560; 1; 2599.99945; 6.933331866666666; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1376479860; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1376480160; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 124429.06666666667; 0.0; 1.2; 0.0; 0.0 +1376480460; 1; 2599.999343; 37.55554606555556; 1.4444444444444446; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1376480760; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.8; 0.06666666666666667; 0.0 +1376481060; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1376481360; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376481660; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376481960; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.4; 0.0; 0.0 +1376482261; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 142604.0; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1376482561; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376482861; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1376483161; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376483461; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.6; 0.0; 0.0 +1376483761; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.2; 0.0; 0.0 +1376484061; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 1.2; 0.0; 0.0 +1376484361; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376484661; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376484961; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 79689.6; 0.0; 12.266666666666667; 0.0; 0.0 +1376485261; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142605.6; 0.06666666666666667; 7.6; 0.2; 0.13333333333333333 +1376485561; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130021.6; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376485861; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 166371.46666666667; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 +1376486161; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 113244.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376486461; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376486761; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376487061; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1376487361; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1376487661; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130021.6; 0.0; 1.6; 0.0; 0.0 +1376487961; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376488261; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376488561; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376488861; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.8; 1.8; 1.5333333333333334; 0.0; 0.06666666666666667 +1376489161; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376489461; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1376489761; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376490061; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.8; 0.06666666666666667; 0.0 +1376490362; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 +1376490662; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376490962; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 130022.4; 0.0; 7.6; 0.26666666666666666; 0.26666666666666666 +1376491262; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376491562; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376491862; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125827.2; 0.0; 1.3333333333333333; 0.13333333333333333; 0.0 +1376492162; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376492462; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 +1376492762; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376493062; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 162177.86666666667; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376493362; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121632.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1376493662; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376493962; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 2.4; 0.0 +1376494261; 1; 2599.999309; 25.999993089999997; 1.0; 2097152.0; 71300.8; 0.0; 1.1111111111111112; 0.0; 0.0 +1376494561; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1376494861; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376495161; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1376495461; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376495761; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1376496061; 1; 2599.999309; 17.333328726666668; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376496362; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376496662; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 163575.2; 0.2; 2.8666666666666667; 0.13333333333333333; 0.5333333333333333 +1376496962; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 7.466666666666667; 0.3333333333333333; 0.13333333333333333 +1376497262; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 120235.46666666666; 0.0; 1.6; 0.0; 0.0 +1376497562; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 72698.93333333333; 0.0; 1.2; 0.0; 0.0 +1376497862; 1; 2599.999309; 19.06666159933333; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376498162; 1; 2599.999309; 20.799994471999998; 0.8; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376498462; 1; 2599.999297; 29.249992091249997; 1.125; 2097152.0; 76019.5; 0.0; 1.0; 0.0; 0.0 +1376498762; 1; 2599.999297; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1376499062; 1; 2599.999297; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1376499362; 1; 2599.999297; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1376499662; 1; 2599.999297; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376499962; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.4; 0.0; 0.0 +1376500262; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 152391.2; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376500562; 1; 2599.999297; 0.0; 0.0; 2097152.0; 117438.93333333333; 0.0; 1.2; 0.2; 0.0 +1376500862; 1; 2599.999297; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376501162; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 143.66666666666666; 0.0 +1376501462; 1; 2599.999297; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376501762; 1; 2599.999297; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 +1376502062; 1; 2599.999297; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.4; 0.0; 0.0 +1376502362; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376502662; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 8.4; 0.0 +1376502962; 1; 2599.999297; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1376503263; 1; 2599.999297; 0.0; 0.0; 2097152.0; 113244.26666666666; 0.0; 1.2; 0.0; 0.0 +1376503563; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 138410.93333333332; 0.0; 7.466666666666667; 0.2; 0.13333333333333333 +1376503863; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 169168.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1376504163; 1; 2599.999297; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 1.6; 0.0; 0.0 +1376504463; 1; 2599.999297; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1376504763; 1; 2599.999297; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376505063; 1; 2599.999297; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.2; 0.0; 0.0 +1376505363; 1; 2599.999297; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376505663; 1; 2599.999297; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376505963; 1; 2599.999297; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 1.2; 0.0; 0.0 +1376506263; 1; 2599.999297; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376506563; 1; 2599.999297; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1376506863; 1; 2599.999297; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.4; 0.0; 0.0 +1376507163; 1; 2599.999297; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376507463; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 162177.86666666667; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 +1376507763; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376508063; 1; 2599.999297; 317.19991423399995; 12.2; 2097152.0; 437603.2; 907.8; 1409.7333333333333; 246.6; 7.866666666666666 +1376508363; 1; 2599.999297; 109.199970474; 4.2; 2097152.0; 829071.7333333333; 1.4666666666666666; 6.466666666666667; 0.0; 0.13333333333333333 +1376508663; 1; 2599.999304; 31.199991648; 1.2; 2097152.0; 419428.0; 0.0; 1.7777777777777777; 0.0; 0.0 +1376508963; 1; 2599.999304; 34.66665738666667; 1.3333333333333335; 2097152.0; 321561.86666666664; 0.8; 5.0; 0.0; 0.06666666666666667 +1376509263; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 223693.33333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1376509563; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376509863; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.13333333333333333; 0.0 +1376510163; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376510463; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376510763; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376511064; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 201324.8; 17.266666666666666; 2.6; 0.06666666666666667; 0.4666666666666667 +1376511364; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376511664; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376511964; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376512264; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376512564; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376512864; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376513164; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1376513464; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376513764; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1376514064; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1376514364; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376514664; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1376514964; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376515264; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376515564; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376515864; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376516164; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376516464; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376516764; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1376517064; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376517365; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121632.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376517665; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8; 0.0; 0.0 +1376517965; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376518265; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163576.0; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1376518565; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376518865; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376519165; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 +1376519465; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 2.7333333333333334; 1.2; 0.0; 0.0 +1376519765; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.06666666666666667 +1376520065; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1376520365; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376520665; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1376520965; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376521265; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376521565; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 141206.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376521865; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 164974.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376522165; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1376522465; 1; 2599.999304; 136.93329667733332; 5.266666666666667; 2097152.0; 171964.0; 161.86666666666667; 14.466666666666667; 0.0; 0.0 +1376522765; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 289404.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376523065; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 170567.46666666667; 31.8; 3.7333333333333334; 0.0; 0.0 +1376523365; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 226490.4; 0.0; 0.8; 0.0; 0.0 +1376523665; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376523965; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376524265; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 7.0; 0.2; 0.13333333333333333 +1376524565; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 146798.4; 0.0; 0.8; 0.0; 0.0 +1376524865; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376525165; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1376525465; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 159380.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376525765; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 +1376526065; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 0.8; 0.0; 0.0 +1376526365; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376526665; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.6666666666666666; 1.1333333333333333; 0.0; 0.0 +1376526965; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1376527265; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376527565; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376527865; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376528165; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376528465; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 86680.26666666666; 0.0; 11.666666666666666; 0.0; 0.0 +1376528765; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 142604.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376529065; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163576.0; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1376529365; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376529666; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376529966; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376530266; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.26666666666; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 +1376530566; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1376530866; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 159382.4; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1376531166; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376531466; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376531766; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1376532066; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376532366; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376532666; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 163575.73333333334; 0.0; 2.066666666666667; 0.0; 0.5333333333333333 +1376532966; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 +1376533266; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376533566; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376533866; 1; 2599.999304; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376534166; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376534466; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.6; 0.0; 0.0 +1376534766; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376535066; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376535366; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376535666; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376535966; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1376536266; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 199926.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376536566; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 128624.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376536866; 1; 2599.999304; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1376537166; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376537466; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376537766; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.2 +1376538066; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.8; 0.0; 0.8; 0.0; 0.0 +1376538366; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4; 0.0; 0.0 +1376538666; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376538967; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 174761.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376539267; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117438.13333333333; 0.0; 0.6; 0.0; 0.0 +1376539567; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1376539867; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 174760.53333333333; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1376540167; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376540466; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376540766; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376541066; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376541366; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376541666; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1376541966; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1376542267; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376542567; 1; 2599.999304; 0.0; 0.0; 2097152.0; 148196.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376542867; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1376543167; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376543467; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 188741.33333333334; 0.06666666666666667; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376543767; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.33333333334; 0.0; 6.8; 0.2; 0.13333333333333333 +1376544067; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1376544367; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376544667; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376544967; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1376545267; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376545567; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376545867; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376546167; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376546467; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376546767; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376547067; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 166371.73333333334; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376547367; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 131420.26666666666; 0.0; 0.8; 0.0; 0.0 +1376547667; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376547967; 1; 2599.999304; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 0.6; 0.0; 0.0 +1376548267; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1376548567; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 1.9333333333333333; 0.0; 0.0 +1376548867; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1376549167; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376549467; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376549767; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1376550067; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 153789.06666666668; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376550367; 1; 2599.999304; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376550667; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 192936.0; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376550968; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.53333333333; 0.0; 0.6; 0.0; 0.0 +1376551268; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376551568; 1; 2599.999304; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6; 0.0; 0.0 +1376551868; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376552168; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376552468; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1376552768; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.6; 0.0; 0.0 +1376553068; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376553368; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376553668; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376553968; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.7333333333333333; 1.9333333333333333; 1.2; 0.0 +1376554268; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 159381.86666666667; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1376554568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155187.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376554868; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376555168; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1376555468; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376555768; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376556068; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1376556368; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 141207.46666666667; 0.0; 6.8; 0.2; 0.13333333333333333 +1376556668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 150993.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376556968; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376557268; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 1.5333333333333334; 1.4666666666666666; 0.0; 0.0 +1376557568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376557868; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 176159.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376558168; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1376558468; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376558768; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376559068; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376559368; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376559668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1376559968; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376560268; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376560568; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376560868; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376561168; 1; 2599.999304; 0.0; 0.0; 2097152.0; 134215.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376561468; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 132818.4; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376561768; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376562068; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 7.2; 0.26666666666666666; 0.13333333333333333 +1376562368; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376562668; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376562968; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376563269; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376563569; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376563869; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376564169; 1; 2599.999304; 195.86661423466666; 7.533333333333334; 2097152.0; 359310.4; 162.26666666666668; 117.66666666666667; 0.0; 0.4 +1376564469; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 655707.7333333333; 0.0; 6.0; 0.06666666666666667; 0.0 +1376564769; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 292200.8; 31.8; 3.466666666666667; 0.0; 0.0 +1376565069; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 255850.4; 18.0; 3.933333333333333; 0.7333333333333333; 0.4666666666666667 +1376565369; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 169168.26666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1376565669; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1376565969; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376566269; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.33333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376566569; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376566869; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1376567169; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376567469; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376567769; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376568069; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376568369; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376568669; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 211111.2; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376568969; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 149595.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376569269; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1376569569; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376569869; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1376570169; 1; 2599.999304; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376570469; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1376570769; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376571069; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376571369; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.3333333333333333; 0.0 +1376571669; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376571969; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 11.6; 0.0; 0.0 +1376572269; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 141207.2; 1.0; 3.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376572569; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376572869; 1; 2599.999304; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1376573169; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376573469; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1376573769; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376574069; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376574369; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376574669; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1376574969; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376575269; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376575569; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 +1376575869; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163576.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376576169; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 155188.0; 0.06666666666666667; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1376576469; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 0.8; 0.13333333333333333; 0.0 +1376576769; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.3333333333333333; 0.0 +1376577069; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.8; 0.06666666666666667 +1376577369; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376577669; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376577970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376578270; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1376578570; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117438.4; 0.0; 0.6; 0.0; 0.0 +1376578870; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.8; 0.0; 0.0 +1376579170; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1376579470; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 155188.0; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376579770; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376580070; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.6; 0.0; 0.0 +1376580370; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376580670; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 141206.66666666666; 0.0; 0.6; 0.0; 0.0 +1376580970; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376581270; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376581570; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 7.4; 0.3333333333333333; 0.13333333333333333 +1376581870; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1376582170; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376582470; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376582770; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376583070; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 192936.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376583370; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376583670; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376583970; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1376584270; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376584570; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376584870; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376585170; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376585470; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 2.8; 0.0 +1376585770; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376586070; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 +1376586370; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142604.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376586670; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 176159.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376586970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376587270; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376587571; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1376587871; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376588171; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376588471; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 145401.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376588771; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376589071; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1376589371; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376589670; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376589970; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1376590270; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 150993.6; 0.2; 2.0; 0.06666666666666667; 0.4666666666666667 +1376590570; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376590870; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1376591170; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376591470; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376591771; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376592071; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376592371; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 62912.0; 0.0; 0.5333333333333333; 0.13333333333333333; 0.0 +1376592671; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376592971; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376593271; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376593571; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 +1376593871; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 170565.86666666667; 0.0; 8.2; 0.26666666666666666; 0.6666666666666666 +1376594171; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376594471; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 79689.6; 0.0; 0.6; 0.0; 0.0 +1376594771; 1; 2599.999304; 65.86664903466666; 2.533333333333333; 2097152.0; 329950.13333333336; 161.73333333333332; 22.933333333333334; 0.0; 0.2 +1376595071; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 486536.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1376595371; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 174760.8; 31.8; 3.6666666666666665; 0.0; 0.0 +1376595671; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 135614.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376595971; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376596271; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121633.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376596571; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376596871; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1376597171; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376597471; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 190138.66666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.5333333333333333 +1376597771; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376598071; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1376598371; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376598671; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376598971; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376599271; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376599571; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 159381.6; 12.733333333333333; 13.0; 0.4; 0.13333333333333333 +1376599871; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376600171; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376600471; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376600771; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376601072; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 156586.13333333333; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1376601372; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376601672; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376601972; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 145401.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376602272; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1376602572; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1376602872; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1376603172; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1376603472; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376603772; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1376604072; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376604372; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376604672; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 220897.6; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376604972; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 7.266666666666667; 0.3333333333333333; 0.13333333333333333 +1376605272; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376605572; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376605872; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 97865.33333333333; 2.6666666666666665; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1376606172; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1376606472; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376606772; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1376607072; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376607372; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376607672; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376607972; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1376608272; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1376608572; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376608872; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376609172; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376609472; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376609772; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 62912.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376610072; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1376610372; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376610672; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1376610972; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1376611272; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376611572; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376611872; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 201324.53333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376612172; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1376612472; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376612772; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376613072; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 92272.8; 0.6; 1.2; 0.0; 0.0 +1376613372; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1376613672; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1376613972; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 125827.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376614272; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1376614572; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376614872; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376615172; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376615472; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 170565.86666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376615772; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 11.733333333333333; 0.06666666666666667; 0.0 +1376616072; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376616372; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376616672; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376616973; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376617273; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376617573; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376617873; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1376618173; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376618473; 1; 2599.999304; 71.06664764266665; 2.733333333333333; 2097152.0; 571821.6; 166.6; 21.533333333333335; 0.06666666666666667; 0.4 +1376618773; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 569025.0666666667; 0.0; 2.466666666666667; 0.0; 0.0 +1376619073; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 293599.4666666667; 31.866666666666667; 5.466666666666667; 0.06666666666666667; 0.5333333333333333 +1376619373; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 197130.93333333332; 0.0; 2.2666666666666666; 0.0; 0.0 +1376619673; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 139808.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1376619973; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376620273; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 4.333333333333333; 0.0; 0.0 +1376620573; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376620873; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376621173; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 132818.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376621473; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 109049.86666666667; 0.0; 0.6; 0.0; 0.0 +1376621773; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376622073; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376622373; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376622673; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 146798.93333333332; 0.2; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376622973; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 0.8; 0.0; 0.0 +1376623273; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1376623573; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376623873; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 100661.6; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1376624173; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376624473; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376624773; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376625073; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376625373; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376625673; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 1.4666666666666666; 1.0; 0.06666666666666667; 0.06666666666666667 +1376625973; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376626273; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 104856.0; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376626573; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376626873; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376627173; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376627473; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376627773; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376628073; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1376628373; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376628673; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376628973; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 150993.6; 0.0; 0.6; 0.0; 0.0 +1376629273; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376629573; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376629873; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 139808.8; 0.0; 8.2; 0.26666666666666666; 0.6 +1376630173; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 152391.46666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376630474; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376630774; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1376631074; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1376631374; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376631674; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376631974; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376632274; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1376632574; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.06666666666666667; 0.0 +1376632874; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376633174; 1; 2599.999304; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376633474; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 173362.93333333332; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376633774; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376634074; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376634374; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376634674; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.06666666666666667 +1376634974; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 2.066666666666667; 0.0; 0.0 +1376635274; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1376635574; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376635874; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376636174; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376636474; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376636774; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376637074; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 157983.46666666667; 0.6; 8.666666666666666; 0.3333333333333333; 0.6666666666666666 +1376637374; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376637674; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376637974; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376638274; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376638574; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376638874; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376639174; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376639474; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376639774; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376640074; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376640374; 1; 2599.999304; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376640674; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1376640974; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1376641275; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376641575; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376641875; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376642175; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376642475; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1376642775; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1376643075; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376643375; 1; 2599.999304; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376643675; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1376643975; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376644275; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 155187.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376644575; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1376644875; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376645175; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376645475; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 2.2666666666666666; 0.0 +1376645775; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376646075; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1376646375; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376646675; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376646975; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376647275; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376647575; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376647875; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 209713.6; 0.0; 2.2; 0.0; 0.4666666666666667 +1376648175; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376648475; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376648775; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376649075; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376649375; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1376649675; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376649975; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 +1376650276; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 +1376650576; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376650876; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376651176; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376651476; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 170566.66666666666; 0.0; 2.2; 0.0; 0.4666666666666667 +1376651776; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376652076; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 2.933333333333333; 0.0 +1376652376; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376652676; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376652976; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.6; 4.933333333333334; 0.0 +1376653276; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376653576; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121632.8; 0.0; 1.2; 0.0; 0.0 +1376653876; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376654176; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.6666666666666666; 0.0 +1376654476; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376654776; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376655076; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 157983.46666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376655376; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1376655676; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 62912.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376655976; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376656276; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376656576; 1; 2599.999304; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376656876; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376657176; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 1.3333333333333333; 0.0 +1376657476; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 1.5333333333333334; 0.0 +1376657776; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.3333333333333333; 0.0 +1376658076; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.6; 0.0 +1376658376; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.7333333333333333; 0.0 +1376658676; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 188741.6; 0.06666666666666667; 2.4; 0.4; 0.5333333333333333 +1376658976; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 139809.06666666668; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1376659276; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 11.533333333333333; 0.0; 0.0 +1376659576; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376659876; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376660176; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376660476; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376660776; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376661076; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142604.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376661376; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376661676; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.13333333333333333; 0.0 +1376661976; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1376662276; 1; 2599.999304; 24.266660170666665; 0.9333333333333332; 2097152.0; 198528.53333333333; 12.733333333333333; 14.733333333333333; 0.4; 0.6 +1376662576; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 169169.06666666668; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376662876; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376663176; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 57319.46666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1376663476; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 62912.0; 0.0; 0.8; 0.2; 0.13333333333333333 +1376663777; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376664077; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376664377; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 121632.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376664677; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376664977; 1; 2599.999304; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1376665277; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1376665577; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1376665877; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 171964.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376666177; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376666477; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 +1376666777; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376667077; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376667377; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376667677; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1376667977; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.7333333333333334; 0.0; 0.0 +1376668277; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1376668577; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376668877; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376669177; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 118837.33333333333; 0.0; 7.2; 0.2; 0.13333333333333333 +1376669477; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 169168.53333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376669777; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 131420.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376670077; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376670377; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376670677; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1376670977; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1376671277; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376671577; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376671878; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376672178; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1376672478; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 146799.2; 0.0; 0.6; 0.0; 0.0 +1376672778; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376673078; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 195732.26666666666; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376673378; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376673678; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376673978; 1; 2599.999304; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376674278; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376674578; 1; 2599.999304; 25.99999304; 1.0; 2097152.0; 155188.26666666666; 161.06666666666666; 27.466666666666665; 0.4; 0.5333333333333333 +1376674878; 1; 2599.999304; 48.53332034133333; 1.8666666666666665; 2097152.0; 722816.5333333333; 0.0; 2.6; 0.0; 0.0 +1376675178; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 324357.86666666664; 31.8; 3.0; 0.06666666666666667; 0.0 +1376675478; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 174760.8; 0.0; 2.4; 0.0; 0.0 +1376675778; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 187343.73333333334; 0.0; 1.7333333333333334; 0.0; 0.0 +1376676078; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.13333333333; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376676378; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376676678; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 156585.33333333334; 0.0; 2.0; 0.13333333333333333; 0.4666666666666667 +1376676978; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376677278; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376677578; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376677878; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.6; 0.13333333333333333; 0.0 +1376678178; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.06666666666666667; 0.0 +1376678478; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376678778; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376679078; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142605.6; 0.0; 0.6; 0.0; 0.0 +1376679378; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.06666666666666667; 0.0 +1376679679; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.5333333333333333; 0.13333333333333333; 0.0 +1376679979; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376680279; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 183149.86666666667; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1376680579; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 142605.6; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1376680879; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 164973.33333333334; 0.0; 0.6; 0.0; 0.0 +1376681179; 1; 2599.999304; 43.333321733333335; 1.6666666666666665; 2097152.0; 267036.26666666666; 161.0; 14.466666666666667; 0.0; 0.2 +1376681479; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 459973.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1376681779; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 187344.0; 31.8; 3.466666666666667; 0.0; 0.0 +1376682079; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376682379; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376682679; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376682979; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376683279; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376683579; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376683879; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 150994.4; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376684179; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.06666666666666667; 1.6666666666666667; 0.0; 0.0 +1376684479; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376684779; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376685079; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376685379; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 149595.73333333334; 0.0; 1.0; 0.0; 0.0 +1376685679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376685979; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376686279; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376686579; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1376686879; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1376687179; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 145401.33333333334; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1376687479; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 192935.73333333334; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376687779; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376688079; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376688379; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376688679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376688979; 1; 2599.999304; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376689279; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1376689579; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 65708.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376689879; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376690179; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 62912.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376690479; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376690779; 1; 2599.999304; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376691079; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 187342.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1376691379; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137012.8; 0.0; 0.8; 0.0; 0.0 +1376691679; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376691979; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376692279; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.13333333333333333 +1376692579; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 156586.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1376692879; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376693179; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 137012.26666666666; 0.06666666666666667; 7.466666666666667; 0.2; 0.13333333333333333 +1376693480; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376693780; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376694080; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.2; 0.06666666666666667 +1376694380; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376694680; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376694980; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376695280; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376695580; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376695880; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376696180; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376696480; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 174760.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376696780; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 146800.0; 0.0; 1.0; 0.0; 0.0 +1376697080; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 +1376697380; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1376697680; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376697980; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376698280; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.0; 0.06666666666666667; 0.5333333333333333 +1376698580; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.5333333333333333; 0.0; 0.0 +1376698880; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1376699180; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 124429.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376699480; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1376699780; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376700080; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 +1376700380; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376700680; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376700980; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376701280; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376701581; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376701881; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 198529.06666666668; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376702181; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376702481; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376702781; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376703081; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 171964.53333333333; 0.0; 11.666666666666666; 0.0; 0.0 +1376703381; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376703681; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376703981; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376704281; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376704581; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376704881; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1376705181; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376705481; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 146799.2; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376705781; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 145401.06666666668; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1376706081; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1376706381; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376706681; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376706981; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376707281; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376707581; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.4; 0.0 +1376707881; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 124429.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376708181; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376708481; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376708781; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376709081; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 159383.2; 0.06666666666666667; 2.2666666666666666; 1.0666666666666667; 0.5333333333333333 +1376709381; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 0.6; 0.0; 0.0 +1376709681; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376709981; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376710281; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376710581; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376710881; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376711181; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376711481; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376711781; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376712082; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 86680.26666666666; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1376712382; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.6; 0.06666666666666667; 0.0 +1376712682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1376712982; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376713282; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376713582; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376713882; 1; 2599.999304; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1376714182; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376714482; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376714782; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376715082; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376715382; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376715682; 1; 2599.999304; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 +1376715982; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1376716282; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 150993.06666666668; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376716582; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376716882; 1; 2599.999304; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376717182; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376717482; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1376717782; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376718082; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376718382; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 190138.93333333332; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1376718682; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.06666666666666667; 0.0 +1376718982; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376719282; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117437.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376719582; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376719882; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 187343.2; 0.2; 2.466666666666667; 0.0; 0.5333333333333333 +1376720182; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376720482; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376720782; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376721082; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376721382; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.2666666666666666; 0.26666666666666666; 0.13333333333333333 +1376721682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 1.4666666666666666; 0.13333333333333333; 0.0 +1376721982; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1376722282; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 0.6; 0.0; 0.0 +1376722582; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.8; 3.7333333333333334; 0.0 +1376722882; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376723182; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376723482; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 173362.13333333333; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376723782; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 134216.8; 12.733333333333333; 17.0; 0.3333333333333333; 0.2 +1376724082; 1; 2599.999304; 60.66665042666666; 2.3333333333333335; 2097152.0; 279618.6666666667; 161.0; 22.133333333333333; 0.06666666666666667; 0.4 +1376724382; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 763362.4; 0.0; 2.7333333333333334; 0.06666666666666667; 0.0 +1376724682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 348124.8; 31.8; 3.533333333333333; 0.0; 0.0 +1376724982; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 188741.6; 0.0; 2.3333333333333335; 0.0; 0.0 +1376725282; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 +1376725582; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1376725882; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376726182; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376726482; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376726782; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376727082; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 181750.93333333332; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376727382; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1376727682; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376727982; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376728282; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.2; 0.0 +1376728583; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376728883; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376729183; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376729483; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376729783; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376730083; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 7.0; 0.3333333333333333; 0.13333333333333333 +1376730383; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376730683; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 166372.0; 0.06666666666666667; 2.4; 0.13333333333333333; 0.4666666666666667 +1376730983; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376731283; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376731583; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376731883; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376732183; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376732483; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376732783; 1; 2599.999304; 0.0; 0.0; 2097152.0; 100660.8; 0.0; 1.0; 0.0; 0.0 +1376733083; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376733383; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376733683; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376733983; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376734283; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184547.2; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376734583; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376734883; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 64310.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376735184; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376735484; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 7.866666666666666; 0.0 +1376735784; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376736084; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 144002.93333333332; 0.0; 7.533333333333333; 0.2; 0.13333333333333333 +1376736384; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 155188.0; 0.0; 0.8; 0.13333333333333333; 0.0 +1376736684; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1376736984; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376737284; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.2; 0.0 +1376737584; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376737884; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 160779.46666666667; 0.0; 2.466666666666667; 0.2; 0.5333333333333333 +1376738184; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376738484; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376738784; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376739084; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376739384; 1; 2599.999304; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376739684; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376739984; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376740284; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376740584; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1376740884; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376741184; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1376741484; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 171964.8; 0.0; 2.2; 0.13333333333333333; 0.4666666666666667 +1376741784; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376742084; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1376742384; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 6.866666666666666; 0.3333333333333333; 0.2 +1376742684; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376742984; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376743284; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376743584; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376743885; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376744185; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376744485; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376744785; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376745085; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.3333333333333335; 0.2; 0.4666666666666667 +1376745385; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376745685; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376745985; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376746285; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376746585; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 11.6; 0.13333333333333333; 0.0 +1376746885; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1376747185; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376747485; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376747785; 1; 2599.999304; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1376748085; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376748385; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.2; 0.13333333333333333 +1376748685; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 167769.86666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376748985; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138411.2; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1376749285; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376749585; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376749885; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.06666666666666667; 1.0666666666666667; 0.06666666666666667; 0.13333333333333333 +1376750185; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 128624.26666666666; 0.06666666666666667; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1376750485; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376750785; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376751085; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376751385; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1376751685; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376751985; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376752285; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 141207.46666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376752586; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376752886; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1376753186; 1; 2599.999304; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376753485; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376753785; 1; 2599.999304; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376754085; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376754385; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376754685; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 81087.73333333334; 0.0; 7.2; 0.2; 0.13333333333333333 +1376754985; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376755285; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376755585; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376755885; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 155188.26666666666; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1376756185; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 124429.6; 0.0; 0.8; 0.0; 0.0 +1376756485; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125826.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376756785; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95068.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1376757085; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.4; 0.0; 0.0 +1376757385; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376757685; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376757985; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376758285; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 155188.8; 0.0; 0.6; 0.0; 0.0 +1376758585; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1376758885; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 65708.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376759186; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376759486; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 169168.8; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376759786; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125827.73333333334; 0.0; 1.0; 0.0; 0.0 +1376760086; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376760386; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 117438.66666666667; 0.0; 6.6; 0.2; 0.13333333333333333 +1376760686; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117438.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376760986; 1; 2599.999304; 20.799994432; 0.8; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376761286; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 125827.2; 0.0; 1.0; 0.0; 0.0 +1376761586; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1376761886; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376762186; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376762486; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.06666666666666667 +1376762786; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1376763086; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 198528.8; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376763386; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 125827.73333333334; 0.0; 0.8; 0.0; 0.0 +1376763686; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376763986; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.5333333333333333; 0.0; 0.0 +1376764286; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376764586; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376764886; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376765186; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376765486; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376765786; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376766086; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376766386; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 139808.53333333333; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1376766686; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 185944.53333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376766986; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376767286; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138411.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1376767586; 1; 2599.999304; 45.06665460266667; 1.7333333333333334; 2097152.0; 166371.73333333334; 161.2; 14.133333333333333; 0.0; 0.2 +1376767886; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 432010.93333333335; 0.0; 1.2; 0.0; 0.0 +1376768187; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 177556.53333333333; 31.8; 3.4; 0.0; 0.0 +1376768487; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184546.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1376768787; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376769087; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376769387; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376769687; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1376769987; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376770287; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 155188.0; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376770587; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376770887; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376771187; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376771487; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376771787; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376772087; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376772387; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1376772687; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1376772987; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 117438.4; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1376773287; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376773587; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376773887; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 180352.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1376774187; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376774487; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376774787; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1376775087; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376775387; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376775687; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376775988; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376776288; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376776588; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376776891; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376777191; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376777491; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 149594.4; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376777791; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 +1376778091; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376778391; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376778691; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1376778991; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 114642.93333333333; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 +1376779291; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376779591; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376779891; 1; 2599.999304; 46.799987472000005; 1.8; 2097152.0; 153789.6; 161.46666666666667; 27.933333333333334; 0.3333333333333333; 0.6 +1376780191; 1; 2599.999304; 34.66665738666667; 1.3333333333333335; 2097152.0; 735398.9333333333; 0.0; 2.4; 0.0; 0.0 +1376780491; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 290802.93333333335; 31.8; 3.3333333333333335; 0.0; 0.0 +1376780791; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 178954.4; 0.0; 2.3333333333333335; 0.0; 0.0 +1376781091; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 184547.73333333334; 0.06666666666666667; 3.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376781391; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376781691; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376781991; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1376782291; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 121633.6; 0.06666666666666667; 1.0666666666666667; 0.0; 0.0 +1376782591; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130021.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376782891; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376783191; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 137012.53333333333; 0.0; 1.2; 0.0; 0.0 +1376783491; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 164973.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376783791; 1; 2599.999304; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376784091; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376784392; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1376784692; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 156586.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376784992; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1376785292; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376785592; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376785892; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376786191; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 134216.8; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1376786491; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 134216.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1376786791; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376787091; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376787391; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1376787691; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1376787991; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376788291; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 131419.73333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 +1376788591; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376788891; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376789191; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376789491; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376789791; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376790092; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376790392; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 127225.6; 0.0; 12.0; 0.0; 0.0 +1376790692; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.13333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376790992; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376791292; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1376791592; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1376791892; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.8; 0.06666666666666667; 0.4666666666666667 +1376792192; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376792492; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 114642.93333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376792792; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376793092; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376793392; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376793692; 1; 2599.999304; 19.066661562666667; 0.7333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 +1376793992; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376794292; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376794592; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376794892; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1376795192; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376795492; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 159380.8; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1376795792; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1376796092; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 78291.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376796392; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1376796692; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 128623.46666666666; 0.0; 0.6; 0.0; 0.0 +1376796992; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.0; 0.0 +1376797292; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376797592; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 145401.86666666667; 0.0; 1.2; 0.0; 0.0 +1376797892; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376798193; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1376798493; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376798793; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376799093; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 185945.33333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376799393; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376799693; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1376799993; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1376800293; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376800593; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376800893; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1376801193; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376801493; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 76893.33333333333; 0.0; 1.6; 0.0; 0.0 +1376801793; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 109050.4; 0.0; 0.5333333333333333; 0.0; 0.0 +1376802093; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 144003.73333333334; 0.0; 0.6; 0.0; 0.0 +1376802393; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138410.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376802693; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 195731.2; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376802993; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376803293; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1376803593; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376803893; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 +1376804193; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376804493; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376804793; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 7.0; 0.2; 0.13333333333333333 +1376805093; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130021.6; 0.0; 0.6; 0.0; 0.0 +1376805393; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376805693; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376805993; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376806293; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 208314.93333333332; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376806593; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 169169.33333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376806893; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 149595.46666666667; 0.0; 0.8; 0.0; 0.0 +1376807193; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 0.8; 0.0; 0.0 +1376807493; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.13333333333333333 +1376807793; 1; 2599.999304; 17.333328693333335; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.8; 0.06666666666666667; 0.0 +1376808093; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1376808393; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376808693; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1376808993; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376809293; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376809593; 1; 2599.999304; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1376809894; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 191537.86666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376810194; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376810494; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376810794; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1376811094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376811394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376811694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376811994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376812294; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376812594; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376812894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376813194; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1376813494; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 191537.86666666667; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376813794; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376814094; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1376814394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.5333333333333333; 0.0; 0.0 +1376814694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376814994; 1; 2599.999304; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6; 0.06666666666666667; 0.0 +1376815294; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1376815594; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1376815894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376816194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1376816494; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376816794; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376817094; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 150993.6; 0.2; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376817394; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376817694; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376817994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376818294; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376818594; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376818894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376819194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 57319.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376819494; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376819794; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376820094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.8; 0.0; 0.0 +1376820394; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376820694; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 150993.6; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1376820994; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376821294; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376821594; 1; 2599.999304; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376821894; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376822194; 1; 2599.999304; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376822494; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376822794; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376823094; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 173362.93333333332; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376823394; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376823694; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376823995; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376824295; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 142604.8; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1376824595; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376824895; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376825195; 1; 2599.999304; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376825495; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376825795; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376826095; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376826395; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 +1376826695; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120234.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376826995; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376827295; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376827595; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376827895; 1; 2599.999304; 25.99999304; 1.0; 2097152.0; 185945.6; 161.06666666666666; 22.0; 0.13333333333333333; 0.8666666666666667 +1376828195; 1; 2599.999304; 51.99998608; 2.0; 2097152.0; 812294.1333333333; 0.0; 3.533333333333333; 0.0; 0.0 +1376828495; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 402650.93333333335; 31.8; 3.066666666666667; 0.0; 0.0 +1376828795; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 215304.53333333333; 0.06666666666666667; 2.3333333333333335; 0.0; 0.0 +1376829095; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 1.8666666666666667; 0.0; 0.0 +1376829395; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376829695; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376829995; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1376830295; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376830595; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376830895; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.13333333333333333; 0.06666666666666667 +1376831195; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376831495; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163575.73333333334; 0.0; 2.3333333333333335; 0.13333333333333333; 0.5333333333333333 +1376831795; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376832096; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376832396; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376832696; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376832996; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1376833296; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376833596; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1376833896; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 11.4; 0.0; 0.0 +1376834196; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376834495; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 134215.73333333334; 0.0; 0.8; 0.0; 0.0 +1376834795; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376835095; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 187343.73333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 +1376835395; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376835695; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.13333333333333333; 0.0 +1376835995; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376836295; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 141206.66666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.2 +1376836595; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 146800.0; 0.0; 0.8; 0.0; 0.0 +1376836895; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376837195; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376837495; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376837795; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376838096; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376838396; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376838696; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 192935.73333333334; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1376838996; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376839296; 1; 2599.999304; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376839596; 1; 2599.999304; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376839896; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1376840196; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376840496; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376840796; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376841096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376841396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376841696; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376841996; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1376842296; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 155188.0; 0.06666666666666667; 8.266666666666667; 0.26666666666666666; 0.6 +1376842596; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 130022.4; 0.06666666666666667; 1.0; 0.06666666666666667; 0.0 +1376842896; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376843196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376843496; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376843796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376844096; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376844396; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376844696; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376844996; 1; 2599.999304; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376845296; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376845596; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376845896; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 104855.2; 0.06666666666666667; 2.8; 0.06666666666666667; 0.5333333333333333 +1376846196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 137011.73333333334; 0.0; 0.8; 0.0; 0.0 +1376846496; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1376846796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376847096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1376847396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376847696; 1; 2599.999304; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376847996; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376848296; 1; 2599.999304; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376848596; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 121633.6; 12.733333333333333; 13.4; 0.3333333333333333; 0.2 +1376848896; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 1.0; 0.0; 0.0 +1376849196; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 167771.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376849496; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 142605.6; 0.0; 1.6666666666666667; 0.06666666666666667; 0.4666666666666667 +1376849796; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1376850096; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376850396; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1376850696; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376850996; 1; 2599.999304; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376851296; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376851596; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376851896; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376852196; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376852496; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376852796; 1; 2599.999304; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1376853096; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 184548.0; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 +1376853396; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376853697; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1376853996; 1; 2599.999304; 36.399990255999995; 1.4; 2097152.0; 171964.8; 161.06666666666666; 14.333333333333334; 0.0; 0.2 +1376854297; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 461372.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1376854597; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 222295.2; 31.8; 9.666666666666666; 0.2; 0.13333333333333333 +1376854897; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 218100.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376855197; 1; 2599.999304; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376855497; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376855797; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376856097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376856397; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376856697; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167769.6; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1376856997; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 159381.6; 0.0; 1.0; 0.0; 0.0 +1376857297; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376857597; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376857897; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376858197; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376858497; 1; 2599.999304; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1376858797; 1; 2599.999304; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376859097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376859397; 1; 2599.999304; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376859697; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1376859997; 1; 2599.999304; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376860297; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 197129.6; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376860597; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 137012.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376860897; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 132818.66666666666; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1376861197; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 144002.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376861497; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376861797; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 132818.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376862097; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1376862397; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376862697; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376862997; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376863298; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376863598; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376863898; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 +1376864198; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1376864498; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376864798; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376865098; 1; 2599.999304; 9.2857118; 0.35714285714285715; 2097152.0; 140808.0; 0.07142857142857142; 1.4285714285714286; 0.14285714285714285; 0.14285714285714285 +1376865398; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376865698; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376865998; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376866298; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376866599; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1376866899; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 107652.26666666666; 0.2; 0.9333333333333333; 0.0; 0.0 +1376867199; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376867500; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 174761.06666666668; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1376867801; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1376868101; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376868401; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376868701; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1376869001; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376869301; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376869601; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376869901; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1376870201; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376870501; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376870801; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 162178.66666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376871101; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167770.4; 0.0; 2.8; 0.06666666666666667; 0.5333333333333333 +1376871401; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376871701; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376872001; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376872301; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 90874.66666666667; 0.06666666666666667; 1.4; 0.0; 0.0 +1376872601; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376872901; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376873201; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376873501; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1376873801; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1376874101; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376874401; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376874701; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 181751.2; 0.2; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376875001; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 127225.86666666667; 0.0; 1.0; 0.0; 0.0 +1376875301; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376875601; 1; 2599.999304; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376875901; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376876201; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1376876501; 1; 2599.999304; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376876801; 1; 2599.999304; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376877101; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376877401; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125827.2; 0.0; 11.6; 0.0; 0.0 +1376877701; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376878001; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1376878302; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 171965.06666666668; 0.06666666666666667; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1376878602; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 138410.93333333332; 0.0; 0.8; 0.0; 0.0 +1376878902; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376879202; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376879502; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376879802; 1; 2599.999304; 71.06664764266665; 2.733333333333333; 2097152.0; 661299.7333333333; 161.0; 21.466666666666665; 0.06666666666666667; 0.4 +1376880102; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 416631.73333333334; 0.0; 8.733333333333333; 0.2; 0.13333333333333333 +1376880402; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 262841.06666666665; 31.8; 3.7333333333333334; 0.0; 0.0 +1376880702; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 163576.53333333333; 0.0; 2.2666666666666666; 0.0; 0.0 +1376881002; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 96467.2; 0.0; 1.4; 0.0; 0.0 +1376881302; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376881602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376881902; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 206917.33333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1376882202; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 131419.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376882502; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 96466.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376882802; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 83883.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376883102; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376883402; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376883702; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376884002; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1376884302; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376884602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376884902; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376885202; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376885502; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 232082.93333333332; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1376885802; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 128624.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376886102; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376886402; 1; 2599.999304; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376886702; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.06666666666666667; 6.8; 0.26666666666666666; 0.2 +1376887002; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 155186.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1376887302; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 120235.2; 0.0; 1.0; 0.0; 0.0 +1376887602; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1376887902; 1; 2599.999304; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376888202; 1; 2599.999304; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376888502; 1; 2599.999304; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376888802; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1376889102; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 180352.53333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376889403; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376889703; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1376890003; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 124429.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376890303; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376890603; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1376890903; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1376891203; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376891503; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1376891803; 1; 2599.999304; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376892103; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376892403; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 145401.06666666668; 0.0; 6.533333333333333; 0.2; 0.13333333333333333 +1376892703; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 176158.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1376893003; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376893303; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1376893603; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376893903; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.06666666666666667 +1376894203; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 2.0; 0.06666666666666667; 0.0 +1376894503; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 144003.73333333334; 0.0; 1.4; 0.0; 0.0 +1376894803; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376895103; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 +1376895403; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376895703; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1376896003; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1376896304; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 128623.46666666666; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1376896604; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376896904; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376897204; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1376897504; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1376897804; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376898104; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376898404; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 156586.13333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1376898704; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376899004; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1376899304; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1376899604; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376899904; 1; 2599.999304; 15.599995824; 0.6; 2097152.0; 167771.46666666667; 0.6; 2.2; 0.06666666666666667; 0.5333333333333333 +1376900204; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1376900504; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 71300.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376900804; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1376901104; 1; 2599.999304; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1376901404; 1; 2599.999304; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376901704; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1376902004; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1376902304; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376902604; 1; 2599.999304; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376902904; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1376903204; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 132818.4; 0.0; 0.6; 0.0; 0.0 +1376903504; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 218101.06666666668; 0.0; 1.9333333333333333; 0.06666666666666667; 0.5333333333333333 +1376903804; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376904104; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1376904404; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1376904704; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 127225.86666666667; 0.0; 6.733333333333333; 0.4; 0.06666666666666667 +1376905004; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 142605.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1376905304; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1376905604; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376905904; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 132818.4; 0.0; 0.8; 0.0; 0.0 +1376906204; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 117438.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376906504; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 62912.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376906804; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376907104; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 184548.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376907404; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1376907704; 1; 2599.999304; 1.7333328693333334; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376908004; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1376908304; 1; 2599.999304; 3.466665738666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376908604; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1376908904; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.4; 0.0 +1376909204; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.0; 0.0 +1376909504; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 2.4; 0.0 +1376909804; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376910104; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.13333333333333333; 0.0 +1376910404; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376910705; 1; 2599.999304; 22.533327301333333; 0.8666666666666667; 2097152.0; 170566.66666666666; 12.8; 16.466666666666665; 0.4666666666666667; 0.7333333333333333 +1376911005; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1376911305; 1; 2599.999304; 10.399997216; 0.4; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376911605; 1; 2599.999304; 5.199998608; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376911905; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 162178.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376912205; 1; 2599.999304; 8.666664346666668; 0.33333333333333337; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1376912505; 1; 2599.999304; 6.933331477333334; 0.26666666666666666; 2097152.0; 96466.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376912805; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1376913105; 1; 2599.999304; 13.866662954666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376913405; 1; 2599.999304; 12.133330085333332; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1376913705; 1; 2599.9993; 28.888881111111115; 1.1111111111111112; 2097152.0; 125828.0; 0.0; 1.125; 0.0; 0.0 +1376914005; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376914305; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 166372.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376914605; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376914905; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1376915205; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 61513.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376915505; 1; 2599.999343; 28.599992773000004; 1.1; 2097152.0; 77592.4; 0.0; 1.0; 0.1111111111111111; 0.0 +1376915805; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376916105; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 146800.0; 0.0; 6.8; 0.3333333333333333; 0.13333333333333333 +1376916405; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376916705; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376917005; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376917305; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376917605; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 124429.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376917905; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 199925.33333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376918205; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376918505; 1; 2599.999343; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376918805; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376919105; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1376919405; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1376919705; 1; 2599.999343; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1376920005; 1; 2599.999343; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1376920306; 1; 2599.999343; 3.4666657906666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376920606; 1; 2599.99945; 25.9999945; 1.0; 2097152.0; 76257.81818181818; 0.0; 1.1; 0.0; 0.0 +1376920906; 1; 2599.99945; 8.666664833333334; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376921206; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 11.6; 0.0; 0.0 +1376921506; 1; 2599.99945; 12.133330766666665; 0.4666666666666666; 2097152.0; 156584.8; 0.0; 2.2; 0.0; 0.4666666666666667 +1376921806; 1; 2599.99945; 10.3999978; 0.4; 2097152.0; 130022.13333333333; 0.0; 7.2; 0.4; 0.2 +1376922106; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 159382.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1376922406; 1; 2599.99945; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1376922706; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1376923006; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 121633.06666666667; 0.0; 1.0; 0.0; 0.0 +1376923306; 1; 2599.99945; 5.1999989; 0.2; 2097152.0; 110448.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376923606; 1; 2599.99945; 1.7333329666666666; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376923906; 1; 2599.999306; 21.272721594545455; 0.8181818181818181; 2097152.0; 114388.72727272728; 0.0; 1.0; 0.0; 0.0 +1376924206; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376924506; 1; 2599.999297; 28.88888107777778; 1.1111111111111112; 2097152.0; 88544.44444444444; 0.0; 0.75; 0.0; 0.0 +1376924806; 1; 2599.999334; 28.363629098181818; 1.0909090909090908; 2097152.0; 101042.90909090909; 0.0; 0.8; 0.1; 0.0 +1376925106; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 141206.66666666666; 0.0; 2.2; 1.0; 0.5333333333333333 +1376925406; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 2.066666666666667; 0.0 +1376925706; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.6; 0.06666666666666667; 0.0 +1376926006; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1376926306; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376926606; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 61513.86666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376926906; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.13333333333333333; 0.0 +1376927206; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376927506; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1376927806; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376928106; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1376928406; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1376928706; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 155188.0; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1376929006; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 +1376929306; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376929606; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1376929906; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376930207; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376930507; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376930807; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 134216.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376931107; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.4; 0.0; 0.6; 0.0; 0.0 +1376931407; 1; 2599.999334; 57.19998534800001; 2.2; 2097152.0; 268433.3333333333; 161.0; 21.733333333333334; 0.0; 0.4 +1376931707; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 773148.0; 0.0; 2.6; 0.0; 0.0 +1376932007; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 304784.0; 31.8; 3.2666666666666666; 0.0; 0.0 +1376932307; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 219498.93333333332; 0.0; 3.6; 0.0; 0.4666666666666667 +1376932607; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1376932907; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376933207; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1376933507; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145400.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376933807; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1376934107; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1376934407; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 146799.46666666667; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 +1376934707; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138410.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1376935007; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1376935307; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376935607; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1376935907; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 138410.4; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1376936207; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376936507; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376936807; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376937107; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376937407; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1376937707; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376938007; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1376938307; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1376938607; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.6; 0.06666666666666667; 0.0 +1376938907; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 +1376939208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376939508; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 139809.33333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376939808; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1376940108; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1376940408; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 111846.13333333333; 161.0; 13.266666666666667; 0.0; 0.2 +1376940708; 1; 2599.999334; 38.13332356533333; 1.4666666666666666; 2097152.0; 518693.6; 0.0; 7.933333333333334; 0.26666666666666666; 0.13333333333333333 +1376941008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 225092.53333333333; 31.8; 3.0; 0.0; 0.0 +1376941308; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 219499.73333333334; 0.0; 1.8; 0.0; 0.0 +1376941608; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116040.8; 0.0; 1.2; 0.0; 0.0 +1376941908; 1; 2599.999334; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376942208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376942508; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1376942808; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376943108; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 190139.73333333334; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1376943408; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376943708; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376944008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376944308; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376944608; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376944908; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376945208; 1; 2599.999334; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376945508; 1; 2599.999334; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376945808; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.4; 0.0 +1376946108; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376946408; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1376946708; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 195732.26666666666; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1376947008; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376947309; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376947609; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376947909; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376948209; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1376948509; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1376948809; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1376949109; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1376949408; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1376949709; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376950009; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1376950309; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 176158.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376950609; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 149594.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376950909; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1376951209; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1376951509; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.13333333333333333; 0.13333333333333333 +1376951809; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376952109; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1376952409; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 114642.93333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1376952709; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376953009; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1376953309; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1376953610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376953910; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 137012.26666666666; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1376954210; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1376954510; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376954810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376955110; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376955410; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 +1376955710; 1; 2599.999334; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376956010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1376956310; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376956610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376956910; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376957210; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376957510; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 176159.2; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1376957810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1376958110; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 8.466666666666667; 0.0 +1376958410; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376958710; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 7.4; 0.26666666666666666; 0.2 +1376959010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1376959310; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1376959610; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376959910; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1376960210; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376960510; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376960810; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1376961110; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 141205.86666666667; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376961410; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6; 0.06666666666666667; 0.0 +1376961710; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376962010; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1376962311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1376962611; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376962911; 1; 2599.999334; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1376963211; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1376963511; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1376963811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1376964111; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1376964411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1376964711; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 153789.86666666667; 0.0; 13.4; 0.06666666666666667; 0.4666666666666667 +1376965011; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376965311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.6; 0.0; 0.0 +1376965611; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1376965911; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1376966211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376966511; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1376966811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1376967111; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 +1376967411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376967711; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1376968011; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 131419.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376968311; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 162177.86666666667; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1376968611; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.06666666666666667; 0.6666666666666666; 0.0; 0.0 +1376968911; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1376969211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1376969511; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1376969811; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376970111; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1376970411; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1376970711; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376971011; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376971311; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1376971611; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 130021.6; 12.733333333333333; 13.466666666666667; 0.3333333333333333; 0.2 +1376971911; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 156586.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1376972211; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376972512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376972812; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1376973112; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 156585.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1376973412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 149594.93333333332; 0.0; 0.6; 0.0; 0.0 +1376973712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1376974012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1376974312; 1; 2599.999626; 28.599995886000002; 1.1; 2097152.0; 62912.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1376974612; 1; 2599.999626; 19.066663923999997; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376974912; 1; 2599.999626; 13.866664671999999; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376975212; 1; 2599.999626; 17.333330840000002; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 +1376975512; 1; 2599.999626; 19.066663923999997; 0.7333333333333333; 2097152.0; 191537.86666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1376975812; 1; 2599.999334; 28.363629098181818; 1.0909090909090908; 2097152.0; 83884.0; 0.0; 0.9; 0.0; 0.0 +1376976112; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1376976412; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1376976712; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1376977012; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1376977312; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1376977612; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 6.8; 0.2; 0.13333333333333333 +1376977912; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116040.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1376978212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376978512; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376978812; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376979112; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 185945.6; 0.0; 2.0; 0.06666666666666667; 0.5333333333333333 +1376979412; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 148197.86666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1376979712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1376980012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376980312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.26666666666666666; 0.13333333333333333 +1376980612; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 146799.2; 0.0; 2.2; 0.06666666666666667; 0.0 +1376980912; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1376981212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376981512; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1376981812; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.2; 0.0 +1376982112; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.6; 0.2; 0.0 +1376982412; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 128623.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1376982712; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 150994.4; 0.06666666666666667; 2.8666666666666667; 2.3333333333333335; 0.4666666666666667 +1376983012; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.06666666666666667; 6.533333333333333; 0.2; 0.13333333333333333 +1376983312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.8; 0.0; 0.0 +1376983612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1376983912; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1376984212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1376984512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1376984812; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111845.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1376985112; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1376985412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1376985712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1376986012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1376986312; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 150993.06666666668; 0.0; 2.2666666666666666; 0.13333333333333333; 0.5333333333333333 +1376986612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 144003.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1376986912; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376987212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1376987512; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 1.3333333333333333; 4.0; 0.0; 0.0 +1376987812; 1; 2599.999334; 45.066655122666674; 1.7333333333333334; 2097152.0; 232082.4; 181.86666666666667; 31.2; 0.5333333333333333; 0.4 +1376988112; 1; 2599.999334; 41.59998934400001; 1.6; 2097152.0; 844450.9333333333; 0.0; 5.2; 0.0; 0.0 +1376988412; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 409641.3333333333; 31.8; 3.3333333333333335; 0.0; 0.0 +1376988712; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 244665.33333333334; 0.0; 2.533333333333333; 0.0; 0.0 +1376989012; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 184547.46666666667; 0.0; 7.666666666666667; 0.26666666666666666; 0.2 +1376989312; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 174761.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376989612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.2666666666666666; 0.6666666666666666; 0.0 +1376989912; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 192935.73333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1376990212; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1376990512; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1376990812; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376991112; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1376991412; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1376991712; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1376992012; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1376992312; 1; 2599.999334; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1376992612; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1376992913; 1; 2599.999334; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1376993213; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104855.73333333334; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1376993513; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 178955.2; 0.06666666666666667; 1.8; 0.0; 0.0 +1376993813; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1376994123; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376994423; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1376994724; 1; 2599.999334; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1376995024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1376995324; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 183150.13333333333; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1376995624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1376995924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1376996224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1376996524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1376996824; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.4; 0.06666666666666667; 0.4666666666666667 +1376997124; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 153789.06666666668; 0.0; 1.9333333333333333; 0.0; 0.0 +1376997424; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1376997724; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1376998024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1376998324; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1376998624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1376998924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 149596.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1376999224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.3333333333333333; 0.2; 0.0 +1376999524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1376999824; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.13333333333333333; 0.0 +1377000124; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377000424; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.7333333333333333; 0.4666666666666667 +1377000724; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 149595.46666666667; 0.0; 1.6; 0.0; 0.0 +1377001024; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377001324; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 146799.46666666667; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1377001624; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137012.0; 0.0; 0.8; 0.0; 0.0 +1377001924; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377002224; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377002524; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377002824; 1; 2599.999334; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377003125; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377003425; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377003725; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377004025; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 124429.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.4666666666666667 +1377004325; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 159382.13333333333; 0.13333333333333333; 1.8666666666666667; 0.06666666666666667; 0.0 +1377004625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377004925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1377005225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377005525; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377005825; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377006125; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1377006425; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377006725; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377007025; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377007325; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 +1377007625; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 +1377007925; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 188741.86666666667; 0.06666666666666667; 7.733333333333333; 0.4666666666666667; 0.13333333333333333 +1377008225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.8; 0.0; 0.0 +1377008525; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 11.8; 0.06666666666666667; 0.0 +1377008825; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377009125; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 0.9333333333333333; 0.13333333333333333; 0.06666666666666667 +1377009425; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377009725; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377010025; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 120234.93333333333; 0.0; 0.7333333333333333; 1.0; 0.0 +1377010325; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.0; 0.0; 1.0; 0.2; 0.0 +1377010625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.13333333333333333; 0.0 +1377010925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377011226; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.4666666666666667 +1377011526; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 137013.06666666668; 0.0; 1.7333333333333334; 0.0; 0.0 +1377011826; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377012126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377012426; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377012726; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1377013026; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1377013326; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1377013626; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.2; 0.0 +1377013926; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 176159.2; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377014226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377014526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377014825; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.06666666666666667; 0.4666666666666667 +1377015125; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 144003.73333333334; 0.0; 1.8666666666666667; 0.0; 0.0 +1377015425; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377015725; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377016025; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1377016325; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1377016625; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377016925; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377017225; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377017526; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.2; 0.0 +1377017826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 162177.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377018126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146798.93333333332; 0.0; 0.8; 0.13333333333333333; 0.0 +1377018426; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.4666666666666667 +1377018726; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 171964.8; 0.06666666666666667; 1.9333333333333333; 0.0; 0.0 +1377019026; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377019326; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.06666666666666667; 7.0; 1.4; 0.13333333333333333 +1377019626; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377019926; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377020226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377020526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377020826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377021126; 1; 2599.999334; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377021426; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377021726; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377022026; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.4666666666666667 +1377022326; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 152391.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377022626; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 120234.93333333333; 0.0; 0.8; 0.0; 0.0 +1377022926; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377023226; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377023526; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377023826; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1377024126; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377024426; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128624.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377024726; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 121633.06666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377025026; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377025326; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 2.2666666666666666; 0.0 +1377025627; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.13333333333333333; 0.4666666666666667 +1377025927; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 163576.8; 0.0; 7.6; 0.26666666666666666; 0.13333333333333333 +1377026227; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 142605.6; 0.0; 0.6; 0.06666666666666667; 0.0 +1377026527; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377026827; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377027127; 1; 2599.999334; 43.33332223333333; 1.6666666666666665; 2097152.0; 510304.5333333333; 161.0; 14.333333333333334; 0.0; 0.2 +1377027427; 1; 2599.999334; 0.0; 0.0; 2097152.0; 223694.4; 0.0; 1.2; 0.0; 0.0 +1377027727; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 222296.8; 31.8; 3.6; 0.0; 0.0 +1377028027; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1377028327; 1; 2599.999334; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377028627; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377028927; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377029227; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 +1377029527; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 201324.0; 0.06666666666666667; 1.7333333333333334; 0.0; 0.0 +1377029827; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377030127; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377030427; 1; 2599.999334; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377030727; 1; 2599.999334; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377031027; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377031327; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 124428.8; 12.8; 13.4; 0.3333333333333333; 0.13333333333333333 +1377031627; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 +1377031927; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377032227; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377032527; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377032827; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.4666666666666667 +1377033127; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 160780.53333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1377033427; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377033727; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377034027; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377034327; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377034627; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377034928; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377035228; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377035528; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377035828; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377036128; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377036428; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 162177.86666666667; 0.0; 1.3333333333333333; 0.06666666666666667; 0.4666666666666667 +1377036728; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 233480.8; 0.13333333333333333; 2.066666666666667; 0.0; 0.0 +1377037028; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 141207.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377037328; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 132817.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377037628; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1377037928; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 120234.66666666667; 0.0; 1.6; 0.13333333333333333; 0.13333333333333333 +1377038229; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1377038529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377038829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377039129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377039429; 1; 2599.999334; 50.266653790666666; 1.9333333333333333; 2097152.0; 225093.06666666668; 161.0; 21.333333333333332; 0.06666666666666667; 0.4 +1377039729; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 724214.9333333333; 0.0; 2.2666666666666666; 0.0; 0.0 +1377040029; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 320164.0; 31.8; 4.0; 0.06666666666666667; 0.4666666666666667 +1377040329; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 229286.4; 0.06666666666666667; 2.2666666666666666; 0.0; 0.0 +1377040629; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.0; 1.8; 0.0; 0.0 +1377040929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377041229; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377041529; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 120234.66666666667; 0.06666666666666667; 0.9333333333333333; 0.0; 0.0 +1377041829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377042129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377042429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.9333333333333333; 0.0; 0.0 +1377042729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377043029; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377043329; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1377043629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1377043929; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 153790.66666666666; 0.0; 1.9333333333333333; 0.0; 0.0 +1377044229; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377044529; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377044829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377045129; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.4; 0.0; 0.0 +1377045429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 88078.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377045729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377046029; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377046329; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377046629; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1377046929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377047230; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 127225.86666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377047529; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 205517.86666666667; 0.0; 2.1333333333333333; 0.0; 0.0 +1377047829; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377048129; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377048429; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377048729; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377049029; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377049329; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377049629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377049929; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377050229; 1; 2599.999334; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377050529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377050829; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 72698.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377051129; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 167770.4; 0.0; 1.4666666666666666; 0.0; 0.0 +1377051429; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377051729; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377052029; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 17.933333333333334; 0.26666666666666666; 0.13333333333333333 +1377052329; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377052629; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377052929; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377053229; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 135614.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377053529; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377053830; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377054130; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377054430; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 109050.4; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377054730; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 146799.2; 0.06666666666666667; 1.6666666666666667; 0.0; 0.0 +1377055030; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377055330; 1; 2599.999334; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377055630; 1; 2599.999334; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377055930; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377056230; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377056530; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377056830; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377057130; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104855.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377057430; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377057730; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377058030; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.06666666666666667; 7.2; 0.3333333333333333; 0.6666666666666666 +1377058330; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 176158.4; 0.0; 1.6666666666666667; 0.0; 0.0 +1377058630; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1377058930; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1377059230; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377059530; 1; 2599.999334; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377059830; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377060130; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377060430; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377060730; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377061030; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377061330; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377061631; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.06666666666666667; 0.4666666666666667 +1377061931; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 150994.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1377062231; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8; 0.0; 0.0 +1377062531; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377062831; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377063131; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377063431; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377063731; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377064031; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377064331; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 155187.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377064631; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377064931; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377065231; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.4666666666666666; 0.06666666666666667; 0.4666666666666667 +1377065531; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 180353.6; 0.26666666666666666; 1.7333333333333334; 0.0; 0.0 +1377065831; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377066131; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1377066431; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377066731; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.06666666666666667; 0.8666666666666667; 0.06666666666666667; 0.06666666666666667 +1377067031; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.9333333333333333; 0.0; 0.0 +1377067331; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 50328.8; 0.0; 1.4; 0.0; 0.0 +1377067631; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377067931; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.2; 0.0 +1377068231; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.2; 0.0 +1377068531; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.7333333333333334; 0.06666666666666667; 0.0 +1377068831; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.4666666666666667 +1377069131; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 146798.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1377069432; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1377069732; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.6; 0.13333333333333333 +1377070032; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377070332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377070632; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1377070932; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377071232; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1377071532; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377071832; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377072132; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1377072432; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.4666666666666667 +1377072732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 2.2666666666666666; 0.0; 0.0 +1377073032; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377073332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 117439.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1377073632; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377073932; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377074232; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.6; 0.0; 0.0 +1377074532; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377074832; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377075132; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377075432; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377075732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377076032; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.13333333333; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1377076332; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 176159.2; 0.0; 1.6666666666666667; 0.0; 0.0 +1377076632; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377076932; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 141207.46666666667; 0.0; 6.8; 0.2; 0.13333333333333333 +1377077232; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377077532; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377077832; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377078132; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 152390.13333333333; 20.2; 2.3333333333333335; 0.0; 0.06666666666666667 +1377078432; 1; 2599.999334; 24.266660450666663; 0.9333333333333332; 2097152.0; 138410.4; 0.0; 4.133333333333334; 0.0; 0.0 +1377078732; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 125827.2; 0.2; 2.466666666666667; 0.0; 0.0 +1377079032; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377079332; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377079632; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 96467.2; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377079932; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 150993.33333333334; 0.0; 1.4; 0.0; 0.0 +1377080232; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377080532; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377080832; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 92272.8; 0.0; 1.7333333333333334; 0.0; 0.0 +1377081132; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377081432; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377081732; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377082032; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1377082332; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1377082632; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377082932; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377083232; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 124429.33333333333; 0.0; 7.533333333333333; 0.26666666666666666; 0.6666666666666666 +1377083532; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 206916.26666666666; 0.0; 1.8; 0.0; 0.0 +1377083832; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377084132; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377084432; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377084732; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377085032; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377085332; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1377085632; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1377085932; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377086232; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377086532; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377086832; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.6; 0.06666666666666667; 0.4666666666666667 +1377087132; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 146799.2; 0.0; 1.6; 0.0; 0.0 +1377087432; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 0.8; 0.2; 0.0 +1377087732; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377088032; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377088332; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377088633; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377088933; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377089233; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 131419.73333333334; 12.733333333333333; 13.6; 0.4; 0.13333333333333333 +1377089533; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377089833; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377090133; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377090433; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.5333333333333334; 0.06666666666666667; 0.4666666666666667 +1377090733; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 169169.33333333334; 0.06666666666666667; 1.4; 0.06666666666666667; 0.0 +1377091033; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377091333; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377091633; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377091933; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377092233; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.6; 0.0; 0.0 +1377092533; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377092833; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377093133; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 69902.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377093433; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377093733; 1; 2599.999334; 62.399984016; 2.4; 2097152.0; 388670.93333333335; 161.06666666666666; 21.533333333333335; 0.13333333333333333; 0.4 +1377094033; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 581607.7333333333; 0.0; 4.2; 0.06666666666666667; 0.5333333333333333 +1377094333; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 320163.4666666667; 31.8; 4.333333333333333; 0.0; 0.0 +1377094633; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 216703.2; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.13333333333333333 +1377094933; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1377095233; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 142604.53333333333; 0.0; 0.8; 0.0; 0.0 +1377095533; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 150993.6; 0.06666666666666667; 11.866666666666667; 0.06666666666666667; 0.06666666666666667 +1377095833; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 156586.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377096133; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1377096433; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377096733; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377097033; 1; 2599.999334; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377097333; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377097633; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.5333333333333333 +1377097933; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 215305.06666666668; 0.0; 1.8; 0.0; 0.0 +1377098234; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377098534; 1; 2599.999334; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377098834; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1377099134; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1377099434; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.13333333333333333; 0.0 +1377099734; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377100034; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377100334; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377100634; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377100934; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 3.6666666666666665; 0.0 +1377101234; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.2; 0.4666666666666667 +1377101534; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 156586.13333333333; 0.06666666666666667; 8.2; 0.26666666666666666; 0.13333333333333333 +1377101834; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377102134; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377102434; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1377102734; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377103034; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377103334; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377103634; 1; 2599.999334; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377103934; 1; 2599.999334; 0.0; 0.0; 2097152.0; 54523.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377104234; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377104534; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 88078.4; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377104834; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.4666666666666667 +1377105134; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 155187.2; 0.0; 0.8; 0.0; 0.0 +1377105434; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1377105735; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377106035; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377106335; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 54523.2; 0.0; 0.6; 0.06666666666666667; 0.0 +1377106635; 1; 2599.999334; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8; 0.0; 0.0 +1377106935; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377107235; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 74097.06666666667; 0.0; 6.8; 0.26666666666666666; 0.2 +1377107535; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377107835; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377108135; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377108435; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 89476.26666666666; 0.0; 1.4; 0.06666666666666667; 0.4666666666666667 +1377108735; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 187342.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377109035; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377109335; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377109635; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377109935; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377110235; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377110535; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377110835; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377111135; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 1.0; 0.0; 0.0 +1377111435; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377111735; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377112036; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377112336; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 1.8; 0.0; 0.0 +1377112636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377112935; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.5333333333333334; 0.06666666666666667; 0.0 +1377113235; 1; 2599.999334; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377113535; 1; 2599.999334; 46.799988012; 1.8; 2097152.0; 466963.73333333334; 161.2; 20.266666666666666; 0.2; 0.3333333333333333 +1377113835; 1; 2599.999334; 0.0; 0.0; 2097152.0; 255851.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1377114135; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 167771.46666666667; 31.8; 3.6666666666666665; 0.0; 0.0 +1377114435; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377114735; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 134215.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377115035; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377115335; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 47532.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377115635; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 74097.06666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377115935; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1377116235; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377116535; 1; 2599.999334; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377116835; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1377117135; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377117435; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377117735; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377118036; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377118336; 1; 2599.999334; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1377118636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377118936; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377119236; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 9.066666666666666; 0.4; 0.6 +1377119536; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1377119836; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377120136; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377120436; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.2; 0.0 +1377120736; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377121036; 1; 2599.999334; 0.0; 0.0; 2097152.0; 152392.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377121336; 1; 2599.999334; 0.0; 0.0; 2097152.0; 111846.4; 0.0; 1.0; 0.0; 0.0 +1377121636; 1; 2599.999334; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377121936; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377122236; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377122537; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109049.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377122837; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 2.1333333333333333; 0.2; 0.4666666666666667 +1377123137; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 185945.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377123437; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377123737; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377124037; 1; 2599.999334; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377124337; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 1.6; 0.06666666666666667; 0.13333333333333333 +1377124637; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1377124937; 1; 2599.999334; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377125237; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 135614.13333333333; 169.73333333333332; 186.0; 0.2; 0.13333333333333333 +1377125537; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 260044.53333333333; 0.0; 0.8; 0.0; 0.0 +1377125837; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377126137; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.7333333333333333; 1.2; 0.0; 0.0 +1377126437; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377126737; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 176158.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377127037; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377127337; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377127637; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377127937; 1; 2599.999334; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377128237; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377128537; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377128837; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377129137; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377129437; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377129737; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377130037; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 97864.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377130337; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 215304.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377130637; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 167770.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377130937; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377131237; 1; 2599.999334; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377131537; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377131837; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377132138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377132438; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 113244.8; 0.0; 6.8; 0.2; 0.13333333333333333 +1377132738; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377133038; 1; 2599.999334; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377133338; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377133638; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 1.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377133938; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377134238; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377134538; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377134838; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377135138; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377135438; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377135738; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 58717.6; 0.0; 1.0; 0.0; 0.0 +1377136038; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377136338; 1; 2599.999334; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377136638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377136938; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377137238; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1377137538; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 170565.86666666667; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377137838; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377138138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377138438; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377138738; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 124429.86666666667; 0.06666666666666667; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1377139038; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377139338; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 11.8; 0.0; 0.0 +1377139638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377139938; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377140238; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377140538; 1; 2599.999334; 67.59998268400001; 2.6; 2097152.0; 669688.5333333333; 161.06666666666666; 22.0; 0.06666666666666667; 0.4 +1377140838; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 408244.26666666666; 0.0; 3.533333333333333; 0.0; 0.4666666666666667 +1377141138; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 258645.86666666667; 31.8; 3.533333333333333; 0.0; 0.0 +1377141438; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 149596.0; 0.0; 2.2666666666666666; 0.0; 0.0 +1377141738; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 160781.06666666668; 0.0; 1.9333333333333333; 0.0; 0.0 +1377142038; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 145400.8; 0.0; 0.8; 0.0; 0.0 +1377142338; 1; 2599.999334; 0.0; 0.0; 2097152.0; 148197.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377142638; 1; 2599.999334; 0.0; 0.0; 2097152.0; 128624.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377142938; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377143238; 1; 2599.999334; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377143538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377143838; 1; 2599.999334; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8; 0.0; 0.0 +1377144138; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1377144438; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 152391.73333333334; 0.0; 8.4; 0.26666666666666666; 0.6 +1377144738; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377145039; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377145339; 1; 2599.999334; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377145638; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377145938; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377146238; 1; 2599.999334; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377146538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377146838; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377147138; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377147438; 1; 2599.999334; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377147738; 1; 2599.999334; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377148038; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 2.4; 0.0; 0.5333333333333333 +1377148338; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 173362.93333333332; 0.06666666666666667; 0.7333333333333333; 0.0; 0.0 +1377148638; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377148938; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377149238; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377149538; 1; 2599.999334; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377149839; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377150139; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377150439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377150739; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377151039; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 173363.46666666667; 12.8; 13.4; 0.26666666666666666; 0.13333333333333333 +1377151339; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 142604.26666666666; 0.0; 1.4; 0.0; 0.0 +1377151639; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.0; 0.0; 2.2; 0.0; 0.4666666666666667 +1377151939; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 209712.26666666666; 0.0; 0.6; 0.0; 0.0 +1377152239; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377152539; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377152839; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377153139; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.13333333333333333 +1377153439; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 164973.86666666667; 0.0; 1.7333333333333334; 0.0; 0.0 +1377153739; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1377154039; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377154339; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377154639; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1377154939; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377155239; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377155539; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 132817.86666666667; 0.06666666666666667; 1.0; 0.13333333333333333; 0.0 +1377155839; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377156139; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377156439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377156739; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377157039; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377157339; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 8.2; 0.26666666666666666; 0.13333333333333333 +1377157639; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377157939; 1; 2599.999334; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1377158239; 1; 2599.999334; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377158539; 1; 2599.999334; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377158839; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1377159140; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 178955.46666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377159440; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377159740; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377160040; 1; 2599.999334; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377160340; 1; 2599.999334; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 +1377160640; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377160940; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377161240; 1; 2599.999334; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377161540; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1377161840; 1; 2599.999334; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.6; 0.0; 0.0 +1377162140; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1377162439; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.2; 2.6666666666666665; 0.0; 0.4666666666666667 +1377162739; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 162177.86666666667; 0.0; 0.6; 0.0; 0.0 +1377163039; 1; 2599.999334; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377163339; 1; 2599.999334; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6; 0.0; 0.0 +1377163639; 1; 2599.999334; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1377163939; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1377164239; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 81087.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377164539; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377164840; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377165140; 1; 2599.999334; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377165440; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377165740; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377166040; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.53333333334; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377166340; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 184546.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377166640; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377166940; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377167240; 1; 2599.999334; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377167540; 1; 2599.999334; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377167840; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377168140; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 4.733333333333333; 0.0 +1377168440; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377168740; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377169040; 1; 2599.999334; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377169340; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377169640; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377169940; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377170240; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377170540; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377170840; 1; 2599.999334; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377171140; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 92272.8; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1377171440; 1; 2599.999334; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377171740; 1; 2599.999334; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377172041; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1377172341; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377172641; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377172941; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1377173241; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 83884.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377173541; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 159381.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377173841; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377174141; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377174441; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377174741; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377175041; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377175341; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 0.0; 0.0 +1377175641; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377175941; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 149594.66666666666; 0.0; 1.0; 0.0; 0.0 +1377176241; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377176541; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377176841; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377177141; 1; 2599.999334; 20.799994672000004; 0.8; 2097152.0; 142604.8; 0.0; 7.0; 0.26666666666666666; 0.2 +1377177441; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377177741; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377178041; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377178341; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377178641; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377178941; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377179241; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377179541; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377179841; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377180141; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377180441; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 142604.8; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1377180741; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1377181041; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377181341; 1; 2599.999334; 1.7333328893333333; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377181641; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377181941; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1377182241; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 142604.0; 0.0; 0.8; 0.0; 0.0 +1377182542; 1; 2599.999334; 6.933331557333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377182842; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 85282.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377183142; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377183442; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1377183742; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377184042; 1; 2599.999334; 5.199998668000001; 0.2; 2097152.0; 110448.53333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1377184342; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 155187.2; 0.0; 0.7333333333333333; 0.2; 0.0 +1377184642; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377184942; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377185242; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377185542; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377185842; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377186142; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1377186442; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377186742; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377187042; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377187342; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377187642; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 88078.4; 0.13333333333333333; 2.4; 0.06666666666666667; 0.4666666666666667 +1377187942; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 +1377188242; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377188542; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377188842; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377189142; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377189442; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377189742; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377190042; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377190342; 1; 2599.999334; 19.066661782666664; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377190643; 1; 2599.999334; 12.133330225333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.13333333333333333; 0.0 +1377190943; 1; 2599.999334; 15.599996004; 0.6; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377191243; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.06666666666666667; 2.1333333333333333; 0.13333333333333333; 0.4666666666666667 +1377191543; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377191843; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377192143; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377192443; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377192743; 1; 2599.999334; 13.866663114666666; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377193043; 1; 2599.999297; 27.999992429230765; 1.0769230769230769; 2097152.0; 77431.07692307692; 0.0; 0.8333333333333334; 0.08333333333333333; 0.0 +1377193343; 1; 2599.999297; 17.33332864666667; 0.6666666666666667; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377193643; 1; 2599.999297; 34.66665729333334; 1.3333333333333335; 2097152.0; 100661.06666666667; 161.13333333333333; 20.6; 0.06666666666666667; 0.4 +1377193943; 1; 2599.999297; 55.46665166933333; 2.1333333333333333; 2097152.0; 746584.8; 0.0; 3.6666666666666665; 0.0; 0.0 +1377194243; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 327154.13333333336; 31.8; 3.4; 0.06666666666666667; 0.0 +1377194543; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 181752.53333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1377194843; 1; 2599.999297; 20.799994376; 0.8; 2097152.0; 121633.6; 0.0; 9.2; 0.26666666666666666; 0.6666666666666666 +1377195143; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 181751.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377195443; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377195743; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1377196043; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377196343; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377196643; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377196943; 1; 2599.999297; 15.599995781999999; 0.6; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377197243; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377197543; 1; 2599.999297; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377197843; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377198143; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 111845.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377198443; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 103457.33333333333; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1377198743; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 157982.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377199043; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377199343; 1; 2599.999297; 1.7333328646666666; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377199643; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 107651.46666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1377199943; 1; 2599.999297; 45.06665448133334; 1.7333333333333334; 2097152.0; 392864.0; 161.06666666666666; 14.4; 0.06666666666666667; 0.2 +1377200243; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 290802.6666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1377200543; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 243268.0; 31.8; 4.466666666666667; 0.0; 0.0 +1377200843; 1; 2599.999297; 12.133330052666665; 0.4666666666666666; 2097152.0; 171965.06666666668; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1377201143; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377201443; 1; 2599.999297; 5.199998594; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377201743; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377202043; 1; 2599.999297; 6.933331458666666; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 3.1333333333333333; 0.0; 0.4666666666666667 +1377202343; 1; 2599.999297; 10.399997188; 0.4; 2097152.0; 160779.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377202643; 1; 2599.999297; 3.466665729333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377202943; 1; 2599.999297; 8.666664323333334; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377203243; 1; 2599.999306; 18.571423614285717; 0.7142857142857143; 2097152.0; 101860.0; 0.0; 0.9230769230769231; 1.9230769230769231; 0.0 +1377203543; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377203844; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377204144; 1; 2599.999306; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 1.0; 0.0; 0.0 +1377204444; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377204744; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377205044; 1; 2599.999306; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377205344; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.1333333333333333; 2.466666666666667; 0.0 +1377205644; 1; 2599.999306; 5.199998612000001; 0.2; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377205944; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 170566.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377206244; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.2; 0.0 +1377206844; 1; 2599.999306; 8.666664353333335; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377207144; 1; 2599.999306; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377207444; 1; 2599.999306; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377208044; 1; 2599.999306; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377208344; 1; 2599.999306; 3.4666657413333337; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377208644; 1; 2599.999306; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377208944; 1; 2599.999306; 8.666664353333335; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377209245; 1; 2599.999306; 5.199998612000001; 0.2; 2097152.0; 134216.0; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377209845; 1; 2599.999306; 1.7333328706666669; 0.06666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1377210145; 1; 2599.999601; 25.99999601; 1.0; 2097152.0; 102059.73333333334; 0.0; 0.8571428571428571; 0.0; 0.0 +1377210445; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377210745; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 130021.6; 0.06666666666666667; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 +1377211045; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377211345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377211645; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377211945; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377212245; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377212545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377212845; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377213145; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 177557.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377213445; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.13333333333333333 +1377213745; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1377214045; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377214345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377214645; 1; 2599.999601; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377214945; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377215245; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 +1377215545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377215845; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377216145; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1377216445; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 99263.46666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377216745; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377217045; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377217345; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377217645; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 131419.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377217945; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109049.6; 0.06666666666666667; 1.4666666666666666; 0.0; 0.0 +1377218245; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377218545; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377218845; 1; 2599.999601; 12.133331471333332; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 1.0; 0.0; 0.0 +1377219145; 1; 2599.999601; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377219445; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377219745; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377220045; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 118837.33333333333; 0.13333333333333333; 2.4; 0.0; 0.5333333333333333 +1377220345; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 163576.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377220646; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 85282.13333333333; 0.06666666666666667; 1.7333333333333334; 0.0; 0.0 +1377220946; 1; 2599.999601; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377221246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377221546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377221846; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377222146; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377222446; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377222746; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377223046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377223346; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377223646; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.8666666666666667; 0.0; 0.4666666666666667 +1377223946; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 141206.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377224246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377224546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377224846; 1; 2599.999601; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377225146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377225446; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377225746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377226046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377226346; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377226646; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 11.733333333333333; 0.0; 0.0 +1377226946; 1; 2599.999601; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377227246; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 107652.0; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377227546; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 183148.53333333333; 0.0; 1.0; 0.0; 0.0 +1377227846; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377228146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377228446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377228746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377229046; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377229346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1377229646; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1377229946; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377230246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377230546; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377230846; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 83884.0; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377231146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377231446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377231746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232046; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232646; 1; 2599.999601; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377232946; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 170566.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377233246; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377233547; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 155187.2; 0.2; 6.933333333333334; 0.2; 0.13333333333333333 +1377233847; 1; 2599.999309; 15.166662635833333; 0.5833333333333334; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1377234147; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377234447; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377234747; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 171964.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377235047; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377235347; 1; 2599.999309; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1377235647; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1377235947; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377236247; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377236547; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377236847; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1377237147; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377237447; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377237747; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1377238047; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 +1377238347; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 146798.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377238647; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377238947; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377239247; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 150992.8; 0.0; 6.666666666666667; 0.3333333333333333; 0.13333333333333333 +1377239547; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.06666666666666667 +1377239847; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 121633.6; 0.0; 1.8; 0.0; 0.0 +1377240147; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 149595.46666666667; 0.0; 1.6666666666666667; 0.13333333333333333; 0.0 +1377240447; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377240747; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377241047; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377241347; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.4; 0.0; 0.0 +1377241647; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1377241947; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 192936.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377242247; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377242547; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377242848; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1377243148; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377243448; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377243748; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377244048; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377244347; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.06666666666666667; 0.0 +1377244647; 1; 2599.999309; 57.199984798; 2.2; 2097152.0; 736797.0666666667; 161.0; 21.866666666666667; 0.13333333333333333; 0.4 +1377244947; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 394262.4; 0.0; 2.466666666666667; 0.06666666666666667; 0.0 +1377245247; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 247461.6; 32.06666666666667; 4.8; 0.0; 0.4666666666666667 +1377245547; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 197130.4; 0.0; 2.4; 0.06666666666666667; 0.0 +1377245847; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1377246147; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 6.666666666666667; 0.3333333333333333; 0.2 +1377246447; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 1.4; 1.2666666666666666; 0.0 +1377246748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377247048; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377247348; 1; 2599.999309; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.6; 0.0; 0.0 +1377247648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377247948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377248248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377248548; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377248848; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377249148; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 176158.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377249448; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377249748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377250048; 1; 2599.999309; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377250348; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377250648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377250948; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1377251248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377251548; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377251848; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377252148; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.06666666666666667; 0.0 +1377252448; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1377252748; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377253048; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377253348; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377253648; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377253948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377254248; 1; 2599.999309; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377254548; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377254848; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377255148; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377255448; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377255748; 1; 2599.999309; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377256048; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377256348; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 1.2; 0.0; 0.0 +1377256648; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377256948; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377257249; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377257549; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377257849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377258149; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377258449; 1; 2599.999309; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377258749; 1; 2599.999309; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377259049; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 +1377259349; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377259649; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1377259949; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 155186.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1377260249; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 117438.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377260549; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 156585.86666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377260849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.8666666666666667; 0.0 +1377261149; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 82.06666666666666; 0.0 +1377261449; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377261749; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377262049; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377262349; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377262649; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377262949; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377263249; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377263549; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 197130.4; 0.0; 1.0; 0.0; 0.0 +1377263849; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377264149; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1377264449; 1; 2599.999309; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377264749; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 113244.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377265049; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377265349; 1; 2599.999309; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1377265649; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 116041.06666666667; 0.0; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 +1377265949; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377266249; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1377266549; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377266849; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 107651.73333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377267149; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 188742.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377267449; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377267749; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377268049; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377268349; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 90874.66666666667; 0.06666666666666667; 1.4; 0.06666666666666667; 0.13333333333333333 +1377268649; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377268949; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377269249; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377269549; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377269849; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377270149; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 11.933333333333334; 0.13333333333333333; 0.0 +1377270449; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 93670.4; 0.4666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377270749; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 137012.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377271049; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377271349; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377271649; 1; 2599.999309; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377271950; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377272250; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377272550; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 12.733333333333333; 16.733333333333334; 0.3333333333333333; 0.13333333333333333 +1377272850; 1; 2599.999309; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.6; 0.0; 0.0 +1377273150; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1377273450; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377273750; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377274050; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377274350; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 114642.4; 0.0; 1.0; 0.0; 0.0 +1377274650; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 144002.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377274950; 1; 2599.999309; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377275250; 1; 2599.999309; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377275550; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130021.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377275850; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 132818.4; 0.0; 1.2; 0.0; 0.0 +1377276150; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377276450; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377276750; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377277050; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377277350; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130021.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377277650; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 131420.26666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377277950; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 142604.0; 0.0; 0.8; 0.0; 0.0 +1377278250; 1; 2599.999309; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377278550; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377278850; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377279150; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1377279450; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 128624.26666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 +1377279750; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377280050; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377280350; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377280650; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377280950; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377281250; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 99262.93333333333; 0.0; 2.533333333333333; 0.13333333333333333; 0.4666666666666667 +1377281551; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 171964.0; 0.06666666666666667; 1.0666666666666667; 0.06666666666666667; 0.0 +1377281851; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 153790.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377282151; 1; 2599.999309; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1377282451; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377282751; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377283051; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377283351; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 178955.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377283651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377283951; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377284251; 1; 2599.999309; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.13333333333333333; 0.0 +1377284551; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 65708.26666666666; 0.0; 0.8; 0.0; 0.0 +1377284851; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377285151; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 159382.4; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377285451; 1; 2599.999309; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377285751; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377286051; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377286351; 1; 2599.999309; 38.13332319866666; 1.4666666666666666; 2097152.0; 430614.4; 161.53333333333333; 14.333333333333334; 0.0; 0.2 +1377286651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 394262.6666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1377286951; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 197129.86666666667; 31.8; 3.933333333333333; 0.0; 0.0 +1377287251; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 155187.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1377287551; 1; 2599.999309; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377287851; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377288151; 1; 2599.999309; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377288451; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 139808.8; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377288751; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 181750.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377289051; 1; 2599.999309; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.0; 0.0 +1377289351; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377289651; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377289951; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377290251; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377290551; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377290852; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1377291152; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377291452; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377291752; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 110448.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377292052; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 139808.26666666666; 0.0; 8.466666666666667; 0.3333333333333333; 0.6 +1377292352; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 177556.0; 0.0; 1.2; 0.0; 0.0 +1377292652; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 149596.26666666666; 0.0; 0.8; 0.0; 0.0 +1377292952; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377293251; 1; 2599.999309; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377293551; 1; 2599.999309; 55.46665192533332; 2.1333333333333333; 2097152.0; 268433.6; 161.0; 21.533333333333335; 0.06666666666666667; 0.4 +1377293851; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 717224.2666666667; 0.0; 2.6666666666666665; 0.0; 0.0 +1377294151; 1; 2599.999309; 12.133330108666664; 0.4666666666666666; 2097152.0; 317366.93333333335; 31.8; 3.6; 0.0; 0.0 +1377294451; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 212508.53333333333; 0.0; 2.1333333333333333; 0.0; 0.0 +1377294751; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 121633.6; 0.0; 1.8; 0.0; 0.0 +1377295051; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1377295352; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377295652; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1377295952; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 153789.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377296252; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8; 0.0; 0.0 +1377296552; 1; 2599.999309; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377296852; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377297152; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1377297452; 1; 2599.999309; 13.86666298133333; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1377297752; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377298052; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377298352; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377298652; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377298952; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377299252; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 127225.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377299552; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 166371.73333333334; 0.0; 0.8; 0.0; 0.0 +1377299852; 1; 2599.999309; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377300152; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377300452; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377300752; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377301052; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.26666666666666666; 0.0 +1377301352; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377301652; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377301952; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377302252; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377302552; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377302852; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377303152; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 188741.6; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377303452; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377303752; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377304052; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377304352; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 157984.26666666666; 0.06666666666666667; 1.4; 0.0; 0.0 +1377304652; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377304953; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 1.2; 0.0; 0.0 +1377305253; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1377305553; 1; 2599.999309; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377305853; 1; 2599.999309; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377306153; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377306453; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377306753; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377307053; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 120234.66666666667; 0.0; 0.8; 0.0; 0.0 +1377307353; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1377307653; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377307953; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377308253; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377308553; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377308853; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377309153; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377309453; 1; 2599.999309; 0.0; 0.0; 2097152.0; 149596.0; 0.0; 0.6; 0.0; 0.0 +1377309753; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 114642.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377310053; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 121633.33333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377310353; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 171965.06666666668; 0.0; 1.2; 0.0; 0.0 +1377310653; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377310953; 1; 2599.999309; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1377311253; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 +1377311553; 1; 2599.999309; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377311853; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377312153; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377312453; 1; 2599.999309; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377312753; 1; 2599.999309; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6; 0.0; 0.0 +1377313053; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377313353; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377313653; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 162178.13333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1377313953; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 164974.4; 0.0; 11.6; 0.0; 0.0 +1377314253; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377314553; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377314853; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377315154; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377315454; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377315754; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 139807.73333333334; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1377316054; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1377316354; 1; 2599.999309; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.6; 0.0; 0.0 +1377316654; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 +1377316954; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377317254; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 124429.6; 0.13333333333333333; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377317554; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 180353.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377317854; 1; 2599.999309; 0.0; 0.0; 2097152.0; 144003.2; 0.0; 0.8; 0.0; 0.0 +1377318154; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377318454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377318754; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377319054; 1; 2599.999309; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377319354; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1377319654; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377319954; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377320254; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377320554; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377320854; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.06666666666666667; 2.0; 0.06666666666666667; 0.4666666666666667 +1377321154; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 171963.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377321454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377321754; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377322054; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 128624.26666666666; 0.0; 6.6; 0.26666666666666666; 0.13333333333333333 +1377322354; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.6; 0.0; 0.0 +1377322655; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1377322955; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377323255; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1377323555; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377323855; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377324155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377324455; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 109050.4; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377324755; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377325055; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377325355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377325655; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377325955; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.06666666666666667 +1377326255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 146799.2; 0.0; 1.9333333333333333; 0.0; 0.0 +1377326554; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 134216.8; 0.0; 1.7333333333333334; 0.0; 0.0 +1377326854; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1377327154; 1; 2599.999309; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377327454; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377327755; 1; 2599.999309; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377328055; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 134216.8; 0.06666666666666667; 8.6; 0.26666666666666666; 0.6 +1377328355; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 146800.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377328655; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377328955; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377329255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377329555; 1; 2599.999309; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377329855; 1; 2599.999309; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377330155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1377330455; 1; 2599.999309; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1377330755; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377331055; 1; 2599.999309; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377331355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377331655; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.06666666666666667; 1.9333333333333333; 0.13333333333333333; 0.5333333333333333 +1377331955; 1; 2599.999309; 12.133330108666664; 0.4666666666666666; 2097152.0; 176158.4; 0.0; 1.0; 0.0; 0.0 +1377332255; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377332555; 1; 2599.999309; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377332855; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377333155; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377333455; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377333755; 1; 2599.999309; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377334055; 1; 2599.999309; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377334355; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 132818.66666666666; 12.733333333333333; 14.066666666666666; 0.3333333333333333; 0.2 +1377334655; 1; 2599.999309; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1377334955; 1; 2599.999309; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377335255; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 2.6666666666666665; 0.0; 0.4666666666666667 +1377335555; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 150993.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1377335855; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377336155; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377336455; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377336755; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377337055; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377337355; 1; 2599.999309; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377337655; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377337955; 1; 2599.999309; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377338255; 1; 2599.999309; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377338555; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377338855; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377339156; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377339456; 1; 2599.999309; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1377339756; 1; 2599.999309; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377340056; 1; 2599.999309; 0.0; 0.0; 2097152.0; 57319.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377340356; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377340656; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377340956; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377341256; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377341556; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377341856; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377342156; 1; 2599.999309; 1.7333328726666664; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377342456; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 107652.0; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377342756; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 180353.6; 0.0; 1.0; 0.0; 0.0 +1377343056; 1; 2599.999309; 64.13331628866666; 2.466666666666667; 2097152.0; 328552.5333333333; 161.06666666666666; 21.533333333333335; 0.2; 0.4 +1377343356; 1; 2599.999309; 15.599995854; 0.6; 2097152.0; 658504.0; 0.0; 2.533333333333333; 0.0; 0.0 +1377343656; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 268433.6; 31.8; 3.7333333333333334; 0.0; 0.0 +1377343956; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 167771.2; 0.0; 2.1333333333333333; 0.0; 0.0 +1377344256; 1; 2599.999309; 10.399997235999999; 0.4; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1377344556; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 1.0; 0.0; 0.0 +1377344856; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377345156; 1; 2599.999309; 3.4666657453333327; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377345456; 1; 2599.999309; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377345756; 1; 2599.999309; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377346056; 1; 2599.999309; 5.1999986179999995; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1377346356; 1; 2599.999309; 8.666664363333334; 0.33333333333333337; 2097152.0; 159381.6; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377346656; 1; 2599.999309; 6.933331490666665; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377346956; 1; 2599.999309; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377347256; 1; 2599.999601; 11.999998158461537; 0.4615384615384615; 2097152.0; 79044.30769230769; 0.0; 0.9166666666666666; 0.0; 0.0 +1377347556; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 107652.26666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 +1377347856; 1; 2599.99931; 25.9999931; 1.0; 2097152.0; 116840.0; 0.0; 0.8461538461538461; 0.0; 0.0 +1377348156; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377348456; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377348757; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377349057; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377349357; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1377349657; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 142605.06666666668; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377349957; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 162178.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377350257; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377350557; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377350857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377351157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377351457; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377351757; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 139808.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377352057; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377352357; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377352657; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377352957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377353257; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377353557; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 169169.33333333334; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377353857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377354157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377354457; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377354757; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 72698.93333333333; 0.06666666666666667; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1377355057; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377355357; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.8; 0.26666666666666666; 0.0 +1377355657; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1377355957; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377356257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377356557; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377356857; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 2.2; 0.0; 0.4666666666666667 +1377357157; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 146798.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1377357457; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 11.933333333333334; 0.0; 0.0 +1377357757; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377358057; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377358357; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377358658; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377358957; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1377359257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377359557; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377359857; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377360157; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1377360457; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377360757; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377361057; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377361357; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377361657; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377361957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377362257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1377362557; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377362857; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 +1377363157; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377363457; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377363757; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.0; 0.0 +1377364057; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 103457.06666666667; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1377364357; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 164974.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377364657; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377364957; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377365257; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377365558; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377365858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377366158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377366458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377366758; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 145401.06666666668; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 +1377367058; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377367358; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377367658; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377367958; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377368258; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377368558; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377368858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.5333333333333333; 0.0; 0.0 +1377369158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377369458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.6666666666666666; 0.26666666666666666; 0.0 +1377369758; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.9333333333333333; 0.0 +1377370058; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377370358; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377370658; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377370958; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 +1377371258; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 86680.26666666666; 0.0; 2.4; 0.0; 0.4666666666666667 +1377371558; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 174761.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 +1377371858; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377372158; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377372458; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377372758; 1; 2599.99931; 41.59998896; 1.6; 2097152.0; 369097.3333333333; 161.0; 14.266666666666667; 0.0; 0.2 +1377373058; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 426419.2; 0.0; 7.2; 0.2; 0.13333333333333333 +1377373358; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 208315.46666666667; 31.8; 3.4; 0.06666666666666667; 0.0 +1377373658; 1; 2599.99931; 0.0; 0.0; 2097152.0; 178954.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377373958; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377374259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1377374559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377374859; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377375159; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.8; 0.0; 0.0 +1377375459; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377375759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377376059; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377376359; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377376659; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377376959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377377259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377377559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377377859; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377378159; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96467.2; 0.6666666666666666; 1.5333333333333334; 0.0; 0.0 +1377378459; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 100661.33333333333; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377378759; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159381.86666666667; 0.0; 0.8; 0.0; 0.0 +1377379059; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377379359; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 75495.2; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 +1377379659; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377379959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.5333333333333334; 0.0; 0.0 +1377380259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377380559; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377380859; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377381159; 1; 2599.99931; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 0.8; 0.0; 0.0 +1377381459; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377381759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377382059; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99262.66666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377382359; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 184547.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377382659; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377382959; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377383259; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377383559; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 90874.66666666667; 0.0; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 +1377383859; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377384159; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377384459; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377384759; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377385059; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377385360; 1; 2599.99931; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 0.6; 0.0; 0.0 +1377385660; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138411.2; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377385960; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377386260; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377386560; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377386860; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8; 0.0; 0.0 +1377387160; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 0.8; 0.0; 0.0 +1377387460; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377387760; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377388060; 1; 2599.99931; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.0; 0.0; 0.0 +1377388360; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377388660; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377388960; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1377389260; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 130021.86666666667; 0.0; 2.8; 0.0; 0.4666666666666667 +1377389560; 1; 2599.99931; 0.0; 0.0; 2097152.0; 178954.13333333333; 0.0; 0.8; 0.0; 0.0 +1377389860; 1; 2599.99931; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 +1377390160; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377390460; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377390760; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 61513.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1377391060; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377391360; 1; 2599.99931; 57.19998482000001; 2.2; 2097152.0; 357911.73333333334; 161.0; 21.733333333333334; 0.06666666666666667; 0.3333333333333333 +1377391660; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 665494.4; 0.0; 2.2666666666666666; 0.0; 0.0 +1377391961; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 247461.06666666668; 44.6; 15.8; 0.3333333333333333; 0.2 +1377392261; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 178954.66666666666; 0.0; 2.466666666666667; 0.0; 0.0 +1377392561; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1377392861; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.33333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377393161; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 174760.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377393461; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1377393761; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 0.6; 0.0; 0.0 +1377394061; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1377394361; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377394661; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1377394961; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377395261; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1377395561; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6; 0.0; 0.0 +1377395861; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377396161; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377396461; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 120235.46666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377396761; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 162178.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377397061; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377397361; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.2; 0.0; 0.0 +1377397661; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377397961; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377398261; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377398561; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 148197.06666666668; 0.0; 7.2; 0.2; 0.13333333333333333 +1377398861; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377399161; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377399461; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377399761; 1; 2599.99931; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377400061; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 71300.8; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1377400362; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377400662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377400962; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 11.733333333333333; 0.0; 0.0 +1377401262; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377401562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377401862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377402162; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377402462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377402762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377403062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377403362; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377403662; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 148197.33333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377403962; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 205519.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377404262; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1377404562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377404862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377405162; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377405462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377405762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1377406062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377406362; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377406662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377406962; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377407262; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 83884.0; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1377407562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.06666666666666667; 1.0666666666666667; 0.0; 0.0 +1377407862; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377408162; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377408462; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377408762; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377409062; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377409362; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377409662; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377409962; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1377410262; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377410562; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377410862; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 159382.4; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.6 +1377411162; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377411462; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1377411763; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377412063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377412363; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1377412663; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 138410.4; 0.0; 2.066666666666667; 0.0; 0.0 +1377412963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.4666666666666666; 0.0; 0.0 +1377413263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377413563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 61513.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377413863; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377414163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377414463; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1377414763; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 176158.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377415063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377415363; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377415663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377415963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377416263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377416563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.2; 0.0; 0.0 +1377416863; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1377417163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377417463; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377417763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377418063; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 90874.66666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377418363; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377418663; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377418963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104855.2; 0.0; 0.8; 0.0; 0.0 +1377419263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377419564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377419864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377420164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377420464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377420764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1377421064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377421364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377421664; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 125827.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377421964; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 205519.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377422264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377422564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.8; 0.0; 0.0 +1377422864; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377423164; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377423464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377424064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377424364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.6; 0.0; 0.0 +1377424663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377424963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377425263; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.06666666666666667; 2.933333333333333; 0.0; 0.4666666666666667 +1377425563; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377425863; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377426163; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377426463; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1377426763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377427063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377427363; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377427663; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377427963; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377428263; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377428563; 1; 2599.99931; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8; 0.0; 0.0 +1377428863; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 81087.73333333334; 0.06666666666666667; 2.2; 0.06666666666666667; 0.4666666666666667 +1377429163; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377429463; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377429763; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377430063; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377430363; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377430664; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377430964; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377431264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.2; 0.0; 0.0 +1377431564; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377431864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377432164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1377432464; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377432764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.0; 0.0 +1377433064; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 156585.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377433364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377433664; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377433964; 1; 2599.99931; 0.0; 0.0; 2097152.0; 166372.26666666666; 0.0; 0.8; 0.0; 0.0 +1377434264; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125826.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377434564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377434864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377435164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1377435464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377435764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377436064; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377436364; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 195731.46666666667; 0.0; 1.2; 0.0; 0.0 +1377436664; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.6; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377436964; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377437264; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 +1377437564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377437864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377438164; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377438464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377438764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377439064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377439364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377439664; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138411.2; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1377439964; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 157984.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377440264; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377440564; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377440864; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377441164; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.06666666666666667; 0.06666666666666667 +1377441464; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 0.8; 0.0; 0.0 +1377441764; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1377442064; 1; 2599.99931; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377442364; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377442665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377442965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377443265; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1377443565; 1; 2599.99931; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377443865; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377444165; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1377444465; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1377444765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.0; 11.533333333333333; 0.0; 0.0 +1377445065; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377445365; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377445665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377445965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377446265; 1; 2599.99931; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377446565; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377446865; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 144002.4; 0.0; 1.9333333333333333; 0.0; 0.4666666666666667 +1377447165; 1; 2599.99931; 62.39998344000001; 2.4; 2097152.0; 454381.6; 161.0; 21.733333333333334; 0.0; 0.4 +1377447465; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 671087.2; 0.0; 2.533333333333333; 0.0; 0.0 +1377447765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 264238.93333333335; 31.8; 3.3333333333333335; 0.0; 0.0 +1377448065; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 150993.33333333334; 0.0; 2.2666666666666666; 0.0; 0.0 +1377448365; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1377448665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1377448965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1377449265; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159382.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377449565; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.6; 0.0; 0.0 +1377449865; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377450165; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 130021.86666666667; 12.733333333333333; 13.333333333333334; 0.3333333333333333; 0.13333333333333333 +1377450465; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 233481.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1377450765; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 194334.66666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1377451065; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377451365; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1377451665; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377451965; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377452265; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377452566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377452866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1377453166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377453466; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377453766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377454066; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.4; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1377454366; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 171964.53333333333; 0.0; 0.8; 0.0; 0.0 +1377454666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377454966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377455266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377455566; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377455866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377456166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377456466; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377456766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377457066; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 141207.46666666667; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377457366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377457666; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377457966; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 174760.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377458266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377458566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377458866; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377459166; 1; 2599.99931; 36.39999034; 1.4; 2097152.0; 297793.6; 161.0; 14.333333333333334; 0.0; 0.13333333333333333 +1377459466; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 466963.2; 0.0; 1.0; 0.0; 0.0 +1377459766; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 211110.66666666666; 31.8; 3.8; 0.0; 0.0 +1377460066; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 169169.06666666668; 0.0; 1.0; 0.0; 0.0 +1377460366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377460666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377460966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1377461266; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 120234.66666666667; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1377461566; 1; 2599.99931; 0.0; 0.0; 2097152.0; 173362.4; 0.0; 0.8; 0.0; 0.0 +1377461866; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 0.5333333333333333; 0.0; 0.0 +1377462166; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377462466; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 76893.33333333333; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 +1377462766; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377463066; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377463366; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377463666; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377463966; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377464266; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377464566; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 +1377464866; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 2.2; 0.0; 0.4666666666666667 +1377465167; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1377465467; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377465767; 1; 2599.99931; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377466067; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1377466367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377466667; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377466967; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377467267; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104855.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377467567; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377467867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377468167; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377468467; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377468767; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 144002.13333333333; 0.0; 0.6; 0.0; 0.0 +1377469067; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1377469367; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 137013.06666666668; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377469667; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377469967; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.4; 0.06666666666666667; 0.06666666666666667 +1377470267; 1; 2599.99931; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 +1377470567; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377470867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377471167; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377471467; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377471767; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377472067; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128624.26666666666; 0.2; 2.8; 0.0; 0.4666666666666667 +1377472367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377472667; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377472967; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377473267; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377473567; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377473867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377474167; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.0; 0.0; 0.0 +1377474467; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1377474767; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1377475067; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377475367; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377475667; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96466.93333333333; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377475967; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 176158.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377476267; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377476567; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377476867; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377477168; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1377477468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377477768; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377478068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377478368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377478668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377478968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377479268; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377479568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377479868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377480168; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377480468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377480768; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377481068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377481368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377481668; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377481968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377482268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377482568; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377482868; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377483168; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 145401.86666666667; 0.0; 1.0; 0.0; 0.0 +1377483468; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377483768; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377484068; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377484368; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377484668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377484968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377485268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377485568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 160780.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377485868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377486168; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 85282.13333333333; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 +1377486468; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.2; 0.0; 0.4666666666666667 +1377486768; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 190139.73333333334; 0.0; 0.8; 0.0; 0.0 +1377487068; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377487368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111845.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377487668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377487968; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377488269; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377488569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377488869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1377489169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377489469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377489769; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1377490068; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1377490368; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 180353.6; 0.0; 1.0; 0.0; 0.0 +1377490668; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.8; 0.0; 0.0 +1377490968; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377491268; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377491568; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377491868; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377492168; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377492468; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.0; 0.0 +1377492768; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377493068; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377493368; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377493668; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377493968; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 176157.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377494268; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377494569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377494869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377495169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377495469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377495769; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377496069; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377496369; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377496669; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377496969; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1377497269; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107651.46666666666; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377497569; 1; 2599.99931; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377497869; 1; 2599.99931; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377498169; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377498469; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377498769; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 61513.86666666667; 0.06666666666666667; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1377499069; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 58717.6; 0.0; 1.8; 0.0; 0.0 +1377499369; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.5333333333333334; 0.0; 0.0 +1377499669; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 6.8; 0.2; 0.13333333333333333 +1377499969; 1; 2599.99931; 60.666650566666675; 2.3333333333333335; 2097152.0; 359311.4666666667; 161.0; 21.733333333333334; 0.06666666666666667; 0.4 +1377500269; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 654309.6; 0.0; 2.6; 0.0; 0.0 +1377500569; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 310376.8; 31.8; 3.4; 0.0; 0.0 +1377500869; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 192935.2; 0.0; 3.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377501169; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 192936.0; 0.0; 1.8666666666666667; 0.0; 0.0 +1377501470; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377501770; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377502070; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377502370; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377502670; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1377502970; 1; 2599.99931; 36.39999034; 1.4; 2097152.0; 92272.8; 0.0; 1.2; 104.86666666666666; 0.0 +1377503270; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377503570; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377503870; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.4; 0.0 +1377504170; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377504470; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99262.66666666667; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377504770; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 0.8; 0.0; 0.0 +1377505070; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1377505370; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1377505670; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377505970; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377506270; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377506570; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377506870; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377507170; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377507470; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377507770; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1377508070; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 142605.6; 0.13333333333333333; 2.466666666666667; 0.0; 0.4666666666666667 +1377508370; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 142605.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377508670; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377508970; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377509270; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377509570; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1377509870; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377510170; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377510470; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377510771; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377511071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377511371; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 152391.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377511671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.06666666666666667; 2.2666666666666666; 0.13333333333333333; 0.4666666666666667 +1377511971; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 156586.13333333333; 12.733333333333333; 12.933333333333334; 0.4666666666666667; 0.2 +1377512271; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377512571; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1377512871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377513171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377513471; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 1.4; 0.0; 0.0 +1377513771; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377514071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377515571; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377515871; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1377516171; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377516471; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377516771; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 3.1333333333333333; 0.0 +1377517071; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377517371; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377517671; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377517971; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377518271; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1377518571; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6; 0.0; 0.0 +1377518871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377519171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 169168.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377519472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377519772; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377520072; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377520372; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377520672; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377520972; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377521272; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377521572; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 134216.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377521872; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377522172; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 71300.8; 0.0; 0.6; 0.0; 0.0 +1377522472; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377522771; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 204121.06666666668; 0.0; 0.8; 0.0; 0.0 +1377523071; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377523371; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377523671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377523971; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377524271; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.6666666666666667; 0.0; 0.0 +1377524571; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 100661.6; 0.0; 7.4; 0.6; 0.2 +1377524871; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377525171; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377525471; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1377525771; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377526071; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1377526371; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377526671; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377526971; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377527271; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377527571; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1377527871; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377528171; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377528472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377528772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.5333333333333333; 0.0 +1377529072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377529372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377529672; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 150992.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377529972; 1; 2599.99931; 0.0; 0.0; 2097152.0; 171965.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377530272; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377530572; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 6.6; 0.2; 0.13333333333333333 +1377530872; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377531172; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377531472; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377531772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 150994.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377532072; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 12.066666666666666; 0.06666666666666667; 0.0 +1377532372; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 1.8; 0.0 +1377532672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 2.2666666666666666; 0.0 +1377532972; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377533272; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 121633.6; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1377533572; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377533872; 1; 2599.99931; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377534172; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 4.2; 0.0 +1377534472; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377534772; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377535072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377535372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377535672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377535972; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1377536272; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377536572; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377536872; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.46666666666; 0.13333333333333333; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377537172; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 155188.0; 0.0; 7.2; 0.2; 0.13333333333333333 +1377537472; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377537772; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377538072; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377538372; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 2.2666666666666666; 0.0 +1377538672; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377538972; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377539272; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377539572; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 0.6666666666666666; 0.0; 0.0 +1377539873; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 142604.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377540173; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377540473; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 142604.8; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377540773; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 169169.33333333334; 0.0; 0.8; 0.0; 0.0 +1377541073; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377541373; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377541673; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377541973; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 111846.13333333333; 0.0; 0.8; 0.6; 0.0 +1377542273; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 +1377542573; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8; 3.2; 0.0 +1377542873; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1377543173; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377543473; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 173363.2; 0.0; 6.8; 0.2; 0.13333333333333333 +1377543773; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377544073; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377544373; 1; 2599.99931; 0.0; 0.0; 2097152.0; 156585.33333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377544673; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377544973; 1; 2599.99931; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8; 0.0; 0.0 +1377545273; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377545573; 1; 2599.99931; 50.26665332666667; 1.9333333333333333; 2097152.0; 233481.6; 161.2; 14.6; 0.06666666666666667; 0.2 +1377545873; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 486537.06666666665; 0.0; 1.2666666666666666; 0.0; 0.0 +1377546173; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 208314.66666666666; 31.8; 3.6666666666666665; 0.0; 0.0 +1377546473; 1; 2599.99931; 0.0; 0.0; 2097152.0; 201324.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377546773; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377547073; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377547373; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377547673; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377547973; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 190140.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377548273; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377548573; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 1.8666666666666667; 0.0 +1377548873; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 7.333333333333333; 0.2; 0.13333333333333333 +1377549173; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1377549473; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377549774; 1; 2599.99931; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1377550074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377550374; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377550674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377550974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377551274; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 132817.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377551574; 1; 2599.99931; 60.666650566666675; 2.3333333333333335; 2097152.0; 423622.93333333335; 161.0; 21.6; 0.5333333333333333; 0.4 +1377551874; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 608172.0; 0.0; 2.533333333333333; 0.0; 0.0 +1377552174; 1; 2599.99931; 13.866662986666668; 0.5333333333333333; 2097152.0; 232082.13333333333; 31.8; 3.533333333333333; 0.0; 0.0 +1377552474; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 149595.2; 0.0; 2.533333333333333; 0.0; 0.0 +1377552774; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 116041.06666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377553074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377553374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377553674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 124429.33333333333; 0.0; 1.2; 0.0; 0.0 +1377553974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377554274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377554574; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 1.5333333333333334; 0.0 +1377554874; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 2.4; 0.0; 0.4666666666666667 +1377555174; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.0; 0.0; 1.2; 0.06666666666666667; 0.0 +1377555474; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377555774; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 99263.46666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377556074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377556374; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 149595.46666666667; 0.06666666666666667; 1.8; 0.13333333333333333; 0.06666666666666667 +1377556674; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377556974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377557274; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377557574; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377557874; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 1.9333333333333333; 0.0; 0.0 +1377558174; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377558474; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106253.6; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377558774; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 157984.0; 0.0; 0.8; 0.0; 0.0 +1377559074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377559374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377559674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377559974; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377560274; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377560574; 1; 2599.99931; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377560874; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1377561174; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377561474; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377561774; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1377562074; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128623.73333333334; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377562374; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 148197.06666666668; 0.0; 0.7333333333333333; 0.0; 0.0 +1377562674; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377562974; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377563274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377563574; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1377563874; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377564174; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377564474; 1; 2599.99931; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377564774; 1; 2599.99931; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377565074; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377565374; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377565674; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 123031.2; 0.06666666666666667; 2.0; 0.06666666666666667; 0.4666666666666667 +1377565974; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 177557.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1377566274; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377566574; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377566874; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377567175; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377567475; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377567775; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377568075; 1; 2599.99931; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377568375; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377568675; 1; 2599.99931; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377568975; 1; 2599.99931; 0.0; 0.0; 2097152.0; 148198.13333333333; 0.0; 1.2; 0.0; 0.0 +1377569275; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102059.73333333334; 0.2; 2.066666666666667; 0.0; 0.4666666666666667 +1377569575; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 164974.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1377569875; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377570175; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377570475; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377570775; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377571075; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377571375; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377571675; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 96466.93333333333; 0.0; 1.0; 0.0; 0.0 +1377571975; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377572275; 1; 2599.99931; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377572575; 1; 2599.99931; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377572875; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 162177.86666666667; 12.8; 14.466666666666667; 0.4; 0.6 +1377573175; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 152391.73333333334; 0.0; 1.4; 0.0; 0.0 +1377573475; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377573776; 1; 2599.99931; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377574076; 1; 2599.99931; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377574376; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377574676; 1; 2599.99931; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377574976; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377575276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377575576; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 128624.26666666666; 0.0; 11.8; 0.0; 0.0 +1377575876; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377576176; 1; 2599.99931; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1377576476; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 102058.66666666667; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377576776; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 170566.93333333332; 0.0; 0.7333333333333333; 0.0; 0.0 +1377577076; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1377577376; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1377577676; 1; 2599.99931; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377577976; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377578276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377578576; 1; 2599.99931; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377578876; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 97865.33333333333; 0.0; 7.066666666666666; 0.4; 0.13333333333333333 +1377579176; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 148196.53333333333; 0.0; 0.8; 0.0; 0.0 +1377579476; 1; 2599.99931; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377579776; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377580076; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113243.73333333334; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1377580376; 1; 2599.99931; 0.0; 0.0; 2097152.0; 198528.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377580676; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377580976; 1; 2599.99931; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377581276; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377581576; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377581876; 1; 2599.99931; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377582176; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377582476; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377582776; 1; 2599.99931; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377583077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 107651.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377583377; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 65708.26666666666; 0.06666666666666667; 1.2; 0.0; 0.0 +1377583677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 92272.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377583977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377584277; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377584577; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377584877; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1377585177; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.8666666666666667; 0.26666666666666666; 0.06666666666666667 +1377585477; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 145401.06666666668; 0.0; 1.5333333333333334; 0.0; 0.0 +1377585777; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377586077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377586377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377586677; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1377586977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377587277; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.0; 0.0; 2.2; 0.2; 0.4666666666666667 +1377587577; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 170566.13333333333; 0.0; 0.6; 0.26666666666666666; 0.0 +1377587877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 137013.06666666668; 0.0; 0.6; 0.0; 0.0 +1377588177; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 159382.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377588477; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 132818.13333333333; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1377588776; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 148198.13333333333; 0.0; 0.6; 0.13333333333333333; 0.0 +1377589076; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377589376; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1377589676; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1377589976; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 5.2; 0.0 +1377590277; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 118837.33333333333; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1377590577; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377590877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 113244.8; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377591177; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 181751.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377591477; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.6; 0.13333333333333333; 0.0 +1377591777; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377592077; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1377592377; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377592677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377592977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 149595.46666666667; 0.0; 0.6; 0.0; 0.0 +1377593277; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377593577; 1; 2599.99931; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377593877; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377594177; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.5333333333333333; 0.06666666666666667; 0.0 +1377594477; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 93670.93333333333; 0.2; 2.066666666666667; 0.13333333333333333; 0.4666666666666667 +1377594777; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.5333333333333333; 0.0 +1377595077; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 107652.26666666666; 0.0; 0.6; 9.4; 0.0 +1377595377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377595677; 1; 2599.99931; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377595977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377596277; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 106254.13333333333; 0.0; 6.8; 0.3333333333333333; 0.13333333333333333 +1377596577; 1; 2599.99931; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377596877; 1; 2599.99931; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377597177; 1; 2599.99931; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.8; 0.0; 0.0 +1377597477; 1; 2599.99931; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377597777; 1; 2599.99931; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377598077; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 109050.4; 0.0; 2.4; 0.0; 0.5333333333333333 +1377598377; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 137012.26666666666; 0.06666666666666667; 0.9333333333333333; 1.2666666666666666; 0.0 +1377598677; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1377598977; 1; 2599.99931; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6; 0.0; 0.0 +1377599277; 1; 2599.99931; 64.13331631333334; 2.466666666666667; 2097152.0; 603977.0666666667; 161.0; 22.8; 0.0; 0.4 +1377599577; 1; 2599.99931; 12.133330113333335; 0.4666666666666666; 2097152.0; 394262.4; 0.0; 4.8; 0.0; 0.0 +1377599877; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 190140.0; 31.8; 3.533333333333333; 0.0; 0.0 +1377600177; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 156586.13333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.0 +1377600477; 1; 2599.99931; 6.933331493333334; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.5333333333333334; 0.0; 0.0 +1377600777; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377601077; 1; 2599.99931; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377601377; 1; 2599.99931; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377601677; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 2.0; 0.0; 0.4666666666666667 +1377601977; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377602278; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 113244.8; 0.0; 1.8666666666666667; 0.0; 0.0 +1377602578; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377602878; 1; 2599.99931; 8.66666436666667; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377603178; 1; 2599.99931; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377603478; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377603778; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377604078; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1377604378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 1.1333333333333333; 0.0 +1377604678; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 2.6666666666666665; 0.0 +1377604978; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377605278; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 121632.8; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1377605578; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 187343.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377605878; 1; 2599.99931; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377606178; 1; 2599.99931; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377606478; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377606778; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377607078; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377607378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377607678; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 74097.06666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1377607978; 1; 2599.99931; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377608278; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.7333333333333333; 0.0 +1377608578; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377608878; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 138410.4; 0.06666666666666667; 2.2666666666666666; 80.73333333333333; 0.4666666666666667 +1377609178; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 170566.66666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377609478; 1; 2599.99931; 5.19999862; 0.2; 2097152.0; 138410.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377609778; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377610078; 1; 2599.99931; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377610378; 1; 2599.99931; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377610678; 1; 2599.99931; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377610978; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377611278; 1; 2599.99931; 1.7333328733333335; 0.06666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377611578; 1; 2599.99931; 3.466665746666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377611878; 1; 2599.99931; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377612178; 1; 2599.99931; 10.39999724; 0.4; 2097152.0; 142604.8; 0.0; 0.8; 10.6; 0.0 +1377612478; 1; 2599.998991; 40.44442874888888; 1.5555555555555554; 2097152.0; 130486.66666666667; 0.0; 3.875; 0.125; 0.875 +1377612778; 1; 2599.998991; 19.066659267333332; 0.7333333333333333; 2097152.0; 201324.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377613078; 1; 2599.998991; 17.33332660666667; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377613378; 1; 2599.999334; 25.99999334; 1.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1377613678; 1; 2599.999334; 10.399997336000002; 0.4; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377613978; 1; 2599.999334; 17.333328893333338; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.13333333333333333; 0.13333333333333333 +1377614279; 1; 2599.999334; 8.666664446666669; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377614579; 1; 2599.999334; 3.4666657786666666; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1377614879; 1; 2599.999602; 34.666661360000006; 1.3333333333333335; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1377615179; 1; 2599.999602; 17.333330680000003; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377615479; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377615779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377616079; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 150993.6; 0.06666666666666667; 2.8; 0.06666666666666667; 0.4666666666666667 +1377616379; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 184547.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1377616679; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377616979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377617279; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377617579; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377617879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1377618179; 1; 2599.999602; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377618479; 1; 2599.999602; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.2; 0.0; 0.0 +1377618779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377619079; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377619379; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 11.733333333333333; 0.0; 0.0 +1377619679; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1377619979; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 153789.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377620279; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377620579; 1; 2599.999602; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377620879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377621179; 1; 2599.999602; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377621479; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 90874.66666666667; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1377621779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377622079; 1; 2599.999602; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377622379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377622679; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377622979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377623279; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 121633.6; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377623579; 1; 2599.999602; 0.0; 0.0; 2097152.0; 171964.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377623879; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377624179; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1377624479; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377624779; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377625079; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377625379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377625679; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 150994.4; 0.0; 0.9333333333333333; 0.6; 0.0 +1377625979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8; 0.0; 0.0 +1377626279; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377626579; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377626879; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377627179; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1377627479; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159381.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377627779; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 113244.8; 0.0; 7.266666666666667; 0.26666666666666666; 0.2 +1377628079; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377628379; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377628679; 1; 2599.999602; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377628979; 1; 2599.999602; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1377629279; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377629580; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377629880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377630180; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377630480; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1377630780; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377631080; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377631380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377631680; 1; 2599.999602; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377631980; 1; 2599.999602; 39.866660564; 1.5333333333333334; 2097152.0; 181751.73333333334; 161.06666666666666; 14.266666666666667; 0.13333333333333333; 0.2 +1377632280; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 536869.6; 0.0; 1.2; 0.0; 0.0 +1377632580; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 184548.0; 31.8; 3.8; 0.0; 0.0 +1377632880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 213908.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377633180; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1377633480; 1; 2599.999602; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377633780; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377634080; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 131419.46666666667; 0.06666666666666667; 2.933333333333333; 0.0; 0.5333333333333333 +1377634380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 176159.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377634680; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 171964.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1377634980; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 1.0; 0.0; 0.0 +1377635280; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1377635580; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377635880; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377636180; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377636480; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377636780; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377637080; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377637380; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377637680; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377637980; 1; 2599.999602; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 1.0; 0.0; 0.0 +1377638280; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377638581; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 +1377638881; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377639181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377639481; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377639781; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377640081; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377640381; 1; 2599.999602; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1377640681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377640981; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 81087.73333333334; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377641281; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377641581; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 171963.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377641881; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377642181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377642481; 1; 2599.999602; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377642781; 1; 2599.999602; 10.399998407999998; 0.4; 2097152.0; 109050.4; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.13333333333333333 +1377643081; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377643381; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377643681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377643981; 1; 2599.999602; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1377644281; 1; 2599.999602; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377644581; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377644881; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1377645181; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 152392.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377645481; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1377645781; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377646081; 1; 2599.999602; 0.0; 0.0; 2097152.0; 60115.73333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377646381; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 1.0; 0.0; 0.0 +1377646681; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377646981; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 85282.13333333333; 0.0; 7.733333333333333; 0.2; 0.13333333333333333 +1377647281; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1377647581; 1; 2599.999602; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377647881; 1; 2599.999602; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377648181; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1377648481; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 102059.73333333334; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377648781; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 160779.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377649081; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 1.1333333333333333; 0.0 +1377649381; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377649681; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377649982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 +1377650282; 1; 2599.999602; 60.66665738; 2.3333333333333335; 2097152.0; 592792.2666666667; 161.06666666666666; 21.8; 0.06666666666666667; 0.4 +1377650582; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 596986.9333333333; 0.0; 2.8666666666666667; 0.06666666666666667; 0.0 +1377650882; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 241868.8; 31.8; 3.533333333333333; 0.13333333333333333; 0.0 +1377651182; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 171964.53333333333; 0.0; 2.2666666666666666; 0.06666666666666667; 0.0 +1377651482; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 +1377651782; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377652082; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 82485.33333333333; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1377652382; 1; 2599.999602; 0.0; 0.0; 2097152.0; 137012.53333333333; 0.0; 0.8; 0.0; 0.0 +1377652682; 1; 2599.999602; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377652982; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1377653282; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377653582; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 121633.06666666667; 0.06666666666666667; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1377653882; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 100661.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377654182; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.2; 0.0 +1377654482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1377654782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377655082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1377655382; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377655682; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 145401.33333333334; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377655982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 144003.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377656282; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377656582; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6; 0.0; 0.0 +1377656882; 1; 2599.999602; 0.0; 0.0; 2097152.0; 159381.6; 0.0; 0.6; 0.0; 0.0 +1377657182; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377657482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377657782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6; 0.0; 0.0 +1377658082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377658382; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377658682; 1; 2599.999602; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377658982; 1; 2599.999602; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377659282; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377659582; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 135614.13333333333; 0.0; 1.0; 0.0; 0.0 +1377659882; 1; 2599.999602; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.0; 0.0 +1377660182; 1; 2599.999602; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377660482; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 135614.93333333332; 0.0; 6.733333333333333; 0.26666666666666666; 0.2 +1377660782; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377661082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377661382; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377661682; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1377661982; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.6; 3.8666666666666667; 0.0 +1377662282; 1; 2599.999602; 6.933332272; 0.26666666666666666; 2097152.0; 125828.0; 0.06666666666666667; 1.6666666666666667; 0.06666666666666667; 0.0 +1377662582; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 120235.46666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377662882; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 116040.0; 0.13333333333333333; 13.133333333333333; 0.06666666666666667; 0.4666666666666667 +1377663182; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 166372.0; 0.0; 0.8; 0.0; 0.0 +1377663482; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 1.0; 0.0 +1377663782; 1; 2599.999602; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.6; 0.0; 0.0 +1377664082; 1; 2599.999602; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377664382; 1; 2599.999602; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377664683; 1; 2599.999602; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.06666666666666667; 0.0 +1377664983; 1; 2599.999602; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377665283; 1; 2599.999602; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377665583; 1; 2599.999602; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377665883; 1; 2599.999602; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377666183; 1; 2599.999602; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377666483; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 127225.06666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1377666783; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 209713.33333333334; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377667083; 1; 2599.999602; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377667383; 1; 2599.999602; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377667683; 1; 2599.999602; 1.733333068; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377667983; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377668283; 1; 2599.999602; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.9333333333333333; 0.8666666666666667; 0.0 +1377668583; 1; 2599.999602; 0.0; 0.0; 2097152.0; 109049.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377668883; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.7333333333333333; 0.0 +1377669183; 1; 2599.999602; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377669483; 1; 2599.999602; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377669783; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.3333333333333333; 0.0 +1377670083; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 81087.73333333334; 0.0; 2.7333333333333334; 0.0; 0.4666666666666667 +1377670383; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377670683; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377670983; 1; 2599.999602; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377671283; 1; 2599.999602; 3.466666136; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.2; 0.0 +1377671583; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 2.1333333333333333; 0.13333333333333333; 0.13333333333333333 +1377671883; 1; 2599.999602; 13.866664544; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.5333333333333334; 0.3333333333333333; 0.0 +1377672183; 1; 2599.999602; 8.666665340000002; 0.33333333333333337; 2097152.0; 137013.06666666668; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377672483; 1; 2599.999602; 0.0; 0.0; 2097152.0; 142604.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377672783; 1; 2599.9993; 25.999993; 1.0; 2097152.0; 62912.0; 0.0; 1.125; 0.0; 0.0 +1377673083; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377673383; 1; 2599.9993; 12.133330066666666; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 7.0; 0.26666666666666666; 0.2 +1377673683; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 123030.93333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377673983; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377674283; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377674583; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377674883; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377675183; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377675483; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.06666666666666667; 0.0 +1377675783; 1; 2599.9993; 0.0; 0.0; 2097152.0; 61513.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377676083; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1377676383; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377676684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377676984; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 148197.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377677284; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 135614.13333333333; 0.2; 2.4; 0.0; 0.5333333333333333 +1377677584; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377677884; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377678184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377678484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377678784; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377679084; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377679384; 1; 2599.9993; 17.33332866666667; 0.6666666666666667; 2097152.0; 74097.06666666667; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377679684; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 150993.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377679984; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377680284; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377680584; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377680884; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 120234.66666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377681184; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377681484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377681784; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377682084; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377682384; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377682684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377682984; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 123030.66666666667; 0.0; 1.8666666666666667; 0.0; 0.06666666666666667 +1377683284; 1; 2599.9993; 24.266660133333332; 0.9333333333333332; 2097152.0; 184548.0; 0.0; 3.6666666666666665; 0.0; 0.0 +1377683584; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 2.8666666666666667; 0.0; 0.0 +1377683884; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1377684184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377684484; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377684784; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 153789.86666666667; 0.0; 7.0; 0.2; 0.13333333333333333 +1377685084; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377685384; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377685684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377685984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377686284; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1377686584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377686884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 142604.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377687184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377687484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377687784; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377688084; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 100661.6; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1377688384; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377688684; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377688984; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377689284; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377689584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377689884; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377690184; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377690484; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377690784; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 157983.46666666667; 0.06666666666666667; 7.2; 0.2; 0.13333333333333333 +1377691084; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 130020.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377691384; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1377691684; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 109050.4; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377691984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.06666666666666667; 1.1333333333333333; 0.0; 0.0 +1377692284; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377692584; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377692884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377693184; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377693484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377693784; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377694084; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377694384; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377694684; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377694984; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1377695284; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 120234.93333333333; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377695584; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 170567.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377695884; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.13333333333333333; 0.0 +1377696184; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377696484; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.2; 0.0 +1377696785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1377697085; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 124429.06666666667; 12.933333333333334; 13.133333333333333; 0.4666666666666667; 0.13333333333333333 +1377697385; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1377697685; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1377697985; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377698285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377698585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377698885; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 121633.6; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1377699185; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155188.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377699485; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377699785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377700085; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377700385; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 149595.46666666667; 0.06666666666666667; 1.4666666666666666; 0.13333333333333333; 0.06666666666666667 +1377700685; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377700985; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377701285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1377701585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377701885; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377702185; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377702485; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 107652.26666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377702785; 1; 2599.9993; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1377703085; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377703385; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377703685; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377703985; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 123031.73333333334; 0.0; 6.8; 0.2; 0.13333333333333333 +1377704285; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377704585; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377704885; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377705185; 1; 2599.9993; 74.53331326666667; 2.8666666666666667; 2097152.0; 657105.6; 161.33333333333334; 22.2; 0.26666666666666666; 0.4 +1377705485; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 374688.26666666666; 0.0; 5.133333333333334; 1.2666666666666666; 0.0 +1377705785; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 218101.33333333334; 31.8; 3.4; 0.0; 0.0 +1377706085; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 160780.53333333333; 0.0; 3.8; 0.0; 0.5333333333333333 +1377706385; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.3333333333333333; 0.0; 0.0 +1377706685; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 139809.33333333334; 0.0; 11.533333333333333; 0.0; 0.0 +1377706986; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377707286; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1377707586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377707886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1377708186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377708486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377708786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1377709086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377709386; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 102059.73333333334; 0.0; 6.866666666666666; 0.26666666666666666; 0.2 +1377709686; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 152392.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377709986; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1377710286; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377710586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377710886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377711186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377711486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377711786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377712086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377712386; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377712686; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6; 0.0; 0.0 +1377712986; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377713286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 110448.26666666666; 0.2; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1377713586; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142604.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377713886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377714186; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 111846.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377714486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377714786; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377715086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377715386; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377715686; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130021.6; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377715987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377716287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.6; 0.0; 0.0 +1377716587; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.0; 0.0 +1377716887; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 86680.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377717187; 1; 2599.9993; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377717487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.5333333333333333; 0.0; 0.0 +1377717787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377718087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377718387; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 88078.4; 161.73333333333332; 13.333333333333334; 0.0; 0.06666666666666667 +1377718687; 1; 2599.9993; 38.13332306666666; 1.4666666666666666; 2097152.0; 517296.0; 0.0; 2.2666666666666666; 0.0; 0.06666666666666667 +1377718987; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 223694.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1377719286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 197129.33333333334; 31.8; 3.8666666666666667; 0.0; 0.0 +1377719586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 0.8; 0.0; 0.0 +1377719886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377720186; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 132818.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1377720486; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 141206.66666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377720786; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 169168.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377721086; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377721386; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377721686; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1377721986; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377722286; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 104856.0; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1377722586; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377722886; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377723186; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377723486; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377723787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377724087; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 88078.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1377724387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 148196.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377724687; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377724987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377725287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 162177.33333333334; 0.0; 0.8; 0.0; 0.0 +1377725587; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377725887; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1377726187; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377726487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377726787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377727087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377727387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377727687; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127225.86666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377727987; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 170566.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377728287; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377728587; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 128624.26666666666; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1377728887; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377729187; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 81087.73333333334; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.06666666666666667 +1377729487; 1; 2599.9993; 0.0; 0.0; 2097152.0; 144003.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377729787; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377730087; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138409.86666666667; 0.0; 0.8; 0.0; 0.0 +1377730387; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377730687; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377730987; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377731288; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.4666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377731588; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377731888; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377732188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377732488; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.6; 0.0; 0.0 +1377732788; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377733088; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 67106.4; 0.0; 1.0; 0.0; 0.0 +1377733388; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6; 0.0; 0.0 +1377733688; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1377733988; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377734288; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377734588; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377734888; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 111846.66666666667; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377735188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 171964.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377735488; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 146799.2; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1377735788; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.4; 0.0; 0.0 +1377736088; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377736388; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130022.4; 0.0; 1.4; 0.0; 0.0 +1377736688; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377736988; 1; 2599.9993; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377737288; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377737588; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377738188; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.0; 0.0 +1377738489; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106253.33333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377738789; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 149594.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377739089; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377739389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377739689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377739989; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377740289; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377740589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377740889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377741189; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 144002.66666666666; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1377741489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377741789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1377742089; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377742389; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377742689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377742989; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377743289; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377743589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377743889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377744189; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377744489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377744789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377745089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377745389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377745689; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 131420.53333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377745989; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 171964.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377746289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377746589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377746889; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377747189; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377747489; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 92272.8; 0.2; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 +1377747789; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377748089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377748389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1377748690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377748990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.0; 0.0 +1377749290; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1377749590; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377749890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377750190; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.0; 11.933333333333334; 0.0; 0.0 +1377750490; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377750790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377751090; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377751390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377751690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377751990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377752289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377752589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377752889; 1; 2599.9993; 12.133330066666666; 0.4666666666666666; 2097152.0; 142604.53333333333; 0.0; 8.8; 0.26666666666666666; 0.6666666666666666 +1377753189; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 171965.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377753489; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377753789; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377754089; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377754389; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1377754689; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8; 0.0; 0.0 +1377754989; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377755289; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377755589; 1; 2599.9993; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377755890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377756190; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377756490; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 103456.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377756790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 159381.6; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 +1377757090; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377757390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1377757690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377757990; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.9333333333333333; 0.06666666666666667; 0.06666666666666667 +1377758290; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.6; 0.0; 0.0 +1377758590; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1377758890; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 149594.66666666666; 12.733333333333333; 12.866666666666667; 0.26666666666666666; 0.13333333333333333 +1377759190; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.4; 0.0; 0.0 +1377759490; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377759790; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377760090; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1377760390; 1; 2599.9993; 0.0; 0.0; 2097152.0; 176158.4; 0.0; 0.8; 0.0; 0.0 +1377760690; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8; 0.0; 0.0 +1377760990; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377761290; 1; 2599.9993; 0.0; 0.0; 2097152.0; 62912.0; 0.0; 1.0; 0.0; 0.0 +1377761590; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1377761890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377762190; 1; 2599.9993; 57.19998460000001; 2.2; 2097152.0; 634736.5333333333; 161.06666666666666; 22.533333333333335; 0.06666666666666667; 0.4 +1377762490; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 507508.8; 0.0; 2.7333333333333334; 0.0; 0.0 +1377762790; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 260044.8; 31.8; 3.8666666666666667; 0.0; 0.0 +1377763090; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 159382.4; 0.0; 2.2; 0.0; 0.0 +1377763390; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.0; 0.0 +1377763690; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377763990; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 163576.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377764290; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377764590; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377764890; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377765191; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377765491; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1377765791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377766091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1377766391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377766691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1377766991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377767291; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 180353.06666666668; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1377767591; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 216704.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377767891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377768191; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377768491; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377768791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377769091; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 81087.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377769391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1377769691; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 57319.46666666667; 0.0; 1.2; 0.0; 0.0 +1377769991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 +1377770291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 64310.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377770591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377770891; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1377771191; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1377771491; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377771791; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377772091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.06666666666666667; 6.666666666666667; 0.2; 0.13333333333333333 +1377772391; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1377772691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377772991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.0; 0.0; 0.8; 0.0; 0.0 +1377773291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.13333333333; 0.0; 1.0; 0.0; 0.0 +1377773591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377773891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377774191; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1377774491; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.0; 2.2; 0.0; 0.4666666666666667 +1377774791; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 197130.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377775091; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1377775391; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377775691; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377775991; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377776291; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377776591; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377776892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 +1377777192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377777492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377777792; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1377778092; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377778392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1377778692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377778992; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377779292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377779592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377779892; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377780192; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377780492; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1377780792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377781092; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.6; 4.066666666666666; 0.0 +1377781392; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.6; 0.0; 0.0 +1377781692; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1377781992; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 166372.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377782292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.5333333333333333; 0.0; 0.0 +1377782592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.6; 0.0; 0.0 +1377782892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377783192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 120234.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377783492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1377783792; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377784092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377784392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377784692; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106254.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1377784992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1377785292; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 96467.2; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377785591; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 159381.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377785891; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377786192; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377786492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1377786792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 1.4; 0.06666666666666667; 0.13333333333333333 +1377787092; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377787392; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.6; 0.0; 0.0 +1377787692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377787992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377788292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377788592; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.06666666666666667; 1.0; 0.0; 0.0 +1377788892; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.26666666666666666; 0.4666666666666667 +1377789192; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 162177.86666666667; 0.0; 0.8; 0.0; 0.0 +1377789492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377789792; 1; 2599.9993; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377790092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377790392; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124429.06666666667; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1377790692; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1377790992; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377791292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1377791592; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377791892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377792192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377792492; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.93333333333; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1377792792; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 146798.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377793092; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377793392; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377793692; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 11.733333333333333; 0.0; 0.0 +1377793992; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377794292; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377794592; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377794892; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.0; 0.0; 0.0 +1377795192; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377795492; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377795793; 1; 2599.9993; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377796093; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377796393; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 159381.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377796693; 1; 2599.9993; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377796993; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377797293; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377797593; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377797893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377798193; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377798493; 1; 2599.9993; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377798793; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377799093; 1; 2599.9993; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377799393; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377799693; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 81087.73333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1377799993; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377800293; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377800593; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377800893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 169168.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377801193; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377801493; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377801793; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377802093; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377802393; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1377802693; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377802993; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377803293; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 99263.46666666666; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377803593; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 160779.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377803893; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377804194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377804494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377804794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.8; 0.0; 0.0 +1377805094; 1; 2599.9993; 39.866655933333334; 1.5333333333333334; 2097152.0; 436205.86666666664; 161.0; 14.2; 0.0; 0.2 +1377805394; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 257248.26666666666; 0.0; 1.4; 0.0; 0.0 +1377805694; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 184547.73333333334; 31.8; 3.7333333333333334; 0.0; 0.0 +1377805994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 155187.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377806294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377806594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 +1377806894; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377807194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 153789.06666666668; 0.0; 0.5333333333333333; 0.0; 0.0 +1377807494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 169169.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377807794; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 131420.26666666666; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 +1377808094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130021.86666666667; 0.0; 0.6; 0.0; 0.0 +1377808394; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1377808694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377808994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377809294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1377809594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.0; 0.0 +1377809894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1377810194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.6; 0.0; 0.0 +1377810494; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124429.06666666667; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1377810794; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 180353.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377811094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1377811394; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.06666666666666667; 0.0 +1377811694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.6; 0.0; 0.0 +1377811994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377812294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1377812594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 163576.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377812894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377813194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377813494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377813794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377814094; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 92272.8; 0.0; 8.0; 0.3333333333333333; 0.6666666666666666 +1377814395; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1377814695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377814995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377815295; 1; 2599.9993; 17.33332866666667; 0.6666666666666667; 2097152.0; 160780.53333333333; 161.0; 20.6; 0.06666666666666667; 0.4 +1377815595; 1; 2599.9993; 48.533320266666664; 1.8666666666666665; 2097152.0; 781536.8; 0.0; 4.2; 0.06666666666666667; 0.13333333333333333 +1377815895; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 367698.93333333335; 31.8; 3.0; 0.0; 0.0 +1377816195; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 219500.0; 0.0; 2.6; 0.0; 0.0 +1377816495; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 +1377816795; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377817095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377817395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377817694; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.66666666667; 0.2; 2.7333333333333334; 0.0; 0.4666666666666667 +1377817994; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 157982.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377818294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377818594; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377818894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377819194; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.2; 1.0; 0.0; 0.0 +1377819494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377819794; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377820094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 1.2; 0.0; 0.0 +1377820394; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 170566.66666666666; 12.733333333333333; 16.8; 0.4; 0.13333333333333333 +1377820694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1377820994; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377821294; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 114642.13333333333; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377821594; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 157983.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377821894; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377822194; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377822494; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377822794; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 146800.0; 0.0; 1.4; 0.0; 0.0 +1377823094; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377823394; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377823694; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377823994; 1; 2599.9993; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377824294; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.8; 0.0; 0.0 +1377824595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377824895; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 117438.93333333333; 0.0; 3.2; 0.06666666666666667; 0.4666666666666667 +1377825195; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 145400.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377825495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377825795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377826095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377826395; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 7.2; 0.2; 0.13333333333333333 +1377826695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377826995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377827295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377827595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1377827895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377828195; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377828495; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130021.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377828795; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 167771.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377829095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377829395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377829695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377829995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377830295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377830595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377830895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377831195; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377831495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377831795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1377832095; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 125826.93333333333; 0.06666666666666667; 8.6; 0.2; 0.6 +1377832395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377832695; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377832995; 1; 2599.9993; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377833295; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377833595; 1; 2599.9993; 0.0; 0.0; 2097152.0; 159382.13333333333; 0.0; 0.8; 0.0; 0.0 +1377833895; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377834195; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377834495; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1377834795; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377835095; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 0.8; 0.0; 0.0 +1377835395; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377835695; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 103457.86666666667; 0.0; 2.2; 0.0; 0.4666666666666667 +1377835996; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377836296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377836596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377836896; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377837196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377837496; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 11.733333333333333; 0.0; 0.0 +1377837796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377838096; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127226.13333333333; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1377838396; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377838696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377838996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1377839296; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 89476.53333333334; 0.0; 1.9333333333333333; 0.06666666666666667; 0.4666666666666667 +1377839596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377839896; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377840196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1377840496; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377840796; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 145401.86666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377841096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1377841396; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377841696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377841996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377842296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1377842596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377842896; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 113244.8; 0.06666666666666667; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1377843196; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 159382.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377843496; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 113244.8; 0.06666666666666667; 6.933333333333334; 0.2; 0.13333333333333333 +1377843796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377844096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 106253.6; 0.0; 0.8; 0.0; 0.0 +1377844396; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 141205.86666666667; 0.0; 1.9333333333333333; 0.06666666666666667; 0.13333333333333333 +1377844696; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 130022.4; 0.0; 1.4666666666666666; 0.0; 0.0 +1377844997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377845297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377845597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1377845897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1377846197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377846497; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 106254.13333333333; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377846797; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 163576.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377847097; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377847397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1377847697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1377847997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377848297; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1377848597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1377848897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1377849197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377849497; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1377849797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377850097; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 100661.6; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1377850397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 +1377850696; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6; 0.06666666666666667; 0.0 +1377850996; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1377851296; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377851596; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6; 0.0; 0.0 +1377851896; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377852196; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377852496; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1377852796; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377853096; 1; 2599.9993; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 +1377853396; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1377853696; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377853996; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 159383.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377854297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100660.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377854597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377854897; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377855197; 1; 2599.9993; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377855497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377855797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8; 0.13333333333333333; 0.0 +1377856097; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 144003.73333333334; 0.2; 7.133333333333334; 0.2; 0.13333333333333333 +1377856397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.5333333333333333; 0.0; 0.0 +1377856697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.3333333333333333; 0.0 +1377856997; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1377857297; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 127225.06666666667; 0.0; 1.8666666666666667; 0.0; 0.4666666666666667 +1377857597; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 121632.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377857897; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377858197; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377858497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377858797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377859097; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377859397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377859697; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377859997; 1; 2599.9993; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377860297; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.6; 0.13333333333333333; 0.0 +1377860597; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377860897; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 125827.46666666666; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1377861197; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 192935.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377861497; 1; 2599.9993; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6; 0.0; 0.0 +1377861797; 1; 2599.9993; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377862097; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 6.866666666666666; 0.4; 0.13333333333333333 +1377862397; 1; 2599.9993; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377862698; 1; 2599.9993; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.6; 0.0; 0.0 +1377862998; 1; 2599.9993; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.6; 0.0; 0.0 +1377863298; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377863598; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377863898; 1; 2599.9993; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377864198; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377864498; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 128624.26666666666; 0.0; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1377864798; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 156586.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377865098; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1377865398; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377865698; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.2; 0.0 +1377865998; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377866298; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1377866598; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377866898; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 3.066666666666667; 0.0 +1377867198; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377867498; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377867798; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.2; 0.0 +1377868098; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 181750.93333333332; 0.06666666666666667; 8.533333333333333; 0.4; 0.6 +1377868398; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 208315.2; 0.0; 1.0; 0.13333333333333333; 0.0 +1377868698; 1; 2599.9993; 60.66665033333334; 2.3333333333333335; 2097152.0; 227889.33333333334; 161.06666666666666; 21.933333333333334; 0.06666666666666667; 0.4 +1377868998; 1; 2599.9993; 13.866662933333332; 0.5333333333333333; 2097152.0; 673882.4; 0.0; 2.466666666666667; 0.06666666666666667; 0.0 +1377869298; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 285210.13333333336; 31.8; 4.466666666666667; 0.06666666666666667; 0.0 +1377869598; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 208314.4; 0.0; 2.2666666666666666; 0.0; 0.0 +1377869898; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 149596.26666666666; 0.0; 1.6; 0.0; 0.0 +1377870198; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377870498; 1; 2599.9993; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.26666666666666666; 0.0 +1377870798; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 139808.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377871098; 1; 2599.9993; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377871398; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377871698; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377871998; 1; 2599.9993; 10.3999972; 0.4; 2097152.0; 174760.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377872299; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377872599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377872899; 1; 2599.9993; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377873199; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.4; 0.06666666666666667; 0.06666666666666667 +1377873499; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377873799; 1; 2599.9993; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1377874099; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377874399; 1; 2599.9993; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377874699; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 6.666666666666667; 0.0 +1377874999; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 6.0; 0.3333333333333333; 0.13333333333333333 +1377875299; 1; 2599.9993; 8.666664333333335; 0.33333333333333337; 2097152.0; 150993.86666666667; 0.0; 3.2; 0.0; 0.5333333333333333 +1377875599; 1; 2599.9993; 6.933331466666666; 0.26666666666666666; 2097152.0; 160780.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377875899; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 96467.2; 0.0; 0.8; 0.13333333333333333; 0.0 +1377876199; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377876499; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.4; 0.0 +1377876799; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377877099; 1; 2599.9993; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377877399; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1377877699; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377877999; 1; 2599.9993; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1377878299; 1; 2599.9993; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377878599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377878899; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 95068.53333333334; 0.06666666666666667; 2.7333333333333334; 0.13333333333333333; 0.4666666666666667 +1377879199; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 124428.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377879499; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377879799; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377880100; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377880400; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377880700; 1; 2599.9993; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377881000; 1; 2599.9993; 15.599995799999999; 0.6; 2097152.0; 128624.26666666666; 12.8; 23.933333333333334; 0.3333333333333333; 0.2 +1377881300; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1377881600; 1; 2599.9993; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1377881900; 1; 2599.9993; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377882200; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377882500; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 79689.6; 0.06666666666666667; 2.6; 0.2; 0.4666666666666667 +1377882800; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1377883100; 1; 2599.9993; 5.1999986; 0.2; 2097152.0; 109050.4; 0.0; 1.0; 0.13333333333333333; 0.0 +1377883399; 1; 2599.9993; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8; 0.06666666666666667; 0.0 +1377883699; 1; 2599.9993; 1.7333328666666665; 0.06666666666666667; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377883999; 1; 2599.9993; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377884299; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 1.2; 0.0; 0.0 +1377884599; 1; 2599.9993; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377884899; 1; 2599.9993; 3.466665733333333; 0.13333333333333333; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1377885199; 1; 2599.9993; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377885499; 1; 2599.9993; 0.0; 0.0; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377885799; 1; 2599.999602; 11.99999816307692; 0.4615384615384615; 2097152.0; 96789.84615384616; 0.0; 0.8333333333333334; 0.0; 0.0 +1377886099; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 162178.4; 0.06666666666666667; 2.3333333333333335; 0.13333333333333333; 0.4666666666666667 +1377886400; 1; 2599.999602; 0.0; 0.0; 2097152.0; 163575.46666666667; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377886700; 1; 2599.999602; 5.199999203999999; 0.2; 2097152.0; 162178.66666666666; 0.0; 7.0; 0.26666666666666666; 0.2 +1377887000; 1; 2599.999602; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377887300; 1; 2599.999602; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377887600; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 119836.0; 0.0; 0.8461538461538461; 0.07692307692307693; 0.0 +1377887900; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377888200; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1377888500; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377888800; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.5333333333333333; 0.0 +1377889100; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377889400; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377889700; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1377890000; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 157984.26666666666; 0.0; 0.8; 0.0; 0.0 +1377890300; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377890600; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377890900; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377891200; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1377891500; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 462770.4; 161.06666666666666; 14.533333333333333; 0.06666666666666667; 0.2 +1377891800; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 276821.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1377892100; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 212510.13333333333; 31.8; 4.0; 0.0; 0.0 +1377892400; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150994.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377892700; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377893000; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 124429.86666666667; 0.06666666666666667; 7.066666666666666; 0.2; 0.13333333333333333 +1377893300; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142604.26666666666; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 +1377893600; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1377893900; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377894200; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377894500; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.4666666666666667; 0.0 +1377894800; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377895100; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 1.0666666666666667; 0.0 +1377895400; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377895700; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377896000; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377896300; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377896600; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377896901; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 141207.46666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1377897201; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1377897501; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377897801; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1377898101; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377898401; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 79689.6; 0.0; 0.8; 0.2; 0.0 +1377898701; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1377899001; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377899301; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377899601; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377899901; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1377900201; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377900501; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.13333333333; 0.0; 1.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1377900801; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 159381.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377901101; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118836.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377901401; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106253.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377901701; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1377902001; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.06666666666666667; 1.7333333333333334; 0.06666666666666667; 0.13333333333333333 +1377902301; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377902601; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1377902901; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377903201; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377903502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377903802; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377904102; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 156585.6; 0.26666666666666666; 2.0; 0.06666666666666667; 0.4666666666666667 +1377904402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 176159.46666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377904702; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377905002; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1377905302; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139808.53333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1377905602; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377905902; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377906202; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1377906502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1377906802; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1377907102; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377907402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377907702; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 125827.73333333334; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1377908002; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 169168.0; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377908302; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377908602; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377908902; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377909202; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 110448.53333333334; 0.0; 1.4666666666666666; 0.0; 0.0 +1377909502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377909802; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 +1377910102; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1377910402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377910702; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1377911002; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 123031.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377911302; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 139808.0; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377911602; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152391.2; 0.06666666666666667; 0.7333333333333333; 0.0; 0.0 +1377911902; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 123031.46666666666; 0.0; 7.2; 0.2; 0.13333333333333333 +1377912202; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377912502; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1377912802; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377913102; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377913402; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377913702; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1377914003; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 1.6; 0.0; 0.0 +1377914303; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377914603; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1377914903; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1377915203; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1377915503; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377915803; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1377916102; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1377916402; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377916702; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377917002; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377917302; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377917602; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377917902; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377918202; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120234.4; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1377918502; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1377918802; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377919102; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 5.133333333333334; 0.0 +1377919402; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377919702; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377920002; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.6; 0.0; 0.0 +1377920302; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377920602; 1; 2599.999343; 67.59998291800001; 2.6; 2097152.0; 336940.0; 161.0; 21.8; 0.06666666666666667; 0.4 +1377920903; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 634736.0; 0.0; 2.7333333333333334; 0.0; 0.0 +1377921203; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 292201.3333333333; 31.8; 3.4; 0.06666666666666667; 0.0 +1377921503; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 205517.86666666667; 0.0; 2.3333333333333335; 0.0; 0.0 +1377921803; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.6; 0.0; 1.5333333333333334; 0.0; 0.0 +1377922103; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139808.53333333333; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1377922403; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 166372.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377922703; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.6; 0.0; 0.0 +1377923003; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377923303; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 0.6; 0.0; 0.0 +1377923603; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377923903; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.6; 0.0; 0.0 +1377924203; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377924503; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 61513.86666666667; 0.0; 1.0; 0.0; 0.0 +1377924803; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 71300.8; 0.0; 11.666666666666666; 0.0; 0.0 +1377925103; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 6.2; 0.2; 0.13333333333333333 +1377925403; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.7333333333333334; 0.0; 0.0 +1377925703; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.6; 0.06666666666666667; 2.533333333333333; 0.13333333333333333; 0.5333333333333333 +1377926003; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 226490.13333333333; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1377926303; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.6; 0.06666666666666667; 0.0 +1377926603; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.6; 0.0; 0.0 +1377926903; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377927203; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377927503; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.5333333333333333; 0.0; 0.0 +1377927803; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1377928103; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377928403; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377928703; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1377929003; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 81087.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1377929303; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134215.73333333334; 0.06666666666666667; 2.2666666666666666; 0.2; 0.5333333333333333 +1377929604; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1377929904; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377930204; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.5333333333333333; 0.0; 0.0 +1377930504; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377930804; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 8.133333333333333; 0.26666666666666666; 0.2 +1377931104; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.4; 0.0; 0.0 +1377931404; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1377931704; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.6; 0.0; 0.0 +1377932004; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1377932304; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.6; 0.0; 0.0 +1377932604; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377932904; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377933204; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377933504; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121632.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377933804; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1377934104; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377934404; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377934704; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377935004; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1377935304; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1377935604; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1377935904; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377936204; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377936504; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130021.6; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377936804; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 152390.93333333332; 0.0; 6.8; 0.2; 0.13333333333333333 +1377937104; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.06666666666666667; 1.5333333333333334; 0.06666666666666667; 0.0 +1377937404; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1377937704; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377938004; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377938304; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1377938604; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377938905; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377939205; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 1.2; 0.0 +1377939505; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121632.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377939805; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377940105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 135613.6; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377940405; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 176160.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1377940705; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377941005; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1377941305; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377941605; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377941905; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377942205; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377942505; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 142604.8; 12.733333333333333; 13.266666666666667; 0.3333333333333333; 0.2 +1377942805; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377943105; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377943405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377943705; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 103457.86666666667; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1377944005; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377944305; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377944605; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377944905; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377945205; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1377945505; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 0.8; 0.0; 0.0 +1377945805; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377946105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377946405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377946706; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1377947006; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377947306; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 139808.53333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377947606; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 188741.6; 0.0; 0.8; 0.0; 0.0 +1377947906; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 117439.2; 0.0; 1.0; 3.066666666666667; 0.0 +1377948206; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 64310.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377948506; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377948805; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1377949105; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 152391.73333333334; 0.0; 7.466666666666667; 0.26666666666666666; 0.13333333333333333 +1377949405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1377949705; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 118836.26666666666; 0.0; 1.0; 0.0; 0.0 +1377950005; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130021.33333333333; 0.0; 0.6; 0.0; 0.0 +1377950305; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377950605; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1377950905; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 125828.0; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1377951205; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 +1377951505; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377951805; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377952105; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109049.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1377952405; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 76893.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1377952705; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377953005; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1377953306; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377953606; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1377953906; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377954206; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377954506; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 142604.0; 0.06666666666666667; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1377954806; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 167770.4; 0.0; 1.0; 0.0; 0.0 +1377955106; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377955406; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1377955706; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377956006; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 118837.33333333333; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1377956306; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 178954.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1377956606; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377956906; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1377957206; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377957506; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1377957806; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377958106; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.33333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1377958406; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 173363.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1377958706; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377959006; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377959306; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1377959606; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.13333333333333333 +1377959906; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377960206; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377960506; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1377960806; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377961106; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377961406; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1377961706; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1377962006; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141206.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377962307; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1377962607; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 +1377962907; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.06666666666666667; 6.8; 0.2; 0.13333333333333333 +1377963207; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1377963507; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1377963807; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377964107; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377964407; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121632.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377964707; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377965007; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 50328.8; 0.0; 0.8; 0.0; 0.0 +1377965307; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.86666666667; 0.0; 2.0; 0.06666666666666667; 0.4666666666666667 +1377965607; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 171964.53333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377965907; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377966207; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377966507; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377966807; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377967107; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377967407; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377967707; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1377968007; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 142604.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377968307; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 0.0; 17.666666666666668; 0.2; 0.13333333333333333 +1377968607; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377968907; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377969207; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1377969507; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1377969807; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377970107; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377970407; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1377970707; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1377971007; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1377971307; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 75495.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1377971607; 1; 2599.999343; 67.59998291800001; 2.6; 2097152.0; 232082.93333333332; 161.0; 21.866666666666667; 0.13333333333333333; 0.3333333333333333 +1377971907; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 727010.4; 0.0; 2.466666666666667; 0.0; 0.0 +1377972207; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 279618.4; 31.8; 3.6; 1.1333333333333333; 0.0 +1377972507; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 191537.6; 0.0; 3.6; 0.06666666666666667; 0.4666666666666667 +1377972807; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 164974.93333333332; 0.0; 1.6; 0.0; 0.0 +1377973107; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1377973407; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.6; 0.0; 0.0 +1377973707; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1377974008; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1377974308; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377974608; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377974908; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377975208; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1377975508; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1377975808; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1377976108; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 149595.46666666667; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1377976408; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 181751.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377976708; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1377977008; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1377977308; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.6; 0.0; 0.0 +1377977608; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1377977908; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 387272.0; 161.06666666666666; 14.6; 0.0; 0.2 +1377978208; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 315969.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1377978508; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 155188.0; 31.8; 3.8666666666666667; 0.0; 0.0 +1377978808; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1377979108; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1377979408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377979708; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130021.06666666667; 0.06666666666666667; 3.0; 0.06666666666666667; 0.4666666666666667 +1377980008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1377980308; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 7.2; 0.2; 0.13333333333333333 +1377980608; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1377980908; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377981208; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377981508; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1377981808; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1377982108; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1377982408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1377982708; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1377983008; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1377983308; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.86666666667; 0.06666666666666667; 2.2666666666666666; 0.0; 0.5333333333333333 +1377983608; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1377983908; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1377984208; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1377984508; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377984808; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377985108; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377985408; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1377985708; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 149596.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377986008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 155188.26666666666; 0.0; 0.8; 0.0; 0.0 +1377986308; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 131420.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377986608; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1377986908; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 8.533333333333333; 0.26666666666666666; 0.7333333333333333 +1377987208; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1377987508; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 148197.33333333334; 169.66666666666666; 179.2; 0.0; 0.0 +1377987808; 1; 2599.999343; 25.99999343; 1.0; 2097152.0; 243268.0; 0.0; 1.2; 0.0; 0.0 +1377988108; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 145401.33333333334; 0.0; 1.0; 0.0; 0.0 +1377988408; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 +1377988708; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377989008; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 81087.73333333334; 0.0; 0.8; 0.0; 0.0 +1377989309; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1377989609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 1.0; 0.0; 0.0 +1377989909; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377990209; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1377990509; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1377990809; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1377991109; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1377991409; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1377991709; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 71300.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1377992009; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1377992309; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1377992609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1377992909; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377993209; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1377993509; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1377993809; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1377994109; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 164974.66666666666; 0.0; 8.6; 0.26666666666666666; 0.6 +1377994409; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 185944.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1377994709; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1377995009; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86679.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1377995309; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.6; 0.0; 0.0 +1377995609; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1377995909; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 68504.53333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377996209; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1377996509; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1377996809; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1377997109; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 +1377997409; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.5333333333333333; 0.0; 0.0 +1377997709; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1377998009; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 +1377998310; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.6; 0.0; 0.0 +1377998610; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.6; 0.0; 0.0 +1377998910; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1377999210; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 1.0; 0.0; 0.0 +1377999510; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.0; 0.0 +1377999810; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.06666666666666667; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378000110; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1378000410; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378000710; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378001010; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.6; 0.0; 0.0 +1378001310; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 124428.8; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1378001610; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 177556.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378001910; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110447.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378002210; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1378002510; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 163576.53333333333; 0.0; 0.6; 0.0; 0.0 +1378002810; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.13333333333; 0.0; 1.5333333333333334; 0.13333333333333333; 0.0 +1378003110; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1378003410; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378003710; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378004010; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 145400.53333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378004310; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378004610; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1378004910; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127225.06666666667; 0.0; 2.1333333333333333; 0.06666666666666667; 0.5333333333333333 +1378005210; 1; 2599.999343; 327.599917218; 12.6; 2097152.0; 534072.8; 34.2; 753.7333333333333; 149.46666666666667; 32.13333333333333 +1378005510; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 322958.93333333335; 0.0; 1.4; 0.0; 0.0 +1378005810; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378006110; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378006410; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1378006711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 12.733333333333333; 13.133333333333333; 0.3333333333333333; 0.2 +1378007011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378007311; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1378007611; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378007911; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378008211; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378008511; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.13333333333333333; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378008811; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 199926.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378009111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 137012.26666666666; 0.0; 1.0; 0.0; 0.0 +1378009411; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378009711; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378010011; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378010311; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1378010611; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378010911; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378011211; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378011511; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1378011811; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378012111; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 113243.46666666666; 0.13333333333333333; 13.533333333333333; 0.0; 0.4666666666666667 +1378012411; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174761.06666666668; 0.0; 6.133333333333334; 0.2; 0.13333333333333333 +1378012711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 156586.93333333332; 0.0; 1.9333333333333333; 0.0; 0.0 +1378013011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1378013311; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378013611; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378013912; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378014211; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 +1378014511; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378014811; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378015111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378015411; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378015711; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378016011; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 167771.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378016311; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378016611; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378016911; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378017211; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 2.6; 0.06666666666666667; 0.13333333333333333 +1378017511; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 159381.6; 0.0; 1.8666666666666667; 0.0; 0.0 +1378017811; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378018111; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378018411; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1378018711; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 6.066666666666666; 0.2; 0.13333333333333333 +1378019011; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 2.066666666666667; 0.0; 0.0 +1378019312; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1378019612; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 163576.0; 0.0; 1.0; 0.0; 0.0 +1378019912; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378020212; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378020512; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378020812; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378021112; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.3333333333333333; 0.0 +1378021412; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378021712; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.2666666666666666; 0.2; 0.0 +1378022012; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141206.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378022312; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378022612; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378022912; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.2; 2.4; 0.06666666666666667; 0.5333333333333333 +1378023212; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378023512; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 1.0; 0.13333333333333333; 0.0 +1378023812; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378024112; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378024412; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.8; 0.13333333333333333; 0.0 +1378024712; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378025012; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378025312; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 6.266666666666667; 0.3333333333333333; 0.2 +1378025612; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 192936.0; 0.0; 2.1333333333333333; 0.0; 0.0 +1378025912; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378026212; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378026512; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 149596.26666666666; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378026812; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 171964.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378027112; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378027412; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378027713; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378028013; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378028313; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 156586.13333333333; 0.0; 1.2; 0.0; 0.0 +1378028613; 1; 2599.999343; 69.33331581333334; 2.666666666666667; 2097152.0; 422225.06666666665; 161.0; 21.933333333333334; 0.06666666666666667; 0.4 +1378028913; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 603977.6; 0.0; 2.6; 0.06666666666666667; 0.0 +1378029213; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 226489.6; 31.8; 3.6; 0.0; 0.0 +1378029513; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 184548.0; 0.8; 2.6; 0.0; 0.0 +1378029813; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1378030113; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 2.3333333333333335; 1.4666666666666666; 0.5333333333333333 +1378030413; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 174761.33333333334; 0.0; 1.0; 0.0; 0.0 +1378030713; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378031013; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159381.6; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378031313; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378031613; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378031913; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378032213; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378032513; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378032813; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378033113; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.0; 0.0 +1378033413; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378033713; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378034013; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170566.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378034313; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378034613; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.06666666666666667; 1.4; 0.13333333333333333; 0.0 +1378034913; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.0 +1378035214; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378035514; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378035814; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 131419.73333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378036114; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378036414; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378036714; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1378037014; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378037314; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378037614; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1378037914; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378038214; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378038514; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378038814; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378039114; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1378039414; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378039714; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1378040014; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 60115.73333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378040314; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1378040614; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378040914; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128623.73333333334; 0.0; 2.4; 0.13333333333333333; 0.5333333333333333 +1378041214; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 1.0; 0.0; 0.0 +1378041514; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378041814; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 130022.4; 0.0; 1.2; 0.0; 0.0 +1378042114; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.33333333333; 0.0; 7.4; 0.2; 0.13333333333333333 +1378042414; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378042715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378043015; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378043315; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1378043615; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378043915; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378044215; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378044515; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.06666666667; 0.06666666666666667; 2.533333333333333; 0.13333333333333333; 0.4666666666666667 +1378044815; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 159382.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378045115; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378045415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378045715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378046015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1378046315; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1378046615; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378046915; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378047215; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 149594.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378047515; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.8666666666666667; 0.0; 0.0 +1378047815; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378048115; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 176157.86666666667; 0.0; 8.333333333333334; 0.26666666666666666; 0.6 +1378048415; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378048715; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378049015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378049315; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378049615; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 164974.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378049915; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378050215; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378050515; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.4; 0.0; 0.0 +1378050815; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378051115; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378051415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 164975.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378051715; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150992.8; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378052015; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378052315; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 +1378052615; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378052915; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 145401.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378053215; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378053515; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378053815; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378054115; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378054415; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378054715; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 72698.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378055015; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125827.2; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378055315; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 167770.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378055615; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144002.93333333332; 0.0; 12.0; 0.0; 0.0 +1378055916; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378056216; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378056516; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378056816; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378057116; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378057416; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378057716; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378058016; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378058316; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378058616; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1378058916; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 176159.2; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1378059216; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 222296.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378059516; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1378059816; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378060116; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.2; 0.0; 0.0 +1378060416; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378060716; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.06666666666666667; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378061016; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 160779.73333333334; 0.06666666666666667; 1.9333333333333333; 0.0; 0.0 +1378061316; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378061616; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378061916; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378062216; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 1.4; 1.3333333333333333; 0.0; 0.0 +1378062516; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378062816; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378063116; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378063416; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1378063716; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378064017; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 163576.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378064317; 1; 2599.999343; 50.266653964666666; 1.9333333333333333; 2097152.0; 303386.4; 161.66666666666666; 14.466666666666667; 0.0; 0.2 +1378064617; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 373291.2; 0.0; 1.4; 0.0; 0.0 +1378064917; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 204120.53333333333; 31.8; 4.0; 0.0; 0.0 +1378065217; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 188741.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378065517; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378065817; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378066117; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378066417; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378066717; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378067017; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378067317; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 150993.6; 12.866666666666667; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1378067617; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 184547.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378067917; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378068217; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378068517; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1378068817; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.8; 0.0; 0.0 +1378069117; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1378069417; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378069717; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.2; 3.2; 0.06666666666666667; 0.4666666666666667 +1378070017; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.06666666666666667; 0.8; 0.0; 0.0 +1378070317; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378070617; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378070917; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378071217; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1378071517; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.6; 0.0; 1.2; 0.0; 0.0 +1378071817; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378072117; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378072418; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 +1378072718; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 6.8; 0.2; 0.13333333333333333 +1378073018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 173362.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378073318; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144003.46666666667; 0.0; 2.4; 0.2; 0.4666666666666667 +1378073618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 153789.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378073918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378074218; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378074518; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378074818; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.06666666667; 0.0; 1.4; 0.06666666666666667; 0.13333333333333333 +1378075118; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378075418; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1378075718; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 155188.0; 0.0; 0.8; 0.0; 0.0 +1378076018; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378076318; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378076618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.2; 1.4; 0.0; 0.0 +1378076918; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 139807.73333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378077218; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 223694.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378077518; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378077818; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378078118; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378078418; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 141207.46666666667; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 +1378078718; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378079018; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378079318; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.4666666666666666; 0.0; 0.0 +1378079618; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378079918; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378080218; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378080518; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 155188.0; 0.06666666666666667; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 +1378080818; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 149594.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378081118; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378081418; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378081718; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378082018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.6; 1.7333333333333334; 0.0; 0.0 +1378082318; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378082618; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378082918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378083218; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378083518; 1; 2599.999343; 51.99998686; 2.0; 2097152.0; 160779.73333333334; 161.0; 22.066666666666666; 0.2; 0.3333333333333333 +1378083818; 1; 2599.999343; 36.399990802; 1.4; 2097152.0; 598384.8; 0.0; 2.7333333333333334; 0.0; 0.0 +1378084118; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 282414.6666666667; 32.6; 5.066666666666666; 0.06666666666666667; 0.5333333333333333 +1378084418; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 209713.33333333334; 0.0; 2.6; 0.0; 0.0 +1378084718; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153790.66666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378085018; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378085318; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1378085618; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1378085918; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378086218; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378086518; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378086818; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378087118; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378087418; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378087718; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 167770.4; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378088018; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 192936.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378088319; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157985.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378088619; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150994.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378088919; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1378089219; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378089519; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378089819; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1378090119; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378090419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 142605.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1378090719; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1378091019; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378091319; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1378091619; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170567.46666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378091919; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.7333333333333334; 0.0; 0.0 +1378092219; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 71300.8; 0.0; 1.0; 0.13333333333333333; 0.0 +1378092519; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378092819; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378093119; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378093419; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 64310.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378093719; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378094019; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378094319; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.8; 0.0; 0.0 +1378094619; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.06666666666666667; 0.0 +1378094919; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.33333333334; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378095219; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153788.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378095519; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378095819; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378096119; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.2; 0.0 +1378096419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.0; 0.0 +1378096719; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378097019; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.2; 0.0; 0.0 +1378097319; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 65708.26666666666; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378097619; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378097919; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378098219; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378098519; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 141207.46666666667; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378098819; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378099119; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 83884.0; 0.0; 11.866666666666667; 0.0; 0.0 +1378099419; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378099719; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378100019; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378100319; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144003.73333333334; 0.0; 0.8; 0.0; 0.0 +1378100620; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378100920; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378101220; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378101520; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 75495.2; 0.0; 1.2; 0.0; 0.0 +1378101820; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378102120; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.06666666666666667; 2.4; 0.06666666666666667; 0.4666666666666667 +1378102420; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 +1378102720; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378103020; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378103320; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 146800.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378103620; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 103457.86666666667; 0.06666666666666667; 2.6; 0.2; 0.13333333333333333 +1378103920; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1378104220; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.2666666666666666; 0.0; 0.0 +1378104520; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.26666666666666666; 7.466666666666667; 0.26666666666666666; 0.13333333333333333 +1378104820; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378105120; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378105420; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1378105720; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 164974.4; 0.0; 2.3333333333333335; 0.13333333333333333; 0.5333333333333333 +1378106020; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 188742.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378106320; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1378106620; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.2; 0.0 +1378106920; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1378107220; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.26666666666666666; 0.0 +1378107520; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378107820; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 +1378108120; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 1.4; 0.06666666666666667; 0.0 +1378108420; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.4; 0.06666666666666667; 0.0 +1378108720; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378109020; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118836.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378109320; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135613.86666666667; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378109620; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 137012.53333333333; 0.0; 1.0; 0.0; 0.0 +1378109921; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378110221; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378110521; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378110820; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378111120; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.0; 0.0 +1378111420; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378111720; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378112020; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378112320; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378112621; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378112921; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.0; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1378113221; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.0; 0.0 +1378113521; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378113821; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378114121; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378114421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378114721; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378115021; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378115321; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.4; 0.0; 0.0 +1378115621; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378115921; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 0.8; 0.0; 0.0 +1378116221; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378116521; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378116821; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 170566.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1378117121; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378117421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378117721; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378118021; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378118321; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8; 0.0; 0.0 +1378118621; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378118921; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378119221; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378119521; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134215.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378119821; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378120121; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141206.66666666666; 0.0; 2.4; 0.2; 0.5333333333333333 +1378120421; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1378120721; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378121021; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378121321; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1378121622; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378121922; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378122222; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378122522; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1378122822; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378123122; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 148197.33333333334; 0.0; 0.8; 0.0; 0.0 +1378123422; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 167770.13333333333; 0.0; 7.2; 0.2; 0.13333333333333333 +1378123722; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152392.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378124022; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 173362.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378124322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378124622; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378124922; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1378125222; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378125522; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378125822; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.7333333333333333; 0.0; 0.0 +1378126122; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378126422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378126722; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378127022; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378127322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 170567.2; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378127622; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1378127922; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1378128222; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378128522; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378128822; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1378129122; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 139809.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378129422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378129722; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378130022; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378130322; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.2 +1378130622; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.06666666666666667; 1.5333333333333334; 0.0; 0.0 +1378130922; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.13333333333333333; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378131222; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 167770.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378131522; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378131822; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378132122; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378132422; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 92272.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.06666666666666667 +1378132722; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378133023; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378133323; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378133623; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378133923; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378134223; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 144003.73333333334; 0.0; 1.0; 0.0; 0.0 +1378134523; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 169168.8; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378134823; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 180353.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378135123; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378135423; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378135723; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378136023; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378136323; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.8; 0.0; 0.0 +1378136623; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378136923; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.4; 0.0; 0.0 +1378137223; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378137523; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378137823; 1; 2599.999343; 51.99998686; 2.0; 2097152.0; 152391.46666666667; 161.0; 21.866666666666667; 0.13333333333333333; 0.4 +1378138123; 1; 2599.999343; 43.333322383333325; 1.6666666666666665; 2097152.0; 713029.6; 0.8; 4.333333333333333; 0.06666666666666667; 0.5333333333333333 +1378138423; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 360708.0; 31.8; 3.533333333333333; 0.13333333333333333; 0.0 +1378138723; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 222296.0; 0.0; 2.7333333333333334; 0.06666666666666667; 0.0 +1378139023; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 155188.0; 0.0; 1.8; 0.0; 0.0 +1378139323; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378139623; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378139923; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378140223; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378140523; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378140824; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378141124; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378141424; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378141724; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 125828.0; 0.6; 2.4; 0.06666666666666667; 0.5333333333333333 +1378142024; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 155187.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378142324; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378142624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378142924; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 138410.4; 0.0; 12.0; 0.0; 0.0 +1378143224; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.53333333333; 0.0; 7.133333333333334; 0.7333333333333333; 0.13333333333333333 +1378143524; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 213906.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378143824; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378144124; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 67106.4; 0.0; 1.0; 0.0; 0.0 +1378144424; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 67106.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378144724; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378145024; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378145324; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 155187.2; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378145624; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378145924; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378146224; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378146524; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378146824; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378147124; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378147424; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378147724; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378148024; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378148324; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0; 0.0; 0.0 +1378148624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378148924; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163576.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378149224; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 152390.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378149524; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 6.933333333333334; 0.3333333333333333; 0.13333333333333333 +1378149824; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378150124; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378150424; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378150724; 1; 2599.999343; 53.733319755333326; 2.0666666666666664; 2097152.0; 247462.4; 161.73333333333332; 14.333333333333334; 0.0; 0.2 +1378151024; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 364902.4; 0.0; 1.4666666666666666; 0.0; 0.0 +1378151324; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 167771.2; 31.8; 4.0; 0.0; 0.0 +1378151624; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 176159.2; 0.0; 0.8; 0.0; 0.0 +1378151924; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378152224; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378152525; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 99263.46666666666; 0.0; 2.8666666666666667; 0.06666666666666667; 0.5333333333333333 +1378152825; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 153789.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378153125; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378153425; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378153725; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378154025; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378154325; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378154625; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378154925; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378155225; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378155525; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378155825; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378156125; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 153789.86666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378156425; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378156725; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378157025; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378157325; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378157625; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378157925; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378158225; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1378158525; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378158825; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378159125; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378159425; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 132818.13333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1378159725; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 166371.46666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378160025; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378160325; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1378160625; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378160925; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378161225; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.06666666666666667; 1.8; 0.06666666666666667; 0.13333333333333333 +1378161525; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378161825; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378162125; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378162425; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 7.2; 0.26666666666666666; 0.13333333333333333 +1378162725; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378163025; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 171964.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378163325; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 170566.66666666666; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1378163625; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378163926; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141206.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378164226; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 61513.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378164526; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378164826; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378165126; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107651.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378165426; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378165726; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378166026; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378166326; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378166626; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378166926; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 102059.73333333334; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378167226; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378167526; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378167826; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 124429.33333333333; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378168126; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378168426; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.5333333333333333; 1.4666666666666666; 0.0; 0.0 +1378168726; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378169026; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378169326; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378169627; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378169927; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378170227; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378170527; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 131420.0; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378170827; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 146798.93333333332; 0.0; 1.0; 0.0; 0.0 +1378171127; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378171427; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 162178.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378171727; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.6; 0.0; 0.0 +1378172027; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378172327; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378172627; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378172927; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1378173227; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378173527; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378173827; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 159381.86666666667; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378174127; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 137011.46666666667; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378174427; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 160780.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378174727; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378175027; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378175327; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378175627; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378175927; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378176227; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 78291.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378176527; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378176827; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378177127; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378177427; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378177727; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378178027; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 184546.13333333333; 0.0; 1.0; 0.0; 0.0 +1378178327; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378178627; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378178927; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378179227; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378179527; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144003.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378179828; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106253.86666666667; 0.0; 1.0; 0.0; 0.0 +1378180128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 7.8; 0.2; 0.13333333333333333 +1378180428; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378180728; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 1.6; 0.0; 0.0 +1378181028; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378181328; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378181628; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 +1378181928; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378182228; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1378182528; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378182828; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378183128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378183428; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378183728; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378184028; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378184328; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378184628; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.2; 0.0; 0.0 +1378184928; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 145401.33333333334; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378185228; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 177556.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378185528; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1378185828; 1; 2599.999343; 69.33331581333334; 2.666666666666667; 2097152.0; 619357.0666666667; 161.0; 22.0; 0.06666666666666667; 0.4 +1378186128; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 404049.3333333333; 0.0; 2.7333333333333334; 0.0; 0.0 +1378186428; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 234879.73333333334; 31.8; 14.466666666666667; 0.0; 0.0 +1378186728; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 190140.0; 0.0; 8.866666666666667; 0.2; 0.13333333333333333 +1378187028; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 178955.46666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1378187328; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.2; 0.0; 0.0 +1378187628; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1378187928; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378188228; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157985.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378188529; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 116041.06666666667; 0.4; 2.8; 0.06666666666666667; 0.5333333333333333 +1378188829; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378189129; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378189429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378189729; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378190029; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 146799.73333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.06666666666666667 +1378190329; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 138410.66666666666; 0.0; 1.7333333333333334; 0.0; 0.0 +1378190629; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378190929; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 153789.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378191229; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378191529; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378191829; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1378192129; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 139808.26666666666; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378192429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 145401.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378192729; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 157984.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378193029; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378193329; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378193629; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378193929; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 135614.13333333333; 12.733333333333333; 13.666666666666666; 0.3333333333333333; 0.13333333333333333 +1378194229; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.6; 0.13333333333333333; 0.0 +1378194529; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.2; 0.06666666666666667; 0.0 +1378194829; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378195129; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.06666666666666667; 0.0 +1378195429; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378195729; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.06666666666666667; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1378196029; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378196329; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1378196629; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378196929; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378197229; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378197529; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378197829; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378198129; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.0; 0.0 +1378198429; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378198730; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378199030; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1378199330; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 146800.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378199630; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378199930; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378200230; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378200530; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378200830; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378201130; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378201430; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378201730; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378202030; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378202330; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378202630; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378202930; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.4; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378203230; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378203530; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378203830; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137012.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378204130; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378204430; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378204730; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378205030; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378205330; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123031.73333333334; 0.0; 1.2; 0.0; 0.0 +1378205630; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378205930; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378206230; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378206530; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.26666666666; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378206831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 141206.93333333332; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378207131; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 1.3333333333333333; 6.133333333333334; 0.0; 0.0 +1378207431; 1; 2599.999343; 32.93332501133333; 1.2666666666666666; 2097152.0; 171964.8; 21.6; 7.2; 0.06666666666666667; 0.0 +1378207731; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378208031; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 141207.46666666667; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378208331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378208631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378208931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1378209231; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378209531; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378209831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378210131; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150992.8; 0.06666666666666667; 2.6; 0.06666666666666667; 0.5333333333333333 +1378210431; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174761.06666666668; 0.0; 1.0; 0.0; 0.0 +1378210731; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.2; 0.13333333333333333; 0.0 +1378211031; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378211331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378211631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378211931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 146799.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378212231; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378212531; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378212831; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.13333333333; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 +1378213131; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378213431; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378213731; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 137012.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378214031; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.6; 0.0; 1.0; 0.0; 0.0 +1378214331; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378214631; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378214931; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378215231; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378215531; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378215831; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378216131; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378216431; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378216731; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.2; 0.0 +1378217031; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131420.26666666666; 0.0; 1.0; 0.0; 0.0 +1378217331; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 152392.0; 0.0; 2.4; 0.06666666666666667; 0.5333333333333333 +1378217631; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 162178.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378217932; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378218232; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378218532; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378218832; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.13333333333333333 +1378219132; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 6.466666666666667; 0.2; 0.13333333333333333 +1378219432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.6666666666666667; 0.0; 0.0 +1378219732; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378220032; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378220332; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378220632; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378220932; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118836.53333333334; 0.0; 2.2; 0.06666666666666667; 0.5333333333333333 +1378221232; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 176159.2; 0.0; 1.0; 0.2; 0.0 +1378221532; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378221832; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378222132; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 82485.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378222432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378222732; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378223032; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378223332; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378223632; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 +1378223932; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378224232; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378224532; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.26666666666666666; 2.8; 0.06666666666666667; 0.4666666666666667 +1378224832; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.8; 0.4666666666666667; 0.0 +1378225132; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378225432; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1378225732; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 5.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378226032; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 2.4; 0.3333333333333333; 0.0 +1378226332; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378226632; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378226932; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1378227232; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378227533; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378227833; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378228133; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1378228433; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.4; 0.0; 1.0; 0.0; 0.0 +1378228733; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.4; 0.0; 0.0 +1378229033; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378229333; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378229633; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378229933; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378230233; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 12.066666666666666; 0.0; 0.0 +1378230533; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378230833; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378231133; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378231433; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378231733; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139808.53333333333; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378232033; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 164974.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378232333; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378232633; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378232933; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 7.333333333333333; 0.26666666666666666; 0.13333333333333333 +1378233233; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378233533; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378233833; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378234133; 1; 2599.999343; 71.06664870866665; 2.733333333333333; 2097152.0; 789924.8; 161.06666666666666; 22.2; 0.06666666666666667; 0.4 +1378234433; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 331348.0; 0.0; 2.933333333333333; 0.0; 0.0 +1378234733; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 188741.6; 31.8; 3.466666666666667; 0.0; 0.0 +1378235033; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 150993.6; 0.8; 2.3333333333333335; 0.06666666666666667; 0.0 +1378235333; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 188741.6; 0.06666666666666667; 3.466666666666667; 0.13333333333333333; 0.5333333333333333 +1378235633; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159382.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378235933; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378236233; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378236533; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378236834; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378237134; 1; 2599.999343; 46.799988174; 1.8; 2097152.0; 208315.73333333334; 161.8; 14.8; 0.0; 0.13333333333333333 +1378237434; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 469760.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1378237734; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 191538.4; 31.8; 4.066666666666666; 0.0; 0.0 +1378238034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 213908.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378238334; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378238634; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1378238934; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 146798.4; 0.0; 2.066666666666667; 0.06666666666666667; 0.5333333333333333 +1378239234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 163576.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378239534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378239834; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378240134; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378240434; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 +1378240734; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378241034; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378241334; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378241634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378241934; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378242234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378242534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 2.6; 0.0; 0.5333333333333333 +1378242834; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378243134; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 113244.0; 0.0; 0.8; 0.0; 0.0 +1378243434; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378243734; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118836.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378244034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378244334; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378244634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 7.2; 0.2; 0.13333333333333333 +1378244934; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378245234; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378245534; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8; 0.0; 0.0 +1378245834; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378246134; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378246434; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1378246734; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378247034; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378247334; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378247634; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132817.86666666667; 0.06666666666666667; 1.5333333333333334; 0.0; 0.06666666666666667 +1378247935; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378248235; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378248535; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378248835; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378249135; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378249435; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378249735; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.33333333334; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378250035; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378250335; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378250635; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378250935; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 103457.86666666667; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1378251235; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 148198.13333333333; 0.0; 2.066666666666667; 0.0; 0.0 +1378251536; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1378251836; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378252136; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.6; 0.0; 0.0 +1378252436; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1378252736; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378253036; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378253336; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378253636; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163576.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378253936; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 150994.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378254236; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378254536; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378254836; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 114642.93333333333; 0.5333333333333333; 1.4666666666666666; 0.0; 0.0 +1378255136; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378255436; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378255736; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378256036; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378256336; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.0; 0.0 +1378256636; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378256936; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 176159.2; 0.2; 2.533333333333333; 0.0; 0.5333333333333333 +1378257236; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150992.8; 0.06666666666666667; 1.0; 0.0; 0.0 +1378257536; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1378257836; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 12.8; 13.0; 0.4; 0.13333333333333333 +1378258136; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378258436; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 152391.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378258736; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378259036; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1378259336; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378259636; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378259936; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378260236; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378260537; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 157983.46666666667; 0.0; 2.6; 0.0; 0.5333333333333333 +1378260837; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378261137; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 166373.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378261437; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378261737; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378262037; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378262337; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378262637; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378262937; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378263237; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.0; 1.2; 0.0; 0.0 +1378263537; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 110447.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378263837; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378264137; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 138410.4; 0.0; 2.2; 0.0; 0.4666666666666667 +1378264437; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 148197.33333333334; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1378264737; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 163577.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378265037; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378265337; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378265637; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1378265937; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378266237; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378266537; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378266837; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378267137; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378267437; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 104856.0; 1.4666666666666666; 1.4; 0.0; 0.0 +1378267737; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 141206.66666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378268037; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378268338; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378268638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378268938; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378269238; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378269538; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1378269838; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1378270138; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378270438; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378270738; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1378271038; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378271338; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 166372.26666666666; 0.06666666666666667; 2.6; 0.0; 0.5333333333333333 +1378271638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 139809.33333333334; 0.0; 7.0; 0.26666666666666666; 0.2 +1378271938; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 146800.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378272238; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378272538; 1; 2599.999343; 5.199998686; 0.2; 2097152.0; 121633.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378272838; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378273138; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 135614.93333333332; 0.0; 0.6; 0.0; 0.0 +1378273438; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378273738; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 100661.6; 0.0; 11.666666666666666; 0.06666666666666667; 0.0 +1378274038; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378274338; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378274638; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378274938; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 121633.6; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378275238; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 155188.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378275538; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378275838; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378276138; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378276438; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 117439.2; 0.0; 2.4; 0.06666666666666667; 0.13333333333333333 +1378276738; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.5333333333333334; 0.0; 0.0 +1378277038; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1378277338; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378277638; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 6.933333333333334; 0.4666666666666667; 0.13333333333333333 +1378277938; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378278238; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378278538; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 156586.93333333332; 0.0; 2.6; 0.0; 0.5333333333333333 +1378278838; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 156584.8; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378279138; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1378279438; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 124428.8; 0.0; 1.0; 0.0; 0.0 +1378279738; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378280038; 1; 2599.999343; 32.93332501133333; 1.2666666666666666; 2097152.0; 164974.66666666666; 161.13333333333333; 20.4; 0.06666666666666667; 0.4 +1378280338; 1; 2599.999343; 53.733319755333326; 2.0666666666666664; 2097152.0; 759166.4; 0.0; 3.6666666666666665; 0.0; 0.0 +1378280638; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 314570.4; 31.8; 3.7333333333333334; 0.0; 0.0 +1378280938; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 204119.46666666667; 0.0; 2.8; 0.0; 0.0 +1378281238; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 183149.06666666668; 0.0; 2.066666666666667; 0.0; 0.0 +1378281538; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 148197.86666666667; 0.0; 1.0; 0.0; 0.0 +1378281838; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.13333333333333333; 0.0 +1378282138; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163575.73333333334; 0.06666666666666667; 2.533333333333333; 0.0; 0.5333333333333333 +1378282438; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 170566.66666666666; 0.0; 1.2; 0.0; 0.0 +1378282739; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378283039; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378283339; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378283639; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378283939; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378284239; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378284539; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 135614.93333333332; 0.06666666666666667; 7.133333333333334; 0.2; 0.13333333333333333 +1378284839; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116040.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378285139; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378285439; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378285739; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378286039; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 142605.06666666668; 0.0; 1.0; 0.0; 0.0 +1378286339; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 139809.06666666668; 0.0; 1.0; 0.0; 0.0 +1378286639; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1378286939; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378287239; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378287539; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378287839; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378288139; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 137013.06666666668; 20.4; 2.3333333333333335; 0.0; 0.06666666666666667 +1378288439; 1; 2599.999343; 29.466659220666667; 1.1333333333333333; 2097152.0; 135614.93333333332; 0.0; 3.933333333333333; 0.0; 0.0 +1378288739; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 127226.13333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1378289039; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 152390.93333333332; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378289340; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.06666666666666667; 2.7333333333333334; 0.0; 0.4666666666666667 +1378289640; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 166372.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378289940; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1378290240; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 160780.53333333333; 0.0; 1.0; 0.0; 0.0 +1378290540; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378290840; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 90874.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378291140; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378291440; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378291740; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378292040; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378292340; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378292640; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378292940; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.06666666667; 0.13333333333333333; 2.6666666666666665; 0.06666666666666667; 0.5333333333333333 +1378293240; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 174760.8; 0.0; 1.0; 0.0; 0.0 +1378293540; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378293840; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378294140; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378294440; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378294740; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378295040; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378295340; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1378295640; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378295940; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.8; 0.0; 0.0 +1378296240; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 156585.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378296540; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 191538.13333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378296840; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 194334.66666666666; 0.0; 6.733333333333333; 0.2; 0.13333333333333333 +1378297140; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 181751.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378297441; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378297741; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378298041; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378298341; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378298641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378298941; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109049.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378299241; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378299541; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378299841; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 160780.0; 0.0; 1.0; 0.0; 0.0 +1378300141; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 162177.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378300441; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 1.2; 0.0; 0.0 +1378300741; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378301041; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 148198.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378301341; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378301641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 102059.73333333334; 0.9333333333333333; 1.7333333333333334; 0.0; 0.0 +1378301941; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378302241; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378302541; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378302841; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378303141; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378303441; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 111846.66666666667; 0.0; 7.466666666666667; 0.2; 0.13333333333333333 +1378303741; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 160780.0; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378304041; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 174760.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378304341; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378304642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 81087.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378304942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378305242; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 177557.06666666668; 0.2; 1.2; 0.06666666666666667; 0.13333333333333333 +1378305542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378305842; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378306142; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1378306442; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378306742; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378307042; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 149595.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378307342; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 138410.13333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378307641; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378307941; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378308241; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378308541; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378308841; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378309141; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378309441; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.2; 0.0 +1378309741; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 148198.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378310041; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378310341; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.93333333333; 0.0; 7.133333333333334; 0.4; 0.13333333333333333 +1378310641; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378310941; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 2.466666666666667; 0.8666666666666667; 0.5333333333333333 +1378311241; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 +1378311541; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1378311842; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378312142; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378312442; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378312742; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378313042; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 141207.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378313342; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378313642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378313942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378314242; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 114642.93333333333; 0.0; 1.8666666666666667; 0.0; 0.0 +1378314542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 150993.86666666667; 0.0; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378314842; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 174760.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378315142; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378315442; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378315742; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 86680.26666666666; 12.733333333333333; 13.533333333333333; 0.4666666666666667; 0.2 +1378316042; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.4666666666666666; 0.06666666666666667; 0.0 +1378316342; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378316642; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378316942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.8666666666666667; 0.0 +1378317242; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 104855.2; 0.0; 11.866666666666667; 0.2; 0.0 +1378317542; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378317842; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.4666666666666666; 0.0; 0.0 +1378318142; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 130022.13333333333; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1378318442; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 138410.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378318742; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378319042; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378319342; 1; 2599.999343; 6.933331581333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378319642; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378319942; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 148197.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378320243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378320543; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378320843; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378321143; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.6; 0.0; 0.0 +1378321443; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378321743; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378322043; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 178955.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378322343; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 120235.46666666666; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378322643; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 148197.33333333334; 0.0; 1.2; 0.0; 0.0 +1378322943; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378323243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378323543; 1; 2599.999343; 39.866656592666665; 1.5333333333333334; 2097152.0; 160779.73333333334; 161.0; 14.4; 0.0; 0.2 +1378323843; 1; 2599.999343; 27.733326325333334; 1.0666666666666667; 2097152.0; 443195.73333333334; 0.0; 1.5333333333333334; 0.0; 0.0 +1378324143; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 184547.2; 31.8; 4.066666666666666; 0.0; 0.0 +1378324443; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 192936.26666666666; 0.0; 1.0; 0.0; 0.0 +1378324743; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 120234.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378325043; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378325343; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 121632.8; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378325643; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 123030.93333333333; 0.0; 1.2; 0.0; 0.0 +1378325943; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378326243; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378326543; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378326843; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1378327143; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378327443; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378327743; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378328043; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378328343; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.3333333333333333; 0.0; 0.0 +1378328643; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 114642.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378328943; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 159381.6; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378329244; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 190139.46666666667; 0.0; 7.933333333333334; 0.2; 0.13333333333333333 +1378329544; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 153790.13333333333; 0.0; 1.2; 0.0; 0.0 +1378329844; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378330144; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 82485.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378330444; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378330744; 1; 2599.999343; 8.666664476666668; 0.33333333333333337; 2097152.0; 149595.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378331044; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378331344; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378331644; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378331944; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378332244; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378332544; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 127225.86666666667; 0.06666666666666667; 2.8; 0.06666666666666667; 0.5333333333333333 +1378332844; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 103457.33333333333; 0.0; 1.0; 0.0; 0.0 +1378333144; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378333444; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1378333744; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378334044; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 +1378334344; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 132817.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378334644; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 110448.53333333334; 0.0; 7.2; 0.2; 0.13333333333333333 +1378334944; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 145401.06666666668; 0.0; 1.0666666666666667; 0.0; 0.0 +1378335244; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 169169.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1378335544; 1; 2599.999343; 65.86665002266666; 2.533333333333333; 2097152.0; 485139.4666666667; 161.0; 21.333333333333332; 0.06666666666666667; 0.4 +1378335844; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 588599.4666666667; 1.0666666666666667; 3.066666666666667; 0.0; 0.0 +1378336144; 1; 2599.999343; 24.266660534666663; 0.9333333333333332; 2097152.0; 306181.86666666664; 32.666666666666664; 5.6; 0.06666666666666667; 0.4666666666666667 +1378336444; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 236276.53333333333; 0.0; 2.466666666666667; 0.0; 0.0 +1378336744; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 169169.6; 0.0; 1.6666666666666667; 0.0; 0.0 +1378337045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 110448.53333333334; 0.06666666666666667; 0.8666666666666667; 0.0; 0.0 +1378337345; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 3.8; 1.4; 0.0; 0.0 +1378337645; 1; 2599.999343; 22.533327639333333; 0.8666666666666667; 2097152.0; 156586.13333333333; 0.4; 3.2666666666666666; 0.0; 0.0 +1378337945; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378338245; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378338545; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378338845; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378339145; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378339445; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378339745; 1; 2599.999343; 20.799994744; 0.8; 2097152.0; 118837.33333333333; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.5333333333333333 +1378340045; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378340345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 128623.46666666666; 0.0; 0.8; 0.0; 0.0 +1378340645; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.0; 0.0; 0.0 +1378340945; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 72698.93333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378341245; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.6; 7.333333333333333; 0.2; 0.13333333333333333 +1378341545; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378341845; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378342145; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 75495.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378342445; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0; 0.0; 0.0 +1378342745; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378343045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378343345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 153789.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378343645; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 152391.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378343945; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 152391.73333333334; 0.0; 1.0; 0.0; 0.0 +1378344245; 1; 2599.999343; 17.333328953333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378344545; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378344845; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 1.4666666666666666; 0.0; 0.0 +1378345145; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378345445; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1378345745; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378346045; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378346345; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378346645; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378346945; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378347245; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 163576.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378347545; 1; 2599.999343; 19.066661848666666; 0.7333333333333333; 2097152.0; 120235.46666666666; 0.0; 7.466666666666667; 0.3333333333333333; 0.13333333333333333 +1378347845; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 123030.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378348145; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 144002.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378348445; 1; 2599.999343; 10.399997372; 0.4; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378348745; 1; 2599.999343; 12.133330267333331; 0.4666666666666666; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378349045; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378349345; 1; 2599.999343; 15.599996057999999; 0.6; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378349645; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378349945; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378350245; 1; 2599.999343; 13.866663162666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378350545; 1; 2599.999601; 25.99999601; 1.0; 2097152.0; 167772.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378350845; 1; 2599.999601; 19.066663740666666; 0.7333333333333333; 2097152.0; 167772.0; 0.0; 1.1333333333333333; 0.2; 0.0 +1378351145; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378351445; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378351745; 1; 2599.999601; 12.133331471333332; 0.4666666666666666; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378352046; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 103457.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378352346; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 109049.86666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378352646; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378352946; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.4666666666666666; 0.0; 0.0 +1378353246; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378353546; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378353846; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.06666666666666667; 6.533333333333333; 0.26666666666666666; 0.13333333333333333 +1378354146; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 180353.6; 0.0; 2.6666666666666665; 0.06666666666666667; 0.4666666666666667 +1378354446; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378354746; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 1.0; 0.0; 0.0 +1378355046; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378355346; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378355646; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378355946; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 1.4; 0.0; 0.0 +1378356246; 1; 2599.999601; 0.0; 0.0; 2097152.0; 127225.33333333333; 0.0; 1.0; 0.0; 0.0 +1378356546; 1; 2599.999601; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378356846; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378357146; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378357446; 1; 2599.999601; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378357746; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378358046; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378358346; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378358646; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378358947; 1; 2599.999601; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.6666666666666667; 0.0; 0.0 +1378359247; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378359547; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378359847; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378360147; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378360447; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378360747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378361047; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 123031.73333333334; 0.0; 11.866666666666667; 0.0; 0.0 +1378361347; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 155186.93333333332; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378361647; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 171965.6; 0.0; 0.8666666666666667; 4.4; 0.0 +1378361947; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 162177.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378362247; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 1.2; 0.26666666666666666; 0.0 +1378362547; 1; 2599.999601; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378362847; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 173362.13333333333; 0.06666666666666667; 2.8666666666666667; 0.13333333333333333; 0.13333333333333333 +1378363147; 1; 2599.999601; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 1.7333333333333334; 0.0; 0.0 +1378363447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378363747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378364047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378364347; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378364647; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378364947; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 149595.46666666667; 0.26666666666666666; 2.4; 0.06666666666666667; 0.5333333333333333 +1378365247; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 180352.8; 0.0; 1.0; 0.0; 0.0 +1378365547; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 134216.8; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378365847; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378366147; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378366447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378366747; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378367047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 155188.0; 0.0; 1.7333333333333334; 0.0; 0.0 +1378367347; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.2; 0.0 +1378367647; 1; 2599.999601; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 1.0; 0.0; 0.0 +1378367947; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378368247; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378368547; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 146799.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378368848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378369148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378369448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378369748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378370048; 1; 2599.999601; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378370348; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378370648; 1; 2599.999601; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378370948; 1; 2599.999601; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378371248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378371548; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378371848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378372148; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 141206.66666666666; 0.0; 8.2; 0.26666666666666666; 0.6666666666666666 +1378372448; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 1.2; 0.0; 0.0 +1378372748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150994.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378373047; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378373347; 1; 2599.999601; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378373647; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378373947; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378374247; 1; 2599.999601; 8.666665336666668; 0.33333333333333337; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378374547; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378374847; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378375147; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378375447; 1; 2599.999601; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.8; 0.0; 0.0 +1378375747; 1; 2599.999601; 5.199999202; 0.2; 2097152.0; 117439.2; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378376047; 1; 2599.999601; 3.4666661346666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378376347; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378376648; 1; 2599.999601; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378376948; 1; 2599.999601; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378377248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378377548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378377848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378378148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 152391.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378378448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378378748; 1; 2599.999601; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378379048; 1; 2599.999601; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378379348; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 142605.6; 13.0; 18.6; 0.3333333333333333; 0.6 +1378379648; 1; 2599.999601; 10.399998404; 0.4; 2097152.0; 130021.6; 0.0; 1.2; 0.0; 0.0 +1378379948; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378380248; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378380548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 109049.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378380848; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 54523.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378381148; 1; 2599.999601; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1378381448; 1; 2599.999601; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.4; 0.0; 0.0 +1378381748; 1; 2599.999601; 1.7333330673333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378382048; 1; 2599.999601; 13.866664538666667; 0.5333333333333333; 2097152.0; 134216.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378382348; 1; 2599.999601; 6.9333322693333335; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1378382648; 1; 2599.999601; 17.333330673333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378382948; 1; 2599.999601; 15.599997605999999; 0.6; 2097152.0; 155187.2; 0.06666666666666667; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1378383248; 1; 2599.999601; 0.0; 0.0; 2097152.0; 150992.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378383548; 1; 2599.999601; 0.0; 0.0; 2097152.0; 141206.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378383848; 1; 2599.999601; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378384149; 1; 2599.999601; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378384449; 1; 2599.998989; 51.999979780000004; 2.0; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378384749; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378385049; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378385349; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378385649; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 139809.33333333334; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1378385949; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378386249; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378386549; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.6; 0.0; 2.533333333333333; 0.13333333333333333; 0.5333333333333333 +1378386849; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 159381.86666666667; 0.0; 0.8; 0.0; 0.0 +1378387149; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 0.6666666666666666; 0.13333333333333333; 0.0 +1378387449; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378387749; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378388049; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378388349; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 118837.33333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378388649; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378388949; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378389249; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378389549; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 109050.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1378389849; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378390149; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 138410.4; 0.2; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378390449; 1; 2599.998989; 74.53330435133334; 2.8666666666666667; 2097152.0; 250258.93333333332; 161.0; 21.8; 0.06666666666666667; 0.3333333333333333 +1378390749; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 717224.5333333333; 0.0; 2.533333333333333; 0.06666666666666667; 0.0 +1378391049; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 359310.13333333336; 31.8; 3.6; 0.0; 0.0 +1378391949; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 145401.86666666667; 0.0; 1.0; 0.0; 0.0 +1378392249; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 130022.4; 0.0; 6.4; 0.2; 0.13333333333333333 +1378392549; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 118837.33333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378392849; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.2; 0.0 +1378393149; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378393449; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378393749; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 181751.46666666667; 0.0; 2.2; 0.06666666666666667; 0.4666666666666667 +1378394050; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 149595.73333333334; 0.0; 0.6; 0.06666666666666667; 0.0 +1378394350; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 +1378394650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 145401.06666666668; 0.0; 1.2; 0.0; 0.0 +1378394950; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.06666666666666667; 0.0 +1378395250; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 96467.2; 0.0; 0.6666666666666666; 0.0; 0.0 +1378395550; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378395850; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378396150; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378396450; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127225.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378396750; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378397050; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142605.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378397350; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 131420.53333333333; 0.0; 2.7333333333333334; 0.13333333333333333; 0.5333333333333333 +1378397650; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 149595.46666666667; 0.0; 0.8; 0.0; 0.0 +1378397950; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378398250; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378398550; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378398850; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125828.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378399150; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 120234.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378399450; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378399750; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 1.0; 0.13333333333333333; 0.0 +1378400050; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378400350; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378400650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378400950; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125827.2; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378401250; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 150994.4; 0.0; 1.0; 0.0; 0.0 +1378401550; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1378401850; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378402150; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378402450; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378402750; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378403050; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378403350; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.7333333333333334; 0.0; 0.0 +1378403650; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378403951; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378404251; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 117439.2; 0.0; 1.6; 0.0; 0.0 +1378404551; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 146798.4; 0.0; 13.0; 0.06666666666666667; 0.4666666666666667 +1378404851; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 178954.66666666666; 0.0; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378405151; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 163575.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378405451; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378405750; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138411.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378406050; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378406350; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378406650; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378406950; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378407250; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378407550; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378407850; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378408150; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 164974.13333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378408450; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 146799.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378408751; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378409051; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378409351; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378409651; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378409951; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378410251; 1; 2599.998989; 51.999979780000004; 2.0; 2097152.0; 591395.2; 161.73333333333332; 14.2; 0.0; 0.2 +1378410551; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 272627.2; 0.0; 1.5333333333333334; 0.0; 0.0 +1378410851; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159383.2; 31.8; 3.533333333333333; 0.0; 0.0 +1378411151; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1378411451; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 4.466666666666667; 0.0 +1378411751; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 159382.4; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378412051; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159382.4; 0.0; 0.8; 0.0; 0.0 +1378412351; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378412651; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378412951; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378413251; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 159382.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378413551; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378413851; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378414151; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378414451; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 113244.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378414751; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378415051; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378415351; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.13333333333333333; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1378415651; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378415951; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378416251; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378416551; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378416851; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378417152; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 85282.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378417452; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378417752; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 78291.46666666666; 0.0; 7.333333333333333; 0.26666666666666666; 0.2 +1378418052; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378418352; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 71300.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378418652; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378418952; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 127226.13333333333; 0.06666666666666667; 2.1333333333333333; 0.0; 0.4666666666666667 +1378419252; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138411.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378419552; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378419852; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378420152; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378420452; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 125827.2; 0.0; 1.6; 0.06666666666666667; 0.13333333333333333 +1378420752; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378421052; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378421352; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378421652; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378421952; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 74097.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378422252; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378422552; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144002.93333333332; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1378422852; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378423152; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378423452; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378423752; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378424052; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378424352; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378424653; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.06666666666666667; 6.333333333333333; 0.2; 0.13333333333333333 +1378424953; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 2.1333333333333333; 0.0; 0.0 +1378425253; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378425553; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378425853; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378426153; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378426453; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 132817.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378426753; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378427053; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378427353; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378427653; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 146799.2; 0.5333333333333333; 1.4; 0.0; 0.0 +1378427953; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 116041.06666666667; 0.0; 1.4; 0.0; 0.0 +1378428253; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378428553; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378428853; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378429153; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 150994.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378429453; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 138410.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378429753; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378430053; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 162178.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378430353; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 120235.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378430653; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378430953; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378431253; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378431553; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378431853; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378432153; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378432453; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378432753; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378433054; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1378433354; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 118836.8; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378433654; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.66666666666; 0.0; 1.6666666666666667; 0.0; 0.0 +1378433954; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 167770.4; 0.0; 1.2; 0.0; 0.0 +1378434254; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1378434554; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378434854; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378435154; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378435454; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378435754; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378436054; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1378436354; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378436654; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378436954; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 157983.73333333334; 0.4; 2.1333333333333333; 0.06666666666666667; 0.4666666666666667 +1378437254; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 208316.0; 12.733333333333333; 13.2; 0.3333333333333333; 0.13333333333333333 +1378437554; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378437854; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378438154; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378438454; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378438754; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378439053; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378439354; 1; 2599.998989; 69.33330637333334; 2.666666666666667; 2097152.0; 310376.8; 161.0; 22.266666666666666; 0.06666666666666667; 0.3333333333333333 +1378439654; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 666892.2666666667; 0.0; 2.466666666666667; 0.0; 0.0 +1378439954; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 279618.4; 31.8; 3.533333333333333; 0.0; 0.0 +1378440254; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 194334.66666666666; 0.8; 2.533333333333333; 0.0; 0.0 +1378440554; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 187343.46666666667; 0.0; 3.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378440854; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 195732.8; 0.0; 1.0; 0.0; 0.0 +1378441154; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378441454; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378441754; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378442054; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378442354; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 121632.8; 0.0; 1.0; 0.0; 0.0 +1378442654; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.0; 0.0 +1378442954; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378443254; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 153789.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378443554; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378443854; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 1.0; 0.0; 0.0 +1378444154; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 187343.73333333334; 0.06666666666666667; 2.7333333333333334; 0.06666666666666667; 0.5333333333333333 +1378444454; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 159382.13333333333; 0.0; 1.0; 0.0; 0.0 +1378444754; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 156586.13333333333; 0.0; 1.0; 0.0; 0.0 +1378445054; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378445354; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378445654; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378445954; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1378446254; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378446554; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378446855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 142605.6; 0.0; 1.0; 0.0; 0.0 +1378447155; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1378447455; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378447755; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.06666666666666667; 3.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378448055; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378448355; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132817.86666666667; 0.0; 11.933333333333334; 0.0; 0.0 +1378448655; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1378448955; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378449255; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 120235.46666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.13333333333333333 +1378449555; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 164974.93333333332; 0.0; 1.7333333333333334; 0.0; 0.0 +1378449855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 6.666666666666667; 0.2; 0.13333333333333333 +1378450155; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 1.8666666666666667; 0.0; 0.0 +1378450455; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 1.2; 0.0; 0.0 +1378450755; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378451055; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137012.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378451355; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.66666666666; 0.0; 2.6; 0.06666666666666667; 0.5333333333333333 +1378451655; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 142604.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378451955; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378452255; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378452555; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378452855; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127225.06666666667; 0.0; 1.2; 0.0; 0.0 +1378453155; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378453455; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.2; 0.0; 0.0 +1378453755; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.93333333332; 0.0; 1.1333333333333333; 0.0; 0.0 +1378454055; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 138411.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378454355; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378454655; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378454955; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 2.066666666666667; 0.06666666666666667; 0.4666666666666667 +1378455255; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378455555; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378455855; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378456155; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378456456; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378456756; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378457056; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132818.66666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378457356; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378457656; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138410.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378457956; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378458256; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378458556; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 155186.93333333332; 0.06666666666666667; 2.4; 0.06666666666666667; 0.5333333333333333 +1378458856; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 157983.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378459156; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 127225.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378459456; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378459756; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378460056; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378460356; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378460656; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378460956; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378461256; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378461556; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378461856; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378462156; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 132818.4; 0.06666666666666667; 2.2; 0.06666666666666667; 0.5333333333333333 +1378462456; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 152391.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378462756; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378463056; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 99263.46666666666; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378463356; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378463657; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378463957; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 +1378464257; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1378464557; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378464857; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378465157; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378465457; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127226.13333333333; 0.0; 0.8; 0.13333333333333333; 0.0 +1378465757; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 142605.33333333334; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1378466057; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 176159.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378466357; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378466657; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378466957; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378467257; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378467557; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378467857; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378468157; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 109050.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1378468457; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 7.0; 0.2; 0.13333333333333333 +1378468757; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378469057; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378469657; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 180352.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378470257; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378470557; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.2; 0.0 +1378470857; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.2; 0.06666666666666667; 0.0 +1378471157; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 1.2; 0.06666666666666667; 0.0 +1378472057; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378472657; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.2666666666666666; 0.13333333333333333; 0.0 +1378472957; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 137012.0; 0.06666666666666667; 2.6666666666666665; 0.13333333333333333; 0.4666666666666667 +1378473257; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130021.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378473557; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 79689.6; 0.0; 1.2666666666666666; 0.2; 0.0 +1378473857; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378474157; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.2; 0.0 +1378474457; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.26666666666666666; 0.0 +1378474757; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 +1378475057; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378475358; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 99263.46666666666; 0.0; 7.266666666666667; 0.26666666666666666; 0.13333333333333333 +1378475658; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.2; 0.0 +1378475958; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 88078.4; 0.0; 1.0; 0.13333333333333333; 0.0 +1378476258; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 121633.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378476558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 160779.46666666667; 0.06666666666666667; 2.533333333333333; 0.2; 0.5333333333333333 +1378476858; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 162178.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378477158; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378477458; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1378477758; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1378478058; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 131419.73333333334; 0.06666666666666667; 1.2; 0.06666666666666667; 0.13333333333333333 +1378478358; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 92272.8; 0.0; 1.2; 0.0; 0.0 +1378478658; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.2; 0.0 +1378478958; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 106253.33333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1378479258; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378479558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 1.2; 0.0 +1378479858; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378480158; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 128623.2; 0.0; 2.2; 0.26666666666666666; 0.5333333333333333 +1378480458; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118836.8; 0.0; 1.1333333333333333; 0.13333333333333333; 0.0 +1378480758; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 74097.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378481058; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378481358; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378481658; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378481958; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378482258; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 2.466666666666667; 0.26666666666666666; 0.13333333333333333 +1378482558; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 142604.8; 0.0; 5.933333333333334; 0.0; 0.0 +1378482858; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378483158; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1378483459; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378483759; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 113244.8; 0.06666666666666667; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378484059; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378484359; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378484659; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378484959; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378485259; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378485559; 1; 2599.998989; 64.13330839533334; 2.466666666666667; 2097152.0; 350922.4; 161.06666666666666; 22.0; 2.1333333333333333; 0.4 +1378485859; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 706038.4; 0.0; 2.8; 0.0; 0.0 +1378486159; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 290803.2; 31.8; 3.7333333333333334; 0.0; 0.0 +1378486459; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 198527.73333333334; 0.26666666666666666; 2.2666666666666666; 0.0; 0.0 +1378486759; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 124429.86666666667; 0.0; 1.6; 0.13333333333333333; 0.0 +1378487059; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378487359; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 128623.46666666666; 0.0; 2.2666666666666666; 0.06666666666666667; 0.4666666666666667 +1378487659; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 156586.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378487959; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378488259; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 171964.8; 0.0; 6.866666666666666; 0.5333333333333333; 0.13333333333333333 +1378488559; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378488859; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378489159; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378489459; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378489759; 1; 2599.998989; 0.0; 0.0; 2097152.0; 163576.53333333333; 0.0; 0.9333333333333333; 0.2; 0.0 +1378490059; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 152390.66666666666; 0.0; 1.0; 0.2; 0.0 +1378490359; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.13333333333333333; 0.0 +1378490659; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378490959; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 118837.06666666667; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378491259; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 137012.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378491559; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378491859; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 11.8; 0.0; 0.0 +1378492159; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.06666666667; 0.0; 0.8; 0.0; 0.0 +1378492459; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.73333333334; 0.0; 1.6666666666666667; 0.0; 0.0 +1378492759; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.3333333333333333; 0.0; 0.0 +1378493059; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 1.0; 0.0; 0.0 +1378493360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378493660; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128623.46666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378493960; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378494260; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 104856.0; 0.0; 7.4; 0.26666666666666666; 0.13333333333333333 +1378494560; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 183149.6; 0.06666666666666667; 2.4; 0.0; 0.5333333333333333 +1378494860; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 164974.4; 0.0; 1.7333333333333334; 0.0; 0.0 +1378495160; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378495460; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1378495760; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378496060; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378496360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378496660; 1; 2599.998989; 41.599983824; 1.6; 2097152.0; 450186.93333333335; 161.8; 14.733333333333333; 0.0; 0.2 +1378496960; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 205519.46666666667; 0.0; 1.6; 0.0; 0.0 +1378497260; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 194333.33333333334; 31.8; 3.6; 0.0; 0.0 +1378497560; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378497860; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378498160; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 127225.06666666667; 0.0; 2.533333333333333; 0.0; 0.5333333333333333 +1378498460; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 156585.6; 0.0; 1.0; 0.0; 0.0 +1378498760; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1378499060; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378499360; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378499660; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 162177.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378499960; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 124429.86666666667; 12.733333333333333; 12.866666666666667; 0.4; 0.13333333333333333 +1378500260; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 1.3333333333333333; 0.0; 0.0 +1378500560; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378500860; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378501160; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378501460; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378501760; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 156585.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.5333333333333333 +1378502060; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 208314.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378502360; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 139809.33333333334; 0.0; 1.0; 0.0; 0.0 +1378502660; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378502960; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378503260; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378503560; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378503860; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378504160; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106253.86666666667; 0.0; 0.8; 0.0; 0.0 +1378504460; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.33333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378504760; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378505060; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 1.0; 0.0; 0.0 +1378505360; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 170566.4; 0.06666666666666667; 2.6; 0.06666666666666667; 0.4666666666666667 +1378505660; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 183149.33333333334; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378505960; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378506260; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.0; 0.06666666666666667; 7.0; 0.3333333333333333; 0.13333333333333333 +1378506560; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378506860; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 134216.0; 0.06666666666666667; 1.5333333333333334; 0.4666666666666667; 0.06666666666666667 +1378507160; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378507460; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378507761; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378508061; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.0; 0.0 +1378508361; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378508661; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378508961; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 146799.2; 0.06666666666666667; 2.2; 0.0; 0.4666666666666667 +1378509261; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 134216.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378509561; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 148198.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378509861; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378510161; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378510461; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378510761; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378511061; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378511361; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378511661; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378511961; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378512261; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 138409.6; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378512561; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 138410.4; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378512861; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.0; 0.0 +1378513161; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378513461; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378513761; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 139809.33333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378514061; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 124429.06666666667; 0.5333333333333333; 1.3333333333333333; 0.13333333333333333; 0.0 +1378514361; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 144003.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378514661; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.4666666666666667; 0.0 +1378514961; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378515261; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.0; 0.0 +1378515561; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 55921.333333333336; 0.0; 0.9333333333333333; 0.0; 0.0 +1378515861; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378516161; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 146798.93333333332; 0.0; 2.6; 0.0; 0.5333333333333333 +1378516461; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 167770.66666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378516761; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 135613.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378517061; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 71300.8; 0.0; 1.0; 0.0; 0.0 +1378517361; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 72698.93333333333; 0.0; 1.0; 0.0; 0.0 +1378517661; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378517961; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 95069.06666666667; 0.0; 1.2; 0.0; 0.0 +1378518261; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 78291.46666666666; 0.2; 6.4; 0.2; 0.13333333333333333 +1378518561; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 163577.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 +1378518861; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378519161; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.0; 1.2; 0.06666666666666667; 0.0 +1378519461; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378519761; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.06666666668; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378520061; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 159381.06666666668; 0.0; 0.8; 0.0; 0.0 +1378520361; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.2; 0.0; 0.0 +1378520662; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378520962; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 10.266666666666667; 0.0 +1378521262; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378521562; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1378521862; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 83884.0; 0.0; 1.2666666666666666; 0.0; 0.0 +1378522162; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378522462; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 83884.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378522762; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378523062; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378523362; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124428.8; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1378523662; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 155187.2; 0.0; 1.0; 0.0; 0.0 +1378523962; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378524262; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378524562; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 8.2; 0.0 +1378524862; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378525162; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 6.733333333333333; 0.26666666666666666; 0.13333333333333333 +1378525462; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 65708.26666666666; 0.0; 1.4; 0.0; 0.0 +1378525762; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 139809.33333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1378526062; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378526362; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378526662; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 74097.06666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378527862; 1; 2599.998989; 16.714279215; 0.6428571428571429; 2097152.0; 107852.0; 0.0; 1.0714285714285714; 0.07692307692307693; 0.0 +1378528762; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.4; 0.0 +1378529062; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 96467.2; 0.0; 1.0; 5.066666666666666; 0.0 +1378529362; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378529662; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378529963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.6666666666666666; 0.0; 0.0 +1378530263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378530563; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 135614.93333333332; 0.06666666666666667; 8.333333333333334; 0.26666666666666666; 0.6 +1378530863; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 159381.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378531163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.8; 0.0; 0.0 +1378531463; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378531763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378532063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1378532363; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378532663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8; 0.06666666666666667; 0.0 +1378532963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378533263; 1; 2599.998989; 60.66664307666668; 2.3333333333333335; 2097152.0; 406845.3333333333; 161.06666666666666; 21.533333333333335; 0.06666666666666667; 0.4 +1378533563; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 562034.4; 0.0; 2.533333333333333; 0.06666666666666667; 0.0 +1378533863; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 293599.2; 31.8; 4.333333333333333; 0.06666666666666667; 0.0 +1378534163; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 251656.0; 0.8; 3.933333333333333; 0.06666666666666667; 0.4666666666666667 +1378534463; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 167770.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1378534763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378535063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378535363; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.8; 0.0; 0.0 +1378535663; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 13.4; 0.13333333333333333; 0.13333333333333333 +1378535963; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134215.2; 0.0; 1.4666666666666666; 0.13333333333333333; 0.0 +1378536263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121632.8; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1378536563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378536863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.5333333333333334; 0.0; 0.0 +1378537163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378537463; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1378537763; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378538063; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378538363; 1; 2599.998989; 0.0; 0.0; 2097152.0; 159383.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378538663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378538963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378539263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378539563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378539863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 2.066666666666667; 0.06666666666666667; 0.0 +1378540163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378540463; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378540763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378541063; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 118837.33333333333; 0.06666666666666667; 1.8666666666666667; 0.0; 0.0 +1378541363; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125827.2; 0.13333333333333333; 2.533333333333333; 0.0; 0.4666666666666667 +1378541663; 1; 2599.998989; 0.0; 0.0; 2097152.0; 148197.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378541963; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378542263; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378542563; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378542863; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378543163; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0; 1.8666666666666667; 0.0 +1378543463; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 134216.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378543763; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378544063; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378544364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378544664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378544964; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 146799.2; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378545264; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 149596.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378545564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378545864; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1378546164; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378546464; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378546764; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146798.93333333332; 0.0; 1.4; 0.0; 0.0 +1378547064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378547364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378547664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378547964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1378548264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378548564; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 125828.0; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378548864; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 1.0; 0.0; 0.0 +1378549164; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378549464; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1378549764; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138410.4; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378550064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378550364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378550664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378550964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378551264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378551564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378551864; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378552164; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138409.86666666667; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1378552464; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 213907.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378552764; 1; 2599.998989; 0.0; 0.0; 2097152.0; 155187.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378553064; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378553364; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.26666666666666666; 0.0 +1378553664; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378553964; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378554264; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378554564; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.06666666666666667; 0.0 +1378554865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378555165; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378555465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378555765; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.2; 0.06666666666666667; 8.733333333333333; 0.26666666666666666; 0.6 +1378556065; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.6; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378556365; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.0; 0.0 +1378556665; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378556965; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 4.2; 0.0 +1378557265; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378557565; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.0; 0.0 +1378557865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378558165; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378558465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 160779.46666666667; 0.0; 0.8; 0.0; 0.0 +1378558765; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 1.0; 0.0; 0.0 +1378559065; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 1.0; 0.0; 0.0 +1378559365; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 116040.53333333334; 0.0; 2.4; 0.0; 0.4666666666666667 +1378559665; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 148197.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378559965; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378560265; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8; 0.0; 0.0 +1378560565; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1378560865; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378561165; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 146800.0; 12.733333333333333; 13.133333333333333; 0.3333333333333333; 0.2 +1378561465; 1; 2599.998989; 0.0; 0.0; 2097152.0; 156585.33333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378561765; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378562065; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378562366; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378562666; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118836.53333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378562966; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 2.466666666666667; 0.13333333333333333; 0.4666666666666667 +1378563266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378563566; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378563866; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378564166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378564466; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 132817.86666666667; 0.0; 1.9333333333333333; 0.06666666666666667; 0.13333333333333333 +1378564766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378565066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378565366; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378565666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378565966; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104855.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378566266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378566566; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 145401.06666666668; 0.06666666666666667; 8.266666666666667; 0.2; 0.6 +1378566866; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 173363.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378567166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378567466; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.2; 0.0; 0.0 +1378567766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378568066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378568366; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378568666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378568966; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.2; 0.0; 0.0 +1378569266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378569566; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378569866; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 118837.33333333333; 0.0; 0.8; 0.0; 0.0 +1378570166; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 152391.2; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378570466; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148197.6; 0.06666666666666667; 1.2; 0.0; 0.0 +1378570766; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378571066; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.0; 0.0 +1378571366; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378571666; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 1.2; 0.13333333333333333; 0.0 +1378571966; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378572266; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378572566; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378572866; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378573166; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.2; 0.0; 0.0 +1378573466; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378573766; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 141206.13333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1378574066; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 141206.4; 0.0; 1.0; 0.0; 0.0 +1378574367; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 103457.86666666667; 0.0; 1.4; 0.0; 0.0 +1378574667; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378574967; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378575267; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.26666666666; 0.0; 1.0; 0.0; 0.0 +1378575567; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378575867; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378576167; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378576467; 1; 2599.998989; 0.0; 0.0; 2097152.0; 71300.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378576767; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378577067; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 82485.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378577367; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 139808.53333333333; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378577667; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 139809.33333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378577967; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.2; 7.0; 0.2; 0.13333333333333333 +1378578267; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378578567; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378578867; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378579167; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 107652.26666666666; 0.0; 11.933333333333334; 0.0; 0.0 +1378579467; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378579767; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378580067; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378580367; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1378580667; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378580967; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 128624.0; 0.0; 2.2666666666666666; 0.06666666666666667; 0.5333333333333333 +1378581267; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 170566.66666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378581567; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378581867; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378582167; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378582467; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378582767; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378583067; 1; 2599.998989; 38.133318505333335; 1.4666666666666666; 2097152.0; 436206.4; 161.73333333333332; 14.8; 0.0; 0.2 +1378583368; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 304784.5333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378583668; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 152390.93333333332; 31.8; 8.6; 0.2; 0.13333333333333333 +1378583968; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 188741.33333333334; 0.0; 2.3333333333333335; 0.0; 0.0 +1378584268; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378584568; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 128624.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378584868; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 150993.06666666668; 0.0; 0.8; 0.0; 0.0 +1378585168; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1378585468; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378585768; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378586068; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378586368; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378586668; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378586968; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0; 0.0; 0.0 +1378587268; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378587568; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378587868; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 106254.13333333333; 0.0; 1.0; 0.0; 0.0 +1378588168; 1; 2599.998989; 25.999989890000002; 1.0; 2097152.0; 142604.53333333333; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1378588468; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 145401.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378588768; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128623.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378589068; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378589368; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378589668; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139809.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378589968; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 137012.8; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378590268; 1; 2599.998989; 67.599973714; 2.6; 2097152.0; 595589.6; 161.06666666666666; 22.133333333333333; 0.06666666666666667; 0.4 +1378590568; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 433409.6; 0.0; 2.4; 0.0; 0.0 +1378590868; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 239072.8; 31.8; 3.933333333333333; 0.0; 0.0 +1378591168; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 192936.26666666666; 0.8666666666666667; 2.533333333333333; 0.0; 0.0 +1378591468; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 132818.66666666666; 0.0; 1.5333333333333334; 0.0; 0.0 +1378591768; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 146799.2; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378592068; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378592368; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.2; 0.0; 0.0 +1378592668; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378592968; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378593269; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 134216.0; 0.0; 1.5333333333333334; 0.06666666666666667; 0.13333333333333333 +1378593569; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378593869; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0; 0.0; 0.0 +1378594169; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378594469; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378594769; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.8; 0.0; 0.0 +1378595069; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137012.8; 0.0; 1.2; 0.0; 0.0 +1378595369; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 171964.8; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378595669; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 195731.46666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378595969; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378596269; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378596569; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 6.0; 0.2; 0.13333333333333333 +1378596869; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 127226.13333333333; 0.0; 2.2; 0.0; 0.0 +1378597169; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378597469; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378597769; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378598069; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.2; 0.0; 0.0 +1378598369; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378598669; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1378598969; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 162176.8; 0.0; 2.1333333333333333; 0.0; 0.4666666666666667 +1378599269; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 153790.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378599569; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378599869; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378600169; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378600469; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 130022.4; 0.5333333333333333; 1.3333333333333333; 0.06666666666666667; 0.0 +1378600769; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.0; 0.0 +1378601069; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378601369; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 107652.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378601669; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378601970; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 86680.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378602269; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378602569; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 155188.0; 0.2; 2.7333333333333334; 0.06666666666666667; 0.4666666666666667 +1378602869; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 141207.46666666667; 0.0; 0.8; 0.0; 0.0 +1378603169; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 141206.93333333332; 0.0; 6.933333333333334; 0.26666666666666666; 0.13333333333333333 +1378603469; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378603769; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378604069; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137012.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378604369; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378604669; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378604969; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378605269; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378605569; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378605869; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1378606169; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 141207.46666666667; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1378606469; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.26666666666; 0.0; 0.8; 0.0; 0.0 +1378606769; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1378607069; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153790.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378607369; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378607669; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378607970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 65708.26666666666; 0.0; 0.8; 0.0; 0.0 +1378608270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1378608570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8; 0.06666666666666667; 0.0 +1378608870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378609170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378609470; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 121633.6; 0.8666666666666667; 1.3333333333333333; 0.06666666666666667; 0.0 +1378609770; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138411.2; 0.0; 2.2; 0.0; 0.4666666666666667 +1378610070; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155187.2; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378610370; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378610670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8; 0.0; 0.0 +1378610970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378611270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378611570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378611870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.6666666666666667; 0.0; 0.0 +1378612170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378612470; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378612770; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378613070; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378613370; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.86666666667; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378613670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378613970; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378614270; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378614570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118836.53333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378614870; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378615170; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378615470; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378615770; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378616070; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.2; 0.0; 0.0 +1378616370; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 146799.2; 0.06666666666666667; 7.266666666666667; 0.2; 0.13333333333333333 +1378616670; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378616970; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 120235.46666666666; 0.0; 2.2; 0.0; 0.4666666666666667 +1378617270; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 167770.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378617570; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378617871; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 92272.0; 0.0; 0.8666666666666667; 7.6; 0.0 +1378618171; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378618471; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378618771; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.2; 0.0; 0.0 +1378619071; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378619371; 1; 2599.998989; 0.0; 0.0; 2097152.0; 149596.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378619671; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146798.4; 0.0; 1.0; 0.0; 0.0 +1378619971; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378620271; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378620571; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378620871; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 213908.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378621171; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378621471; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378621771; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378622071; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130021.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.06666666666666667 +1378622371; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.4666666666666666; 0.0; 0.0 +1378622671; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 11.866666666666667; 0.06666666666666667; 0.0 +1378622971; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 12.733333333333333; 13.666666666666666; 0.26666666666666666; 0.13333333333333333 +1378623271; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378623571; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378623871; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 1.0; 0.0; 0.0 +1378624171; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 96467.2; 0.0; 2.4; 0.06666666666666667; 0.4666666666666667 +1378624472; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146800.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378624772; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 1.0; 0.2; 0.0 +1378625072; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1378625372; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378625672; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378625972; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.7333333333333334; 0.0; 0.0 +1378626272; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.6; 0.0; 0.0 +1378626572; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378626872; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378627172; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378627472; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378627772; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 153789.6; 0.2; 2.4; 0.06666666666666667; 0.4666666666666667 +1378628072; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 184548.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378628372; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 138411.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378628672; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378628972; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378629272; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 7.0; 0.26666666666666666; 0.13333333333333333 +1378629572; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378629872; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117438.4; 0.0; 1.2; 0.06666666666666667; 0.0 +1378630172; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378630472; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378630772; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378631073; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378631373; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 134216.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378631673; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378631973; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378632273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378632573; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 0.0; 1.2666666666666666; 0.0; 0.0 +1378632873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378633173; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1378633473; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 76893.33333333333; 0.0; 0.8; 0.0; 0.0 +1378633773; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378634073; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378634373; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378634673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1378634973; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 170566.4; 0.0; 8.4; 0.2; 0.6666666666666666 +1378635273; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 170566.4; 0.06666666666666667; 1.4666666666666666; 0.06666666666666667; 0.0 +1378635573; 1; 2599.998989; 0.0; 0.0; 2097152.0; 171964.53333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378635873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378636173; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378636473; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378636773; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378637073; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378637373; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378637673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378637973; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378638273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378638573; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.2; 2.533333333333333; 0.0; 0.4666666666666667 +1378638873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378639173; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378639473; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378639773; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378640073; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 139808.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378640373; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378640673; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.4; 0.0; 0.0 +1378640973; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 120234.66666666667; 0.06666666666666667; 7.133333333333334; 0.3333333333333333; 0.13333333333333333 +1378641273; 1; 2599.998989; 0.0; 0.0; 2097152.0; 166373.06666666668; 0.0; 1.0; 0.0; 0.0 +1378641573; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1378641873; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378642173; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 167770.66666666666; 0.0; 2.7333333333333334; 0.0; 0.4666666666666667 +1378642473; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 183149.6; 0.0; 0.8; 0.0; 0.0 +1378642774; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378643074; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378643374; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 173362.93333333332; 161.0; 21.866666666666667; 0.06666666666666667; 0.4 +1378643674; 1; 2599.998989; 55.46664509866667; 2.1333333333333333; 2097152.0; 708835.7333333333; 0.0; 2.8666666666666667; 0.06666666666666667; 0.0 +1378643974; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 318765.3333333333; 31.8; 3.6666666666666665; 0.0; 0.0 +1378644274; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 183148.53333333333; 0.8; 2.2; 0.0; 0.0 +1378644574; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 150992.53333333333; 0.0; 1.6; 0.0; 0.0 +1378644874; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378645174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378645474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152390.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378645774; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 153790.13333333333; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378646074; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 162177.6; 0.0; 1.0; 0.0; 0.0 +1378646374; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1378646674; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378646974; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378647274; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378647574; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 148197.33333333334; 1.0; 1.7333333333333334; 0.0; 0.0 +1378647874; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.2; 0.0; 0.0 +1378648174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378648474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378648774; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378649074; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378649374; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 137012.26666666666; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378649674; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 176159.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378649974; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378650274; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378650574; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.2; 0.0; 0.0 +1378650874; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155188.8; 0.06666666666666667; 1.3333333333333333; 0.06666666666666667; 0.13333333333333333 +1378651174; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378651474; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378651775; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378652075; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1378652375; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378652675; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 104856.0; 0.0; 6.8; 0.26666666666666666; 0.13333333333333333 +1378652975; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 149595.46666666667; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378653275; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 145401.06666666668; 0.0; 1.1333333333333333; 0.0; 0.0 +1378653575; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378653875; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378654175; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378654475; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1378654775; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378655075; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378655375; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378655675; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378655975; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146798.13333333333; 0.0; 1.0; 0.0; 0.0 +1378656275; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 0.8; 0.0; 0.0 +1378656575; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 2.2; 0.0; 0.5333333333333333 +1378656875; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 127225.33333333333; 0.0; 0.8; 0.0; 0.0 +1378657175; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378657475; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1378657775; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378658076; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378658376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378658676; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378658976; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 0.8; 0.0; 0.0 +1378659276; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378659576; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 89476.53333333334; 0.0; 6.933333333333334; 0.2; 0.13333333333333333 +1378659876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378660176; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148196.8; 0.0; 2.8; 0.0; 0.4666666666666667 +1378660476; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152391.46666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378660776; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378661076; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378661376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378661676; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378661976; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378662276; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378662576; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378662876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378663176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8; 0.0; 0.0 +1378663476; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378663776; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 148197.6; 0.06666666666666667; 2.533333333333333; 0.0; 0.4666666666666667 +1378664076; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 138410.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378664376; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 95069.06666666667; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378664676; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378664976; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378665276; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 150994.4; 0.0; 6.733333333333333; 0.26666666666666666; 0.2 +1378665576; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 +1378665876; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 132817.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378666176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378666476; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 11.8; 0.0; 0.0 +1378666776; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378667076; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 120234.93333333333; 0.0; 1.2; 0.0; 0.0 +1378667377; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 117439.2; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1378667677; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378667976; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378668276; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378668576; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 92272.8; 0.0; 1.2; 0.0; 0.0 +1378668876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378669176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378669476; 1; 2599.998989; 39.86665116466667; 1.5333333333333334; 2097152.0; 321561.6; 161.73333333333332; 14.733333333333333; 0.0; 0.2 +1378669776; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 339736.26666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378670076; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 162178.66666666666; 31.8; 3.7333333333333334; 0.0; 0.0 +1378670376; 1; 2599.998989; 0.0; 0.0; 2097152.0; 134216.8; 0.0; 1.8; 0.0; 0.0 +1378670676; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 130021.6; 0.0; 7.0; 0.2; 0.13333333333333333 +1378670976; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142604.53333333333; 0.06666666666666667; 2.7333333333333334; 0.0; 0.5333333333333333 +1378671276; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125827.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378671576; 1; 2599.998989; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378671876; 1; 2599.998989; 0.0; 0.0; 2097152.0; 72698.93333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378672176; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378672477; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 121633.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378672777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1378673077; 1; 2599.998989; 0.0; 0.0; 2097152.0; 74097.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378673377; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378673677; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378673977; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.2666666666666666; 0.0; 0.0 +1378674277; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378674577; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 128624.26666666666; 0.13333333333333333; 2.533333333333333; 0.0; 0.4666666666666667 +1378674877; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 0.8; 0.0; 0.0 +1378675177; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378675477; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378675777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 67106.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378676077; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378676377; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.06666666666666667; 1.5333333333333334; 0.2; 0.13333333333333333 +1378676677; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.33333333334; 0.0; 6.666666666666667; 0.0; 0.0 +1378676977; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378677277; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 1.0; 0.0; 0.0 +1378677577; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378677877; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 83884.0; 0.26666666666666666; 1.1333333333333333; 0.0; 0.0 +1378678177; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 138410.13333333333; 0.0; 2.533333333333333; 0.0; 0.5333333333333333 +1378678477; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124428.53333333334; 0.0; 1.0; 0.0; 0.0 +1378678777; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378679077; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378679377; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.86666666667; 0.0; 0.8; 0.0; 0.0 +1378679677; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 1.8; 0.06666666666666667; 0.13333333333333333 +1378679977; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 166373.06666666668; 0.0; 0.8; 0.0; 0.0 +1378680277; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378680577; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.0; 0.0 +1378680877; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378681178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378681478; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 118837.33333333333; 0.2; 1.0666666666666667; 0.0; 0.0 +1378681778; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 137013.06666666668; 0.0; 2.4; 0.0; 0.4666666666666667 +1378682078; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1378682378; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378682678; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 111846.13333333333; 12.733333333333333; 13.066666666666666; 0.3333333333333333; 0.13333333333333333 +1378682978; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 145400.53333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378683278; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378683578; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 99263.46666666666; 0.0; 1.0; 0.0; 0.0 +1378683878; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 88078.4; 0.0; 1.3333333333333333; 0.0; 0.0 +1378684178; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8; 0.0; 0.0 +1378684478; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 130022.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378684778; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 0.8; 0.0; 0.0 +1378685078; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378685378; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 184547.73333333334; 0.06666666666666667; 2.466666666666667; 0.0; 0.5333333333333333 +1378685678; 1; 2599.998989; 0.0; 0.0; 2097152.0; 213908.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378685978; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378686278; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378686578; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378686878; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 164974.4; 0.6; 1.2666666666666666; 0.0; 0.0 +1378687178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 164973.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378687478; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378687778; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378688078; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378688378; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378688678; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378688978; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 149596.0; 0.0; 2.2666666666666666; 0.0; 0.4666666666666667 +1378689278; 1; 2599.998989; 0.0; 0.0; 2097152.0; 162177.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378689578; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 113244.8; 0.0; 7.2; 0.2; 0.13333333333333333 +1378689878; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 1.0666666666666667; 0.0; 0.0 +1378690178; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378690478; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378690778; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.2666666666666666; 0.0; 0.0 +1378691079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378691379; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 1.0; 0.0; 0.0 +1378691679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378691979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378692279; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378692579; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 131419.73333333334; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378692879; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155188.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378693179; 1; 2599.998989; 0.0; 0.0; 2097152.0; 148196.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378693479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378693779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378694079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378694379; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378694679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378694979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378695279; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 131420.53333333333; 0.0; 6.866666666666666; 0.2; 0.13333333333333333 +1378695579; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135614.93333333332; 0.0; 0.8666666666666667; 0.0; 0.0 +1378695879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378696179; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 2.8; 0.0; 0.4666666666666667 +1378696479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378696779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378697079; 1; 2599.998989; 64.13330839533334; 2.466666666666667; 2097152.0; 426419.2; 161.2; 21.733333333333334; 0.06666666666666667; 0.4 +1378697379; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 539665.0666666667; 0.0; 2.8; 0.0; 0.0 +1378697679; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 246063.46666666667; 31.8; 3.6666666666666665; 0.0; 0.0 +1378697979; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 159382.4; 0.8; 2.6666666666666665; 0.0; 0.0 +1378698279; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.8666666666666667; 0.0; 0.0 +1378698579; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155187.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378698879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378699180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142605.6; 0.0; 1.0; 0.0; 0.0 +1378699480; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378699780; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.53333333333; 6.8; 2.533333333333333; 0.0; 0.4666666666666667 +1378700080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118836.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378700380; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378700679; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378700979; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378701279; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 142605.6; 0.0; 7.066666666666666; 0.26666666666666666; 0.2 +1378701579; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378701879; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378702179; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0; 0.0; 0.0 +1378702479; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378702779; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378703079; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378703379; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 183149.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1378703680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 160780.53333333333; 0.0; 1.0; 0.0; 0.0 +1378703980; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378704280; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 111846.66666666667; 1.0; 2.0; 0.0; 0.0 +1378704580; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378704880; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378705180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378705480; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378705780; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139809.33333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378706080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378706380; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378706680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378706980; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 1.9333333333333333; 0.0; 0.4666666666666667 +1378707280; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 6.333333333333333; 0.26666666666666666; 0.13333333333333333 +1378707580; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 148196.53333333333; 0.0; 1.5333333333333334; 0.0; 0.0 +1378707880; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378708180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378708480; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.06666666666666667; 2.8; 0.06666666666666667; 0.06666666666666667 +1378708780; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.53333333333; 0.0; 1.8; 0.0; 0.0 +1378709080; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0; 0.0; 0.0 +1378709380; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378709680; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378709980; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 81087.73333333334; 0.0; 11.933333333333334; 0.0; 0.0 +1378710280; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378710580; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 135613.33333333334; 0.26666666666666666; 2.3333333333333335; 0.0; 0.4666666666666667 +1378710880; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 156585.6; 0.0; 1.0; 0.0; 0.0 +1378711180; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378711481; 1; 2599.998989; 0.0; 0.0; 2097152.0; 82485.86666666667; 0.0; 1.0; 0.0; 0.0 +1378711781; 1; 2599.998989; 0.0; 0.0; 2097152.0; 135613.86666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378712081; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378712381; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378712681; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.9333333333333333; 0.0; 0.0 +1378712981; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378713281; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378713581; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378713881; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.13333333333333333; 0.0 +1378714181; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 174760.8; 0.0; 8.6; 0.2; 0.6666666666666666 +1378714481; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 155187.46666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378714781; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131419.73333333334; 0.0; 1.6666666666666667; 0.06666666666666667; 0.0 +1378715081; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123030.93333333333; 0.0; 1.0; 0.0; 0.0 +1378715381; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 1.2; 0.0; 0.0 +1378715681; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378715981; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378716281; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378716581; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378716881; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378717181; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378717481; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378717782; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.0; 0.0; 2.4; 0.0; 0.4666666666666667 +1378718082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152391.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378718382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378718682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378718982; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378719282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378719582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.2; 0.0; 0.0 +1378719882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378720182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378720482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378720782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1378721082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378721382; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 145400.8; 0.0; 8.733333333333333; 0.2; 0.6 +1378721682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153788.53333333333; 0.0; 0.8; 0.0; 0.0 +1378721982; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378722282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378722582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378722882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 142604.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378723182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378723482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378723782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.3333333333333333; 0.0; 0.0 +1378724082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378724382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 1.0; 0.0; 0.0 +1378724682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.0; 0.0 +1378724982; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 128624.26666666666; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378725282; 1; 2599.998989; 0.0; 0.0; 2097152.0; 145401.06666666668; 0.0; 0.8; 0.0; 0.0 +1378725582; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378725882; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.7333333333333333; 0.0; 0.0 +1378726182; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.8; 0.26666666666666666; 0.0 +1378726482; 1; 2599.998989; 0.0; 0.0; 2097152.0; 141207.46666666667; 0.0; 1.0; 0.0; 0.0 +1378726782; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378727082; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.4; 0.0; 0.0 +1378727382; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8; 0.0; 0.0 +1378727682; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.26666666666; 0.0; 0.8; 0.13333333333333333; 0.0 +1378727983; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 208314.93333333332; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1378728283; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 125828.0; 0.0; 0.6666666666666666; 0.0; 0.0 +1378728583; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 156585.06666666668; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378728883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 153790.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378729183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378729483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.0; 0.0 +1378729783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.7333333333333333; 0.13333333333333333; 0.0 +1378730083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8; 0.0; 0.0 +1378730383; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127225.06666666667; 0.0; 0.6666666666666666; 0.0; 0.0 +1378730683; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 128624.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378730983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378731283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378731583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 1.0; 0.0; 0.0 +1378731883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378732183; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 162178.4; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1378732483; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378732783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 0.8; 0.06666666666666667; 0.0 +1378733083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378733383; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 114642.93333333333; 0.0; 7.2; 0.26666666666666666; 0.2 +1378733683; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378733983; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378734283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8; 0.06666666666666667; 0.0 +1378734583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.7333333333333333; 0.0; 0.0 +1378734883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378735183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378735483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.6666666666666666; 0.3333333333333333; 0.0 +1378735783; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 180352.8; 0.13333333333333333; 2.6; 0.0; 0.4666666666666667 +1378736083; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167770.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378736383; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.0; 0.0; 0.0 +1378736683; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378736983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378737283; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.06666666666666667; 0.13333333333333333 +1378737583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378737883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378738183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 1.0; 0.0; 0.0 +1378738483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.06666666666666667; 0.0 +1378738783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 69902.66666666667; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378739083; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 6.266666666666667; 0.2; 0.13333333333333333 +1378739383; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 181750.93333333332; 0.0; 2.8666666666666667; 0.06666666666666667; 0.4666666666666667 +1378739683; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 157983.46666666667; 0.0; 1.0; 0.0; 0.0 +1378739983; 1; 2599.998989; 0.0; 0.0; 2097152.0; 167771.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378740283; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.6666666666666666; 0.0 +1378740583; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378740883; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378741183; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378741483; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.2666666666666666; 0.26666666666666666; 0.0 +1378741783; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.1333333333333333; 0.0; 0.0 +1378742084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378742384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378742684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378742984; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 138410.4; 0.0; 2.466666666666667; 0.0; 0.4666666666666667 +1378743284; 1; 2599.998989; 0.0; 0.0; 2097152.0; 130021.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378743584; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378743884; 1; 2599.998989; 0.0; 0.0; 2097152.0; 78291.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378744184; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378744484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.2; 0.0; 0.0 +1378744784; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378745084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1378745384; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 12.733333333333333; 12.133333333333333; 0.4; 0.2 +1378745684; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.6; 0.0; 2.4; 0.0; 0.0 +1378745984; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.4666666666666666; 0.0; 0.0 +1378746284; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 96467.2; 1.4666666666666666; 1.2; 0.0; 0.0 +1378746584; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378746884; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378747184; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378747484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.0; 0.0; 0.0 +1378747784; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378748084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378748384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378748684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378748984; 1; 2599.998989; 65.86664105466667; 2.533333333333333; 2097152.0; 468361.86666666664; 161.06666666666666; 21.733333333333334; 0.06666666666666667; 0.4 +1378749284; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 441797.6; 0.0; 2.8; 0.0; 0.0 +1378749584; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 248859.73333333334; 31.8; 3.7333333333333334; 0.0; 0.0 +1378749884; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 183149.06666666668; 0.8; 2.533333333333333; 0.0; 0.0 +1378750184; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 188742.4; 0.0; 3.466666666666667; 0.0; 0.4666666666666667 +1378750484; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.0; 0.0; 0.0 +1378750784; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1378751084; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378751384; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378751684; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378751984; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 160779.73333333334; 0.06666666666666667; 7.4; 0.2; 0.13333333333333333 +1378752284; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0; 0.0; 0.0 +1378752585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378752885; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378753185; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378753485; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378753785; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 144003.73333333334; 0.0; 13.0; 0.0; 0.4666666666666667 +1378754085; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378754385; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378754685; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378754985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 85282.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378755285; 1; 2599.998989; 0.0; 0.0; 2097152.0; 68504.53333333334; 0.0; 0.8; 0.0; 0.0 +1378755585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378755885; 1; 2599.998989; 39.86665116466667; 1.5333333333333334; 2097152.0; 293599.2; 161.73333333333332; 14.8; 0.0; 0.2 +1378756185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 378883.4666666667; 0.0; 1.4; 0.0; 0.0 +1378756485; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 155188.53333333333; 31.8; 3.533333333333333; 0.0; 0.0 +1378756785; 1; 2599.998989; 0.0; 0.0; 2097152.0; 152390.93333333332; 0.0; 1.2; 0.0; 0.0 +1378757085; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378757385; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 156584.8; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378757685; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 139809.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378757985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378758285; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378758585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 1.2666666666666666; 0.0 +1378758885; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 111846.13333333333; 0.13333333333333333; 7.066666666666666; 0.2; 0.13333333333333333 +1378759185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.4; 0.0; 1.9333333333333333; 0.0; 0.0 +1378759485; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 1.0; 0.06666666666666667; 0.0 +1378759785; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.2; 0.0; 0.0 +1378760085; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378760385; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378760685; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378760985; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 139808.0; 0.0; 2.6; 0.06666666666666667; 0.4666666666666667 +1378761285; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135613.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378761585; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378761885; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 1.0; 0.0; 0.0 +1378762185; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378762485; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378762785; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378763086; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378763386; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378763686; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378763986; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.3333333333333333; 0.0; 0.0 +1378764286; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0; 0.0; 0.0 +1378764586; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 123031.73333333334; 0.06666666666666667; 2.6; 0.0; 0.5333333333333333 +1378764886; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 89476.53333333334; 0.0; 7.066666666666666; 0.2; 0.13333333333333333 +1378765186; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.1333333333333333; 0.0; 0.0 +1378765486; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.0; 0.0; 0.0 +1378765786; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378766086; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 125827.46666666666; 0.06666666666666667; 1.6666666666666667; 0.06666666666666667; 0.13333333333333333 +1378766385; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116040.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378766685; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378766985; 1; 2599.998989; 0.0; 0.0; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378767285; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378767585; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378767885; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378768185; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 163576.8; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378768486; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378768786; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378769086; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378769386; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 85282.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378769686; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 121633.6; 0.0; 0.8; 0.0; 0.0 +1378769986; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 0.8; 0.0; 0.0 +1378770286; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 131419.73333333334; 0.0; 1.2; 0.0; 0.0 +1378770586; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378770886; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 111846.66666666667; 0.0; 1.2; 0.0; 0.0 +1378771186; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378771486; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.06666666666666667; 7.2; 0.26666666666666666; 0.13333333333333333 +1378771786; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 156585.6; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378772086; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 169168.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378772386; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378772686; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 128623.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378772986; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378773286; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 113244.8; 0.5333333333333333; 1.3333333333333333; 0.0; 0.0 +1378773586; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378773886; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378774186; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 124429.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378774486; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378774786; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 78291.46666666666; 0.0; 1.0; 0.0; 0.0 +1378775086; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378775386; 1; 2599.998989; 25.999989890000002; 1.0; 2097152.0; 118837.33333333333; 0.0; 2.2; 0.0; 0.5333333333333333 +1378775686; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 146800.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378775986; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378776286; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378776586; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 0.8; 0.0; 0.0 +1378776886; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 141207.46666666667; 0.0; 7.133333333333334; 0.2; 0.13333333333333333 +1378777186; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378777486; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378777787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378778087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378778387; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378778687; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378778987; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.06666666667; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1378779287; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 135614.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378779587; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378779887; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378780187; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378780487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378780787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378781087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378781387; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 107652.26666666666; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378781687; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8; 0.0; 0.0 +1378781987; 1; 2599.998989; 0.0; 0.0; 2097152.0; 107652.26666666666; 0.0; 1.3333333333333333; 0.0; 0.0 +1378782287; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378782587; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 176158.66666666666; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1378782887; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 194334.13333333333; 0.0; 7.0; 0.2; 0.13333333333333333 +1378783187; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 153790.4; 0.0; 1.1333333333333333; 0.0; 0.0 +1378783487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 83884.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378783787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378784087; 1; 2599.998989; 0.0; 0.0; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378784387; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378784687; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.53333333334; 0.0; 1.6; 0.0; 0.0 +1378784987; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378785287; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139808.8; 0.0; 0.7333333333333333; 0.06666666666666667; 0.0 +1378785587; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378785887; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378786187; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 145400.26666666666; 0.06666666666666667; 2.3333333333333335; 0.0; 0.4666666666666667 +1378786487; 1; 2599.998989; 0.0; 0.0; 2097152.0; 164973.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378786787; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378787088; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378787388; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378787688; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 0.8; 0.0; 0.0 +1378787988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378788288; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 102059.73333333334; 0.0; 7.2; 0.2; 0.13333333333333333 +1378788588; 1; 2599.998989; 0.0; 0.0; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.0; 0.0 +1378788888; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1378789188; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378789488; 1; 2599.998989; 0.0; 0.0; 2097152.0; 86680.26666666666; 0.0; 1.0666666666666667; 0.0; 0.0 +1378789788; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 132817.86666666667; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378790088; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138411.2; 0.0; 1.0; 0.0; 0.0 +1378790388; 1; 2599.998989; 0.0; 0.0; 2097152.0; 146799.2; 0.0; 0.7333333333333333; 0.0; 0.0 +1378790688; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378790988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 89476.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378791288; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378791588; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 1.2666666666666666; 0.0; 0.0 +1378791888; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 116041.06666666667; 0.0; 1.2666666666666666; 0.0; 0.0 +1378792188; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 127226.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378792488; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378792788; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378793088; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 1.2; 0.0; 0.0 +1378793388; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 2.6666666666666665; 0.0; 0.4666666666666667 +1378793688; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 104856.0; 0.0; 1.0; 0.0; 0.0 +1378793988; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 102059.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378794288; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127226.13333333333; 0.0; 1.4; 0.0; 0.0 +1378794588; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378794889; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 131420.53333333333; 0.06666666666666667; 8.4; 0.26666666666666666; 0.2 +1378795189; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 123031.73333333334; 0.0; 1.8; 0.0; 0.0 +1378795489; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378795789; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378796089; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 156586.93333333332; 0.0; 1.0; 0.0; 0.0 +1378796389; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116041.06666666667; 0.0; 1.0; 0.0; 0.0 +1378796689; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.7333333333333333; 0.0; 0.0 +1378796989; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 137012.0; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1378797289; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 145400.53333333333; 0.0; 11.866666666666667; 0.0; 0.0 +1378797589; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378797889; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 106254.13333333333; 0.0; 0.6666666666666666; 0.0; 0.0 +1378798189; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378798489; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378798789; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378799089; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378799388; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 82485.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378799688; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378799988; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378800289; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.2; 0.0; 0.8; 0.0; 0.0 +1378800589; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 150993.06666666668; 0.06666666666666667; 2.4; 0.0; 0.4666666666666667 +1378800889; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 150993.6; 0.0; 7.266666666666667; 0.2; 0.13333333333333333 +1378801189; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378801489; 1; 2599.998989; 72.799971692; 2.8; 2097152.0; 661300.2666666667; 161.2; 22.2; 0.06666666666666667; 0.4 +1378801789; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 500518.13333333336; 0.0; 18.933333333333334; 0.0; 0.0 +1378802089; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 237674.66666666666; 31.8; 3.6; 0.0; 0.0 +1378802389; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 148197.6; 5.066666666666666; 2.4; 0.0; 0.0 +1378802689; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.8; 0.0; 0.0 +1378802989; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378803289; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 82485.86666666667; 0.0; 0.8; 0.0; 0.0 +1378803589; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 79689.6; 0.0; 0.8; 0.0; 0.0 +1378803889; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 67106.4; 0.0; 1.8666666666666667; 0.0; 0.0 +1378804189; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 148196.8; 3.8666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378804489; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 174761.06666666668; 0.0; 0.7333333333333333; 0.0; 0.0 +1378804789; 1; 2599.998989; 0.0; 0.0; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378805089; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378805389; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 69902.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378805689; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378805989; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378806289; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378806589; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 0.8; 0.0; 0.0 +1378806889; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 117439.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378807189; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 149596.26666666666; 0.0; 1.0; 0.0; 0.0 +1378807489; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 164974.13333333333; 12.933333333333334; 13.266666666666667; 0.3333333333333333; 0.2 +1378807789; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 155186.93333333332; 0.0; 2.4; 0.13333333333333333; 0.4666666666666667 +1378808089; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 146799.46666666667; 0.0; 1.3333333333333333; 0.06666666666666667; 0.0 +1378808389; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378808689; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 116041.06666666667; 1.0; 1.6; 0.06666666666666667; 0.0 +1378808990; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 164974.66666666666; 0.0; 1.0; 0.0; 0.0 +1378809290; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137012.53333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378809590; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378809890; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 110448.53333333334; 0.0; 1.0666666666666667; 0.0; 0.0 +1378810190; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378810490; 1; 2599.998989; 0.0; 0.0; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378810790; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 102059.73333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378811090; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 138410.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378811390; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 127226.13333333333; 0.0; 2.4; 0.0; 0.5333333333333333 +1378811690; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 141206.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378811990; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 110448.53333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378812290; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378812590; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 85282.13333333333; 0.0; 1.0; 0.06666666666666667; 0.0 +1378812890; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 144003.46666666667; 0.0; 1.0; 0.0; 0.0 +1378813190; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 135614.13333333333; 0.0; 2.3333333333333335; 0.2; 0.13333333333333333 +1378813490; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 164974.4; 0.0; 6.2; 0.0; 0.0 +1378813790; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.0; 0.0 +1378814090; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378814390; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378814690; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 120235.46666666666; 1.4; 1.2666666666666666; 0.0; 0.0 +1378814990; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 160779.46666666667; 0.0; 2.533333333333333; 0.06666666666666667; 0.5333333333333333 +1378815290; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 153789.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378815590; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378815890; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378816190; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378816490; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378816790; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378817090; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378817390; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 109050.4; 0.0; 1.0; 0.0; 0.0 +1378817690; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 92272.8; 0.0; 1.0666666666666667; 0.0; 0.0 +1378817990; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378818290; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378818590; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 125828.0; 0.06666666666666667; 2.6; 0.0; 0.4666666666666667 +1378818890; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378819190; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 1.2; 6.333333333333333; 0.0 +1378819490; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 104856.0; 0.06666666666666667; 7.066666666666666; 0.4; 0.13333333333333333 +1378819791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 176159.2; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378820091; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 125827.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378820391; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378820691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 104856.0; 0.0; 1.2; 0.13333333333333333; 0.0 +1378820991; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378821291; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378821591; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 121633.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378821891; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378822191; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 128624.26666666666; 0.0; 2.3333333333333335; 0.0; 0.5333333333333333 +1378822491; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 146799.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378822791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 155188.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378823091; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378823391; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 75495.2; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378823691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 125828.0; 0.0; 1.2; 0.06666666666666667; 0.13333333333333333 +1378823991; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378824291; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 83884.0; 0.0; 1.0666666666666667; 0.3333333333333333; 0.0 +1378824591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378824891; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378825191; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 155188.0; 0.0; 6.866666666666666; 0.26666666666666666; 0.13333333333333333 +1378825491; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378825791; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 171964.53333333333; 0.0; 2.0; 0.13333333333333333; 0.4666666666666667 +1378826091; 1; 2599.998989; 0.0; 0.0; 2097152.0; 138410.4; 0.06666666666666667; 1.4; 0.0; 0.0 +1378826391; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378826691; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 113244.8; 0.0; 0.8; 0.0; 0.0 +1378826991; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378827291; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 117439.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378827591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 1.2; 0.13333333333333333; 0.0 +1378827891; 1; 2599.998989; 0.0; 0.0; 2097152.0; 114642.93333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378828191; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 145400.8; 0.0; 1.0; 0.0; 0.0 +1378828491; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132818.66666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378828791; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.53333333333; 0.0; 1.0; 0.2; 0.0 +1378829091; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378829391; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 117439.2; 0.13333333333333333; 2.4; 0.06666666666666667; 0.4666666666666667 +1378829691; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378829991; 1; 2599.998989; 0.0; 0.0; 2097152.0; 176159.2; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378830291; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.33333333334; 0.0; 1.1333333333333333; 0.0; 0.0 +1378830591; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378830892; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378831192; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.13333333333333333; 0.0 +1378831492; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378831791; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 1.0; 0.0; 0.0 +1378832091; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.8; 0.06666666666666667; 7.066666666666666; 0.26666666666666666; 0.13333333333333333 +1378832391; 1; 2599.998989; 0.0; 0.0; 2097152.0; 132817.6; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378832691; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 113244.8; 0.0; 1.0; 0.06666666666666667; 0.0 +1378832991; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 96467.2; 0.0; 2.533333333333333; 0.0; 0.4666666666666667 +1378833291; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378833591; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 123031.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378833891; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378834191; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.26666666666666666; 0.0 +1378834492; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.0; 0.0 +1378834792; 1; 2599.998989; 0.0; 0.0; 2097152.0; 102059.73333333334; 0.0; 1.0; 0.0; 0.0 +1378835092; 1; 2599.998989; 0.0; 0.0; 2097152.0; 97865.33333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378835392; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378835692; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.2; 0.0; 0.0 +1378835992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 159383.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378836292; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 138411.2; 0.0; 1.6; 0.0; 0.0 +1378836592; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 180352.8; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 +1378836892; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 159383.2; 0.0; 0.9333333333333333; 0.0; 0.0 +1378837192; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 138410.13333333333; 0.0; 1.3333333333333333; 0.0; 0.0 +1378837492; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 104856.0; 0.0; 7.133333333333334; 0.26666666666666666; 0.13333333333333333 +1378837792; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.6; 0.0; 1.0; 0.0; 0.0 +1378838092; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 92272.8; 0.0; 0.8; 0.06666666666666667; 0.0 +1378838392; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 100661.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378838692; 1; 2599.998989; 0.0; 0.0; 2097152.0; 90874.66666666667; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378838992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378839292; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.4666666666666667; 0.0 +1378839592; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 100661.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378839892; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 90874.66666666667; 0.0; 1.2; 0.06666666666666667; 0.0 +1378840192; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 170566.93333333332; 0.0; 2.466666666666667; 0.0; 0.5333333333333333 +1378840492; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.06666666666666667; 0.0 +1378840792; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 89476.53333333334; 0.0; 0.8; 0.0; 0.0 +1378841092; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 11.8; 0.0; 0.0 +1378841392; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 1.2; 0.0; 0.0 +1378841692; 1; 2599.998989; 0.0; 0.0; 2097152.0; 81087.73333333334; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378841992; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378842293; 1; 2599.998989; 41.599983824; 1.6; 2097152.0; 251656.8; 161.93333333333334; 14.8; 1.4; 0.2 +1378842593; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 418030.4; 0.0; 1.6; 0.0; 0.0 +1378842893; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 198528.53333333333; 31.8; 3.7333333333333334; 0.0; 0.0 +1378843193; 1; 2599.998989; 0.0; 0.0; 2097152.0; 199927.46666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378843493; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 157984.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378843793; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 194334.13333333333; 0.0; 2.4; 0.0; 0.4666666666666667 +1378844093; 1; 2599.998989; 0.0; 0.0; 2097152.0; 171965.33333333334; 0.0; 1.0; 0.0; 0.0 +1378844393; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 127225.6; 0.0; 7.2; 0.4666666666666667; 0.13333333333333333 +1378844693; 1; 2599.998989; 0.0; 0.0; 2097152.0; 121633.33333333333; 0.0; 1.0; 0.0; 0.0 +1378844993; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142605.06666666668; 0.0; 0.9333333333333333; 0.0; 0.0 +1378845293; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 134216.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378845593; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 132818.66666666666; 0.0; 1.0; 0.06666666666666667; 0.0 +1378845893; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.2; 0.0 +1378846193; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 89476.53333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378846493; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378846793; 1; 2599.998989; 0.0; 0.0; 2097152.0; 113244.8; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378847093; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 93670.93333333333; 0.0; 1.0; 0.0; 0.0 +1378847393; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 130021.6; 0.0; 2.466666666666667; 0.06666666666666667; 0.4666666666666667 +1378847693; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 135614.93333333332; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378847993; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378848293; 1; 2599.998989; 0.0; 0.0; 2097152.0; 99263.46666666666; 0.0; 1.8666666666666667; 0.0; 0.0 +1378848593; 1; 2599.998989; 0.0; 0.0; 2097152.0; 125828.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378848893; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 117438.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378849193; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378849493; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378849793; 1; 2599.998989; 0.0; 0.0; 2097152.0; 139808.53333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378850093; 1; 2599.998989; 0.0; 0.0; 2097152.0; 150993.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378850393; 1; 2599.998989; 0.0; 0.0; 2097152.0; 116040.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378850693; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 82485.86666666667; 0.0; 1.5333333333333334; 0.2; 0.13333333333333333 +1378850993; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 146799.2; 0.0; 8.0; 0.06666666666666667; 0.4666666666666667 +1378851293; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 125828.0; 0.0; 1.0; 0.0; 0.0 +1378851593; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378851893; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 134216.0; 0.0; 1.0; 0.0; 0.0 +1378852193; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 76893.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378852493; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 139808.53333333333; 0.06666666666666667; 1.8; 0.06666666666666667; 0.13333333333333333 +1378852794; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 113244.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378853094; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 248860.8; 169.66666666666666; 179.86666666666667; 0.0; 0.0 +1378853394; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 167770.93333333332; 0.0; 1.0; 0.0; 0.0 +1378853694; 1; 2599.998989; 69.33330637333334; 2.666666666666667; 2097152.0; 640328.5333333333; 161.06666666666666; 22.0; 0.0; 0.4 +1378853994; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 408243.73333333334; 0.0; 2.7333333333333334; 0.0; 0.0 +1378854294; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 233480.26666666666; 31.8; 3.6; 0.0; 0.0 +1378854594; 1; 2599.998989; 24.266657230666667; 0.9333333333333332; 2097152.0; 152391.73333333334; 13.333333333333334; 3.7333333333333334; 0.0; 0.4666666666666667 +1378854894; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 145401.06666666668; 0.0; 1.4666666666666666; 0.0; 0.0 +1378855194; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 123031.2; 0.0; 1.0666666666666667; 0.0; 0.0 +1378855494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 103457.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378855794; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 130022.4; 0.0; 0.8; 0.0; 0.0 +1378856094; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 131419.73333333334; 0.06666666666666667; 1.4; 0.0; 0.0 +1378856394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 125828.0; 0.0; 1.2; 0.0; 0.0 +1378856694; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 144003.73333333334; 0.0; 7.666666666666667; 0.2; 0.13333333333333333 +1378856994; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 159382.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378857294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 97865.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378857594; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378857894; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378858194; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 157984.0; 0.06666666666666667; 2.466666666666667; 0.0; 0.4666666666666667 +1378858494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 144002.93333333332; 0.0; 1.0; 0.06666666666666667; 0.0 +1378858794; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378859094; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378859394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 123031.73333333334; 0.0; 1.0; 0.0; 0.0 +1378859694; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.5333333333333333; 1.3333333333333333; 0.0; 0.0 +1378859994; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 90874.66666666667; 0.0; 1.0; 0.0; 0.0 +1378860294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 93670.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378860594; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 111846.66666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378860894; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 114642.93333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378861194; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378861494; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 141206.93333333332; 0.0; 1.0; 0.0; 0.0 +1378861794; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 183149.86666666667; 0.0; 2.3333333333333335; 0.06666666666666667; 0.4666666666666667 +1378862094; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 152392.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378862394; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378862694; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 89476.53333333334; 0.0; 1.0; 0.0; 0.0 +1378862994; 1; 2599.998989; 20.799991912; 0.8; 2097152.0; 124429.86666666667; 0.0; 7.066666666666666; 0.26666666666666666; 0.06666666666666667 +1378863294; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 155188.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378863595; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 132818.66666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378863895; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 117439.2; 0.0; 1.0; 0.0; 0.0 +1378864195; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 88078.4; 0.0; 0.8; 0.0; 0.0 +1378864494; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378864794; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 128623.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378865094; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 124429.86666666667; 0.0; 1.0; 0.0; 0.0 +1378865394; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 114642.93333333333; 0.06666666666666667; 2.533333333333333; 0.06666666666666667; 0.4666666666666667 +1378865694; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 137013.06666666668; 0.0; 0.8666666666666667; 0.0; 0.0 +1378865994; 1; 2599.998989; 19.066659252666668; 0.7333333333333333; 2097152.0; 95069.06666666667; 0.0; 0.8; 0.0; 0.0 +1378866294; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 95069.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378866594; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 103457.86666666667; 0.0; 0.7333333333333333; 0.0; 0.0 +1378866894; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 134216.8; 0.0; 0.6666666666666666; 0.0; 0.0 +1378867194; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378867494; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378867794; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 120235.46666666666; 0.0; 1.2; 0.0; 0.0 +1378868094; 1; 2599.998989; 15.599993934000002; 0.6; 2097152.0; 102059.73333333334; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378868394; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 0.7333333333333333; 1.2666666666666666; 0.0 +1378868694; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 137012.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378868994; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 178955.2; 12.8; 14.2; 0.3333333333333333; 0.7333333333333333 +1378869294; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 201325.06666666668; 0.0; 1.2666666666666666; 0.0; 0.0 +1378869594; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 171964.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378869894; 1; 2599.998989; 0.0; 0.0; 2097152.0; 131420.0; 0.0; 0.8; 0.0; 0.0 +1378870194; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 99263.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378870494; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 1.0; 0.0; 0.0 +1378870794; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378871094; 1; 2599.998989; 0.0; 0.0; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378871394; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 0.7333333333333333; 0.0; 0.0 +1378871695; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378871995; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 88078.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378872295; 1; 2599.998989; 0.0; 0.0; 2097152.0; 96467.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378872595; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 157983.2; 0.0; 2.3333333333333335; 0.0; 0.4666666666666667 +1378872895; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 116041.06666666667; 0.0; 0.8; 0.0; 0.0 +1378873195; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 130022.4; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378873495; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.6666666666666666; 0.06666666666666667; 0.0 +1378873795; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.6666666666666666; 0.0; 0.0 +1378874095; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 107652.26666666666; 0.0; 0.6666666666666666; 0.0; 0.0 +1378874395; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378874695; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378874995; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8; 0.06666666666666667; 0.0 +1378875295; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.6; 0.0; 0.8; 0.0; 0.0 +1378875595; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 142604.8; 0.0; 7.2; 0.26666666666666666; 0.2 +1378875895; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378876195; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 114642.93333333333; 0.06666666666666667; 2.2666666666666666; 0.0; 0.4666666666666667 +1378876495; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 157984.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378876795; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 131420.53333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378877095; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 127226.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378877395; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 127225.33333333333; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378877695; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 124429.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378877995; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 100661.6; 0.0; 1.1333333333333333; 0.0; 0.0 +1378878295; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378878595; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 121633.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378878895; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378879195; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378879495; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378879795; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 157983.73333333334; 0.06666666666666667; 2.066666666666667; 0.0; 0.4666666666666667 +1378880095; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 139808.53333333333; 0.0; 1.1333333333333333; 0.0; 0.0 +1378880396; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378880696; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.53333333333; 0.0; 0.9333333333333333; 0.0; 0.0 +1378880996; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 148197.6; 0.0; 6.933333333333334; 0.26666666666666666; 0.2 +1378881296; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 139808.53333333333; 0.0; 2.4; 0.0; 0.06666666666666667 +1378881596; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 110448.53333333334; 0.0; 2.1333333333333333; 0.0; 0.0 +1378881896; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378882196; 1; 2599.998989; 0.0; 0.0; 2097152.0; 118837.33333333333; 0.0; 1.0; 0.0; 0.0 +1378882496; 1; 2599.998989; 0.0; 0.0; 2097152.0; 75495.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378882796; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378883096; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 1.4666666666666666; 1.4; 0.0; 0.0 +1378883396; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 195732.26666666666; 0.0; 2.2666666666666666; 0.0; 0.5333333333333333 +1378883696; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 199926.93333333332; 0.0; 0.9333333333333333; 0.0; 0.0 +1378883996; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 104856.0; 0.0; 0.8666666666666667; 0.06666666666666667; 0.0 +1378884296; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 130022.4; 0.0; 1.1333333333333333; 0.06666666666666667; 0.0 +1378884596; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 109050.4; 0.0; 11.8; 1.7333333333333334; 0.0 +1378884896; 1; 2599.998989; 0.0; 0.0; 2097152.0; 128624.26666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378885196; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.9333333333333333; 0.06666666666666667; 0.0 +1378885496; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 92272.8; 0.0; 1.8; 0.0; 0.0 +1378885796; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 116041.06666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378886096; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 134216.8; 0.0; 0.9333333333333333; 0.0; 0.0 +1378886396; 1; 2599.998989; 0.0; 0.0; 2097152.0; 109050.4; 0.0; 0.9333333333333333; 0.0; 0.0 +1378886696; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 124429.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378886996; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 157983.2; 0.13333333333333333; 9.266666666666667; 0.26666666666666666; 0.6 +1378887296; 1; 2599.998989; 12.133328615333333; 0.4666666666666666; 2097152.0; 178955.73333333334; 0.0; 0.9333333333333333; 0.0; 0.0 +1378887596; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.9333333333333333; 0.0 +1378887896; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 118837.33333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378888196; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378888496; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 106254.13333333333; 0.0; 1.2; 0.0; 0.0 +1378888796; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 113244.8; 0.0; 1.0; 0.0; 0.0 +1378889096; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.0; 0.0; 0.8666666666666667; 0.0; 0.0 +1378889396; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109049.86666666667; 0.0; 1.0; 0.0; 0.0 +1378889696; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 1.0666666666666667; 0.06666666666666667; 0.0 +1378889997; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.13333333333333333; 0.0 +1378890297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 137013.06666666668; 0.0; 1.0; 0.0; 0.0 +1378890597; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 156585.33333333334; 0.2; 2.4; 0.0; 0.4666666666666667 +1378890897; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 111846.66666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378891197; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 124429.86666666667; 0.0; 1.1333333333333333; 0.0; 0.0 +1378891497; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 107652.26666666666; 0.0; 0.8666666666666667; 2.0; 0.0 +1378891797; 1; 2599.998989; 0.0; 0.0; 2097152.0; 103457.86666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378892097; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 109050.4; 0.0; 0.8666666666666667; 0.0; 0.0 +1378892397; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378892697; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 92272.8; 0.0; 8.066666666666666; 0.2; 0.13333333333333333 +1378892997; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130021.6; 0.0; 0.9333333333333333; 0.0; 0.0 +1378893297; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 146799.2; 20.4; 2.1333333333333333; 0.0; 0.06666666666666667 +1378893597; 1; 2599.998989; 22.53332457133334; 0.8666666666666667; 2097152.0; 149596.26666666666; 0.0; 4.066666666666666; 0.0; 0.0 +1378893897; 1; 2599.998989; 13.866661274666667; 0.5333333333333333; 2097152.0; 183149.86666666667; 0.0; 2.8; 0.0; 0.0 +1378894197; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 148197.06666666668; 0.0; 2.066666666666667; 0.0; 0.4666666666666667 +1378894497; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 138411.2; 0.0; 0.8666666666666667; 0.0; 0.0 +1378894797; 1; 2599.998989; 0.0; 0.0; 2097152.0; 111846.66666666667; 0.0; 0.8666666666666667; 0.0; 0.0 +1378895097; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378895397; 1; 2599.998989; 0.0; 0.0; 2097152.0; 106254.13333333333; 0.0; 1.2666666666666666; 0.0; 0.0 +1378895697; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378895997; 1; 2599.998989; 0.0; 0.0; 2097152.0; 123031.73333333334; 0.0; 0.8666666666666667; 0.0; 0.0 +1378896297; 1; 2599.998989; 0.0; 0.0; 2097152.0; 137012.26666666666; 0.0; 0.9333333333333333; 0.0; 0.0 +1378896597; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 100661.6; 0.0; 1.0666666666666667; 0.0; 0.0 +1378896897; 1; 2599.998989; 0.0; 0.0; 2097152.0; 93670.93333333333; 0.0; 0.8; 0.0; 0.0 +1378897197; 1; 2599.998989; 0.0; 0.0; 2097152.0; 110448.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378897497; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 116041.06666666667; 0.0; 0.9333333333333333; 0.0; 0.0 +1378897797; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 166372.26666666666; 0.0; 2.4; 0.0; 0.5333333333333333 +1378898097; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 173362.93333333332; 0.0; 1.2; 0.0; 0.0 +1378898397; 1; 2599.998989; 0.0; 0.0; 2097152.0; 124429.86666666667; 0.0; 0.8; 0.0; 0.0 +1378898697; 1; 2599.998989; 10.399995956; 0.4; 2097152.0; 92272.8; 0.0; 7.2; 0.2; 0.13333333333333333 +1378898997; 1; 2599.998989; 0.0; 0.0; 2097152.0; 120235.46666666666; 0.0; 0.8666666666666667; 0.0; 0.0 +1378899297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 106254.13333333333; 0.0; 0.8666666666666667; 0.0; 0.0 +1378899597; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 110448.53333333334; 0.0; 1.2666666666666666; 0.0; 0.0 +1378899897; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 160780.0; 0.0; 1.2666666666666666; 0.06666666666666667; 0.0 +1378900197; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 132817.86666666667; 0.0; 1.0666666666666667; 1.4; 0.0 +1378900497; 1; 2599.998989; 0.0; 0.0; 2097152.0; 104856.0; 0.0; 0.7333333333333333; 0.0; 0.0 +1378900797; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 97865.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378901097; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 90874.66666666667; 0.0; 0.8; 0.0; 0.0 +1378901397; 1; 2599.998989; 6.933330637333333; 0.26666666666666666; 2097152.0; 130022.4; 0.06666666666666667; 2.533333333333333; 0.0; 0.5333333333333333 +1378901697; 1; 2599.998989; 0.0; 0.0; 2097152.0; 184547.2; 0.0; 1.0; 0.0; 0.0 +1378901997; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 128624.26666666666; 0.0; 1.1333333333333333; 0.0; 0.0 +1378902297; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 114642.93333333333; 0.0; 1.2; 0.0; 0.0 +1378902598; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 109050.4; 0.0; 0.8; 0.0; 0.0 +1378902898; 1; 2599.998989; 0.0; 0.0; 2097152.0; 79689.6; 0.0; 0.8666666666666667; 0.0; 0.0 +1378903198; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 0.8666666666666667; 0.0; 0.0 +1378903498; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 125828.0; 0.0; 1.0666666666666667; 0.0; 0.0 +1378903798; 1; 2599.998989; 5.199997978; 0.2; 2097152.0; 95069.06666666667; 0.0; 1.0666666666666667; 0.0; 0.0 +1378904098; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.8; 0.06666666666666667; 0.0 +1378904398; 1; 2599.998989; 0.0; 0.0; 2097152.0; 76893.33333333333; 0.0; 1.0666666666666667; 0.0; 0.0 +1378904698; 1; 2599.998989; 1.7333326593333334; 0.06666666666666667; 2097152.0; 104856.0; 0.0; 0.9333333333333333; 0.0; 0.0 +1378904998; 1; 2599.998989; 77.99996967000001; 3.0; 2097152.0; 450186.6666666667; 161.06666666666666; 107.6; 12.933333333333334; 1.2666666666666666 +1378905298; 1; 2599.998989; 17.333326593333336; 0.6666666666666667; 2097152.0; 633338.4; 0.0; 45.13333333333333; 0.2; 0.13333333333333333 +1378905598; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 297792.8; 31.8; 3.466666666666667; 0.0; 0.0 +1378905898; 1; 2599.998989; 8.666663296666668; 0.33333333333333337; 2097152.0; 162177.86666666667; 5.066666666666666; 2.2; 0.0; 0.0 +1378906198; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 142604.8; 0.0; 1.6; 0.0; 0.0 +1378906498; 1; 2599.998989; 3.4666653186666667; 0.13333333333333333; 2097152.0; 125827.2; 0.0; 1.3333333333333333; 0.0; 0.0 +1378906798; 1; 2599.998989; 0.0; 0.0; 2097152.0; 92272.8; 0.0; 1.0; 0.06666666666666667; 0.0 diff --git a/settings.gradle.kts b/settings.gradle.kts index ec697d80..fd1d404a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") include(":opendc-trace:opendc-trace-api") include(":opendc-trace:opendc-trace-gwf") +include(":opendc-trace:opendc-trace-bitbrains") include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") -- cgit v1.2.3 From 5c6bf9739aa0ffd9651df4fcb4cd46a8545144f0 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 31 Aug 2021 18:08:14 +0200 Subject: refactor(trace): Implement trace API for SWF reader This change updates the SWF trace reader to support the new streaming trace API. --- .../org/opendc/format/trace/swf/SwfTraceReader.kt | 176 --------------------- .../opendc/format/trace/swf/SwfTraceReaderTest.kt | 45 ------ opendc-format/src/test/resources/swf_trace.txt | 6 - opendc-trace/opendc-trace-swf/build.gradle.kts | 35 ++++ .../kotlin/org/opendc/trace/swf/SwfTaskTable.kt | 63 ++++++++ .../org/opendc/trace/swf/SwfTaskTableReader.kt | 162 +++++++++++++++++++ .../main/kotlin/org/opendc/trace/swf/SwfTrace.kt | 46 ++++++ .../kotlin/org/opendc/trace/swf/SwfTraceFormat.kt | 43 +++++ .../services/org.opendc.trace.spi.TraceFormat | 1 + .../org/opendc/trace/swf/SwfTraceFormatTest.kt | 107 +++++++++++++ .../opendc-trace-swf/src/test/resources/trace.swf | 6 + settings.gradle.kts | 1 + 12 files changed, 464 insertions(+), 227 deletions(-) delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt delete mode 100644 opendc-format/src/test/kotlin/org/opendc/format/trace/swf/SwfTraceReaderTest.kt delete mode 100644 opendc-format/src/test/resources/swf_trace.txt create mode 100644 opendc-trace/opendc-trace-swf/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt create mode 100644 opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt create mode 100644 opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt create mode 100644 opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-swf/src/test/resources/trace.swf diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt deleted file mode 100644 index bda392a9..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/swf/SwfTraceReader.kt +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.swf - -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import java.io.BufferedReader -import java.io.File -import java.io.FileReader -import java.util.* - -/** - * A [TraceReader] for reading SWF traces into VM-modeled workloads. - * - * The standard is defined by the PWA, see here: https://www.cse.huji.ac.il/labs/parallel/workload/swf.html - * - * @param file The trace file. - */ -public class SwfTraceReader( - file: File, - maxNumCores: Int = -1 -) : TraceReader { - /** - * The internal iterator to use for this reader. - */ - private val iterator: Iterator> - - /** - * Initialize the reader. - */ - init { - val entries = mutableMapOf>() - - val jobNumberCol = 0 - val submitTimeCol = 1 // seconds (begin of trace is 0) - val waitTimeCol = 2 // seconds - val runTimeCol = 3 // seconds - val numAllocatedCoresCol = 4 // We assume that single-core processors were used at the time - val requestedMemoryCol = 9 // KB per processor/core (-1 if not specified) - - val sliceDuration = 5 * 60L - - var jobNumber: Long - var submitTime: Long - var waitTime: Long - var runTime: Long - var cores: Int - var memory: Long - var slicedWaitTime: Long - var runtimePartialSliceRemainder: Long - - BufferedReader(FileReader(file)).use { reader -> - reader.lineSequence() - .filter { line -> - // Ignore comments in the trace - !line.startsWith(";") && line.isNotBlank() - } - .forEach { line -> - val values = line.trim().split("\\s+".toRegex()) - - jobNumber = values[jobNumberCol].trim().toLong() - submitTime = values[submitTimeCol].trim().toLong() - waitTime = values[waitTimeCol].trim().toLong() - runTime = values[runTimeCol].trim().toLong() - cores = values[numAllocatedCoresCol].trim().toInt() - memory = values[requestedMemoryCol].trim().toLong() - - if (maxNumCores != -1 && cores > maxNumCores) { - println("Skipped a task due to processor count ($cores > $maxNumCores).") - return@forEach - } - - if (memory == -1L) { - memory = 1000L * cores // assume 1GB of memory per processor if not specified - } else { - memory /= 1000 // convert KB to MB - } - - val flopsHistory = mutableListOf() - - // Insert waiting time slices - - // We ignore wait time remainders under one - slicedWaitTime = 0L - if (waitTime >= sliceDuration) { - for (tick in submitTime until (submitTime + waitTime - sliceDuration) step sliceDuration) { - flopsHistory.add( - SimTraceWorkload.Fragment( - tick, - sliceDuration * 1000, - 0.0, - cores - ) - ) - slicedWaitTime += sliceDuration - } - } - - // Insert run time slices - - runtimePartialSliceRemainder = runTime % sliceDuration - - for ( - tick in (submitTime + slicedWaitTime) - until (submitTime + slicedWaitTime + runTime - sliceDuration) - step sliceDuration - ) { - flopsHistory.add( - SimTraceWorkload.Fragment( - tick, - sliceDuration * 1000L, - 1.0, - cores - ) - ) - } - - if (runtimePartialSliceRemainder > 0) { - flopsHistory.add( - SimTraceWorkload.Fragment( - submitTime + slicedWaitTime + runTime, - sliceDuration, - runtimePartialSliceRemainder / sliceDuration.toDouble(), - cores - ) - ) - } - - val uuid = UUID(0L, jobNumber) - val workload = SimTraceWorkload(flopsHistory.asSequence()) - entries[jobNumber] = TraceEntry( - uuid, - jobNumber.toString(), - submitTime, - workload, - mapOf( - "cores" to cores, - "required-memory" to memory, - "workload" to workload - ) - ) - } - } - - // Create the entry iterator - iterator = entries.values.sortedBy { it.start }.iterator() - } - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() {} -} diff --git a/opendc-format/src/test/kotlin/org/opendc/format/trace/swf/SwfTraceReaderTest.kt b/opendc-format/src/test/kotlin/org/opendc/format/trace/swf/SwfTraceReaderTest.kt deleted file mode 100644 index e0e049cf..00000000 --- a/opendc-format/src/test/kotlin/org/opendc/format/trace/swf/SwfTraceReaderTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.swf - -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.opendc.simulator.compute.workload.SimTraceWorkload -import java.io.File - -class SwfTraceReaderTest { - @Test - internal fun testParseSwf() { - val reader = SwfTraceReader(File(SwfTraceReaderTest::class.java.getResource("/swf_trace.txt").toURI())) - var entry = reader.next() - assertEquals(0, entry.start) - // 1961 slices for waiting, 3 full and 1 partial running slices - assertEquals(1965, (entry.workload as SimTraceWorkload).trace.toList().size) - - entry = reader.next() - assertEquals(164472, entry.start) - // 1188 slices for waiting, 0 full and 1 partial running slices - assertEquals(1189, (entry.workload as SimTraceWorkload).trace.toList().size) - assertEquals(0.25, (entry.workload as SimTraceWorkload).trace.toList().last().usage) - } -} diff --git a/opendc-format/src/test/resources/swf_trace.txt b/opendc-format/src/test/resources/swf_trace.txt deleted file mode 100644 index c3ecf890..00000000 --- a/opendc-format/src/test/resources/swf_trace.txt +++ /dev/null @@ -1,6 +0,0 @@ -; Excerpt from the PWA: CTC-SP2-1996-3.1-cln.swf - 1 0 588530 937 306 142.00 -1 -1 35100 -1 1 97 -1 307 3 -1 -1 -1 - 2 164472 356587 75 17 2.00 -1 -1 300 -1 1 81 -1 195 3 -1 -1 -1 - 3 197154 459987 35268 306 32792 -1 -1 35100 -1 0 97 -1 307 3 -1 -1 -1 - 4 310448 50431 29493 64 28745 -1 -1 64800 -1 1 38 -1 38 1 -1 -1 -1 - 5 310541 50766 29063 64 28191 -1 -1 64800 -1 1 38 -1 69 1 -1 -1 -1 diff --git a/opendc-trace/opendc-trace-swf/build.gradle.kts b/opendc-trace/opendc-trace-swf/build.gradle.kts new file mode 100644 index 00000000..c9eaa78d --- /dev/null +++ b/opendc-trace/opendc-trace-swf/build.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for Standard Workload Format (SWF) traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) +} diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt new file mode 100644 index 00000000..12a51a2f --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.swf + +import org.opendc.trace.* +import java.nio.file.Path +import kotlin.io.path.bufferedReader + +/** + * A [Table] containing the tasks in a SWF trace. + */ +internal class SwfTaskTable(private val path: Path) : Table { + override val name: String = TABLE_TASKS + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + TASK_ID -> true + TASK_SUBMIT_TIME -> true + TASK_WAIT_TIME -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_ALLOC_NCPUS -> true + TASK_PARENTS -> true + TASK_STATUS -> true + TASK_GROUP_ID -> true + TASK_USER_ID -> true + else -> false + } + } + + override fun newReader(): TableReader { + val reader = path.bufferedReader() + return SwfTaskTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Invalid partition $partition") + } + + override fun toString(): String = "SwfTaskTable" +} diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt new file mode 100644 index 00000000..5f879a54 --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.swf + +import org.opendc.trace.* +import java.io.BufferedReader + +/** + * A [TableReader] implementation for the SWF format. + */ +internal class SwfTaskTableReader(private val reader: BufferedReader) : TableReader { + /** + * The current row. + */ + private var fields = emptyList() + + /** + * A [Regex] object to match whitespace. + */ + private val whitespace = "\\s+".toRegex() + + override fun nextRow(): Boolean { + var line: String + var num = 0 + + while (true) { + line = reader.readLine() ?: return false + num++ + + if (line.isBlank()) { + // Ignore empty lines + continue + } else if (line.startsWith(";")) { + // Ignore comments for now + continue + } + + break + } + + fields = line.trim().split(whitespace) + + if (fields.size < 18) { + throw IllegalArgumentException("Invalid format at line $line") + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + TASK_ID -> true + TASK_SUBMIT_TIME -> true + TASK_WAIT_TIME -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_ALLOC_NCPUS -> true + TASK_PARENTS -> true + TASK_STATUS -> true + TASK_GROUP_ID -> true + TASK_USER_ID -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any = when (column) { + TASK_ID -> getLong(TASK_ID) + TASK_SUBMIT_TIME -> getLong(TASK_SUBMIT_TIME) + TASK_WAIT_TIME -> getLong(TASK_WAIT_TIME) + TASK_RUNTIME -> getLong(TASK_RUNTIME) + TASK_REQ_NCPUS -> getInt(TASK_REQ_NCPUS) + TASK_ALLOC_NCPUS -> getInt(TASK_ALLOC_NCPUS) + TASK_PARENTS -> { + val parent = fields[COL_PARENT_JOB].toLong(10) + if (parent < 0) emptySet() else setOf(parent) + } + TASK_STATUS -> getInt(TASK_STATUS) + TASK_GROUP_ID -> getInt(TASK_GROUP_ID) + TASK_USER_ID -> getInt(TASK_USER_ID) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + TASK_REQ_NCPUS -> fields[COL_REQ_NCPUS].toInt(10) + TASK_ALLOC_NCPUS -> fields[COL_ALLOC_NCPUS].toInt(10) + TASK_STATUS -> fields[COL_STATUS].toInt(10) + TASK_GROUP_ID -> fields[COL_GROUP_ID].toInt(10) + TASK_USER_ID -> fields[COL_USER_ID].toInt(10) + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + return when (column) { + TASK_ID -> fields[COL_JOB_ID].toLong(10) + TASK_SUBMIT_TIME -> fields[COL_SUBMIT_TIME].toLong(10) + TASK_WAIT_TIME -> fields[COL_WAIT_TIME].toLong(10) + TASK_RUNTIME -> fields[COL_RUN_TIME].toLong(10) + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getDouble(column: TableColumn): Double { + throw IllegalArgumentException("Invalid column") + } + + override fun close() { + reader.close() + } + + /** + * Default column indices for the SWF format. + */ + private val COL_JOB_ID = 0 + private val COL_SUBMIT_TIME = 1 + private val COL_WAIT_TIME = 2 + private val COL_RUN_TIME = 3 + private val COL_ALLOC_NCPUS = 4 + private val COL_AVG_CPU_TIME = 5 + private val COL_USED_MEM = 6 + private val COL_REQ_NCPUS = 7 + private val COL_REQ_TIME = 8 + private val COL_REQ_MEM = 9 + private val COL_STATUS = 10 + private val COL_USER_ID = 11 + private val COL_GROUP_ID = 12 + private val COL_EXEC_NUM = 13 + private val COL_QUEUE_NUM = 14 + private val COL_PART_NUM = 15 + private val COL_PARENT_JOB = 16 + private val COL_PARENT_THINK_TIME = 17 +} diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt new file mode 100644 index 00000000..d4da735e --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.swf + +import org.opendc.trace.TABLE_TASKS +import org.opendc.trace.Table +import org.opendc.trace.Trace +import java.nio.file.Path + +/** + * [Trace] implementation for the SWF format. + */ +public class SwfTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_TASKS) + + override fun containsTable(name: String): Boolean = TABLE_TASKS == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + return SwfTaskTable(path) + } + + override fun toString(): String = "SwfTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt new file mode 100644 index 00000000..36c3122e --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.swf + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * Support for the Standard Workload Format (SWF) in OpenDC. + * + * The standard is defined by the PWA, see here: https://www.cse.huji.ac.il/labs/parallel/workload/swf.html + */ +public class SwfTraceFormat : TraceFormat { + override val name: String = "swf" + + override fun open(url: URL): SwfTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return SwfTrace(path) + } +} diff --git a/opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..6c6b0eb2 --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.swf.SwfTraceFormat diff --git a/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt new file mode 100644 index 00000000..9686891b --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.swf + +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.* +import org.opendc.trace.TABLE_TASKS +import org.opendc.trace.TASK_ALLOC_NCPUS +import org.opendc.trace.TASK_ID +import java.net.URL + +/** + * Test suite for the [SwfTraceFormat] class. + */ +internal class SwfTraceFormatTest { + @Test + fun testTraceExists() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val format = SwfTraceFormat() + assertDoesNotThrow { + format.open(input) + } + } + + @Test + fun testTraceDoesNotExists() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val format = SwfTraceFormat() + assertThrows { + format.open(URL(input.toString() + "help")) + } + } + + @Test + fun testTables() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val trace = SwfTraceFormat().open(input) + + assertEquals(listOf(TABLE_TASKS), trace.tables) + } + + @Test + fun testTableExists() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val table = SwfTraceFormat().open(input).getTable(TABLE_TASKS) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val trace = SwfTraceFormat().open(input) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + @Test + fun testReader() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val trace = SwfTraceFormat().open(input) + val reader = trace.getTable(TABLE_TASKS)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals(1, reader.getLong(TASK_ID)) }, + { assertEquals(306, reader.getInt(TASK_ALLOC_NCPUS)) }, + { assertTrue(reader.nextRow()) }, + { assertEquals(2, reader.getLong(TASK_ID)) }, + { assertEquals(17, reader.getInt(TASK_ALLOC_NCPUS)) }, + ) + + reader.close() + } + + @Test + fun testReaderPartition() { + val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) + val trace = SwfTraceFormat().open(input) + + assertThrows { + trace.getTable(TABLE_TASKS)!!.newReader("test") + } + } +} diff --git a/opendc-trace/opendc-trace-swf/src/test/resources/trace.swf b/opendc-trace/opendc-trace-swf/src/test/resources/trace.swf new file mode 100644 index 00000000..c3ecf890 --- /dev/null +++ b/opendc-trace/opendc-trace-swf/src/test/resources/trace.swf @@ -0,0 +1,6 @@ +; Excerpt from the PWA: CTC-SP2-1996-3.1-cln.swf + 1 0 588530 937 306 142.00 -1 -1 35100 -1 1 97 -1 307 3 -1 -1 -1 + 2 164472 356587 75 17 2.00 -1 -1 300 -1 1 81 -1 195 3 -1 -1 -1 + 3 197154 459987 35268 306 32792 -1 -1 35100 -1 0 97 -1 307 3 -1 -1 -1 + 4 310448 50431 29493 64 28745 -1 -1 64800 -1 1 38 -1 38 1 -1 -1 -1 + 5 310541 50766 29063 64 28191 -1 -1 64800 -1 1 38 -1 69 1 -1 -1 -1 diff --git a/settings.gradle.kts b/settings.gradle.kts index fd1d404a..73d9a151 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") include(":opendc-trace:opendc-trace-api") include(":opendc-trace:opendc-trace-gwf") +include(":opendc-trace:opendc-trace-swf") include(":opendc-trace:opendc-trace-bitbrains") include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") -- cgit v1.2.3 From b2308e1077dc60ec6a4dc646613a4be5b59695a6 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 1 Sep 2021 11:29:27 +0200 Subject: refactor(trace): Implement trace API for WTF reader This change updates the WTF trace reader to support the new streaming trace API. --- .../opendc-experiments-capelin/build.gradle.kts | 4 +- .../experiments/capelin/ExperimentHelpers.kt | 2 +- .../capelin/trace/ParquetTraceReader.kt | 2 - .../capelin/trace/RawParquetTraceReader.kt | 2 - .../capelin/trace/StreamingParquetTraceReader.kt | 2 - .../opendc/experiments/capelin/trace/TraceEntry.kt | 44 +++++++ .../experiments/capelin/trace/TraceReader.kt | 32 ++++++ .../experiments/capelin/trace/WorkloadSampler.kt | 1 - .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../opendc-experiments-energy21/build.gradle.kts | 1 - .../kotlin/org/opendc/format/trace/TraceEntry.kt | 44 ------- .../kotlin/org/opendc/format/trace/TraceReader.kt | 32 ------ .../org/opendc/format/trace/wtf/WtfTraceReader.kt | 126 --------------------- .../opendc/format/trace/wtf/WtfTraceReaderTest.kt | 47 -------- .../wtf-trace/tasks/schema-1.0/part.0.parquet | Bin 87475 -> 0 bytes opendc-trace/opendc-trace-wtf/build.gradle.kts | 37 ++++++ .../kotlin/org/opendc/trace/wtf/WtfTaskTable.kt | 64 +++++++++++ .../org/opendc/trace/wtf/WtfTaskTableReader.kt | 116 +++++++++++++++++++ .../main/kotlin/org/opendc/trace/wtf/WtfTrace.kt | 47 ++++++++ .../kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt | 41 +++++++ .../services/org.opendc.trace.spi.TraceFormat | 1 + .../org/opendc/trace/wtf/WtfTraceFormatTest.kt | 121 ++++++++++++++++++++ .../wtf-trace/tasks/schema-1.0/part.0.parquet | Bin 0 -> 87475 bytes opendc-web/opendc-web-runner/build.gradle.kts | 1 - settings.gradle.kts | 2 +- 25 files changed, 509 insertions(+), 262 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/TraceEntry.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/TraceReader.kt delete mode 100644 opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt delete mode 100644 opendc-format/src/test/kotlin/org/opendc/format/trace/wtf/WtfTraceReaderTest.kt delete mode 100644 opendc-format/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet create mode 100644 opendc-trace/opendc-trace-wtf/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt create mode 100644 opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt create mode 100644 opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt create mode 100644 opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-wtf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-wtf/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 97ca97ec..65cebe1b 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -31,7 +31,6 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcHarness.opendcHarnessApi) - implementation(projects.opendcFormat) implementation(projects.opendcTrace.opendcTraceParquet) implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) @@ -45,6 +44,9 @@ dependencies { implementation(libs.config) implementation(libs.progressbar) implementation(libs.clikt) + implementation(libs.jackson.module.kotlin) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") + } implementation(libs.parquet) testImplementation(libs.log4j.slf4j) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 20dd603f..46e11056 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -48,7 +48,7 @@ import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.monitor.ExperimentMetricExporter import org.opendc.experiments.capelin.monitor.ExperimentMonitor -import org.opendc.format.trace.TraceReader +import org.opendc.experiments.capelin.trace.TraceReader import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.power.SimplePowerDriver diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt index 0f49ecd2..0bf4ada6 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt @@ -24,8 +24,6 @@ package org.opendc.experiments.capelin.trace import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.Workload -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader import org.opendc.simulator.compute.workload.SimWorkload /** diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt index 2630784b..24ff0ba1 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt @@ -23,8 +23,6 @@ package org.opendc.experiments.capelin.trace import org.apache.avro.generic.GenericData -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.trace.util.parquet.LocalParquetReader diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt index 9bcbdc75..61e4cab5 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt @@ -30,8 +30,6 @@ import org.apache.parquet.filter2.predicate.FilterApi import org.apache.parquet.filter2.predicate.Statistics import org.apache.parquet.filter2.predicate.UserDefinedPredicate import org.apache.parquet.io.api.Binary -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.trace.util.parquet.LocalInputFile diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt new file mode 100644 index 00000000..303a6a8c --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2019 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace + +import java.util.UUID + +/** + * An entry in a workload trace. + * + * @param uid The unique identifier of the entry. + * @param name The name of the entry. + * @param start The start time of the workload. + * @param workload The workload of the entry. + * @param meta The meta-data associated with the workload. + */ +public data class TraceEntry( + val uid: UUID, + val name: String, + val start: Long, + val workload: T, + val meta: Map +) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt new file mode 100644 index 00000000..08304edc --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace + +/** + * An interface for reading workloads into memory. + * + * This interface must guarantee that the entries are delivered in order of submission time. + * + * @param T The shape of the workloads supported by this reader. + */ +public interface TraceReader : Iterator>, AutoCloseable diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt index 6de3f265..cb32ce88 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt @@ -26,7 +26,6 @@ import mu.KotlinLogging import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.SamplingStrategy import org.opendc.experiments.capelin.model.Workload -import org.opendc.format.trace.TraceEntry import org.opendc.simulator.compute.workload.SimWorkload import java.util.* import kotlin.random.Random diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 9d6329d1..2934bbe6 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -42,7 +42,7 @@ import org.opendc.experiments.capelin.monitor.ExperimentMonitor import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader -import org.opendc.format.trace.TraceReader +import org.opendc.experiments.capelin.trace.TraceReader import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation diff --git a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts index bc05f09b..7d34d098 100644 --- a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts @@ -31,7 +31,6 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcHarness.opendcHarnessApi) - implementation(projects.opendcFormat) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcSimulator.opendcSimulatorFailures) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/TraceEntry.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/TraceEntry.kt deleted file mode 100644 index 3ce79d69..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/TraceEntry.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2019 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace - -import java.util.UUID - -/** - * An entry in a workload trace. - * - * @param uid The unique identifier of the entry. - * @param name The name of the entry. - * @param start The start time of the workload. - * @param workload The workload of the entry. - * @param meta The meta-data associated with the workload. - */ -public data class TraceEntry( - val uid: UUID, - val name: String, - val start: Long, - val workload: T, - val meta: Map -) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/TraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/TraceReader.kt deleted file mode 100644 index 797a88d5..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/TraceReader.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace - -/** - * An interface for reading workloads into memory. - * - * This interface must guarantee that the entries are delivered in order of submission time. - * - * @param T The shape of the workloads supported by this reader. - */ -public interface TraceReader : Iterator>, AutoCloseable diff --git a/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt deleted file mode 100644 index e8e72f0e..00000000 --- a/opendc-format/src/main/kotlin/org/opendc/format/trace/wtf/WtfTraceReader.kt +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.wtf - -import org.apache.avro.generic.GenericRecord -import org.opendc.format.trace.TraceEntry -import org.opendc.format.trace.TraceReader -import org.opendc.simulator.compute.workload.SimFlopsWorkload -import org.opendc.trace.util.parquet.LocalParquetReader -import org.opendc.workflow.api.Job -import org.opendc.workflow.api.Task -import org.opendc.workflow.api.WORKFLOW_TASK_CORES -import org.opendc.workflow.api.WORKFLOW_TASK_DEADLINE -import java.io.File -import java.nio.file.Path -import java.util.UUID -import kotlin.math.min - -/** - * A [TraceReader] for the Workflow Trace Format (WTF). See the Workflow Trace Archive - * (https://wta.atlarge-research.com/) for more information about the format. - * - * @param path The path to the trace. - */ -public class WtfTraceReader(path: Path) : TraceReader { - /** - * The internal iterator to use for this reader. - */ - private val iterator: Iterator> - - /** - * Construct a [TraceReader] from the specified [path]. - * - * @param path The path to the trace. - */ - public constructor(path: File) : this(path.toPath()) - - /** - * Initialize the reader. - */ - init { - val workflows = mutableMapOf() - val starts = mutableMapOf() - val tasks = mutableMapOf() - val taskDependencies = mutableMapOf>() - - LocalParquetReader(path.resolve("tasks/schema-1.0")).use { reader -> - while (true) { - val nextRecord = reader.read() ?: break - - val workflowId = nextRecord.get("workflow_id") as Long - val taskId = nextRecord.get("id") as Long - val submitTime = nextRecord.get("ts_submit") as Long - val runtime = nextRecord.get("runtime") as Long - val cores = (nextRecord.get("resource_amount_requested") as Double).toInt() - - @Suppress("UNCHECKED_CAST") - val dependencies = (nextRecord.get("parents") as ArrayList).map { - it.get("item") as Long - } - - val flops: Long = 4100 * (runtime / 1000) * cores - - val workflow = workflows.getOrPut(workflowId) { - Job(UUID(0L, workflowId), "", HashSet()) - } - val workload = SimFlopsWorkload(flops) - val task = Task( - UUID(0L, taskId), - "", - HashSet(), - mapOf( - "workload" to workload, - WORKFLOW_TASK_CORES to cores, - WORKFLOW_TASK_DEADLINE to runtime - ) - ) - - starts.merge(workflowId, submitTime, ::min) - (workflow.tasks as MutableSet).add(task) - tasks[taskId] = task - taskDependencies[task] = dependencies - } - } - - // Fix dependencies and dependents for all tasks - taskDependencies.forEach { (task, dependencies) -> - (task.dependencies as MutableSet).addAll( - dependencies.map { taskId -> - tasks[taskId] ?: throw IllegalArgumentException("Dependency task with id $taskId not found") - } - ) - } - - // Create the entry iterator - iterator = workflows.map { (id, job) -> TraceEntry(job.uid, job.name, starts.getValue(id), job, job.metadata) } - .sortedBy { it.start } - .iterator() - } - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() {} -} diff --git a/opendc-format/src/test/kotlin/org/opendc/format/trace/wtf/WtfTraceReaderTest.kt b/opendc-format/src/test/kotlin/org/opendc/format/trace/wtf/WtfTraceReaderTest.kt deleted file mode 100644 index 31ae03e0..00000000 --- a/opendc-format/src/test/kotlin/org/opendc/format/trace/wtf/WtfTraceReaderTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.format.trace.wtf - -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import java.io.File - -/** - * Test suite for the [WtfTraceReader] class. - */ -class WtfTraceReaderTest { - /** - * Smoke test for parsing WTF traces. - */ - @Test - fun testParseWtf() { - val reader = WtfTraceReader(File("src/test/resources/wtf-trace")) - var entry = reader.next() - assertEquals(0, entry.start) - assertEquals(23, entry.workload.tasks.size) - - entry = reader.next() - assertEquals(333387, entry.start) - assertEquals(23, entry.workload.tasks.size) - } -} diff --git a/opendc-format/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet b/opendc-format/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet deleted file mode 100644 index d2044038..00000000 Binary files a/opendc-format/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet and /dev/null differ diff --git a/opendc-trace/opendc-trace-wtf/build.gradle.kts b/opendc-trace/opendc-trace-wtf/build.gradle.kts new file mode 100644 index 00000000..5051c7b0 --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/build.gradle.kts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for Workflow Trace Format (WTF) traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) + + implementation(projects.opendcTrace.opendcTraceParquet) +} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt new file mode 100644 index 00000000..be26f540 --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wtf + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * A [Table] containing the tasks in a GWF trace. + */ +internal class WtfTaskTable(private val path: Path) : Table { + override val name: String = TABLE_TASKS + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + TASK_ID -> true + TASK_WORKFLOW_ID -> true + TASK_SUBMIT_TIME -> true + TASK_WAIT_TIME -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_PARENTS -> true + TASK_CHILDREN -> true + TASK_GROUP_ID -> true + TASK_USER_ID -> true + else -> false + } + } + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("tasks/schema-1.0")) + return WtfTaskTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Invalid partition $partition") + } + + override fun toString(): String = "WtfTaskTable" +} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt new file mode 100644 index 00000000..b6789542 --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wtf + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader + +/** + * A [TableReader] implementation for the WTF format. + */ +internal class WtfTaskTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + TASK_ID -> true + TASK_WORKFLOW_ID -> true + TASK_SUBMIT_TIME -> true + TASK_WAIT_TIME -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_PARENTS -> true + TASK_CHILDREN -> true + TASK_GROUP_ID -> true + TASK_USER_ID -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + TASK_ID -> record["id"] + TASK_WORKFLOW_ID -> record["workflow_id"] + TASK_SUBMIT_TIME -> record["ts_submit"] + TASK_WAIT_TIME -> record["wait_time"] + TASK_RUNTIME -> record["runtime"] + TASK_REQ_NCPUS -> (record["resource_amount_requested"] as Double).toInt() + TASK_PARENTS -> (record["parents"] as ArrayList).map { it["item"] as Long }.toSet() + TASK_CHILDREN -> (record["children"] as ArrayList).map { it["item"] as Long }.toSet() + TASK_GROUP_ID -> record["group_id"] + TASK_USER_ID -> record["user_id"] + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + TASK_REQ_NCPUS -> (record["resource_amount_requested"] as Double).toInt() + TASK_GROUP_ID -> record["group_id"] as Int + TASK_USER_ID -> record["user_id"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + TASK_ID -> record["id"] as Long + TASK_WORKFLOW_ID -> record["workflow_id"] as Long + TASK_SUBMIT_TIME -> record["ts_submit"] as Long + TASK_WAIT_TIME -> record["wait_time"] as Long + TASK_RUNTIME -> record["runtime"] as Long + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getDouble(column: TableColumn): Double { + throw IllegalArgumentException("Invalid column") + } + + override fun close() { + reader.close() + } +} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt new file mode 100644 index 00000000..7eff0f5a --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wtf + +import org.opendc.trace.TABLE_TASKS +import org.opendc.trace.Table +import org.opendc.trace.Trace +import java.nio.file.Path + +/** + * [Trace] implementation for the WTF format. + */ +public class WtfTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_TASKS) + + override fun containsTable(name: String): Boolean = TABLE_TASKS == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + + return WtfTaskTable(path) + } + + override fun toString(): String = "SwfTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt new file mode 100644 index 00000000..781cb335 --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wtf + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A [TraceFormat] implementation for the Workflow Trace Format (WTF). + */ +public class WtfTraceFormat : TraceFormat { + override val name: String = "wtf" + + override fun open(url: URL): WtfTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return WtfTrace(path) + } +} diff --git a/opendc-trace/opendc-trace-wtf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-wtf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..32da52ff --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.wtf.WtfTraceFormat diff --git a/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt b/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt new file mode 100644 index 00000000..a05a523e --- /dev/null +++ b/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wtf + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.* +import java.io.File +import java.net.URL + +/** + * Test suite for the [WtfTraceFormat] class. + */ +class WtfTraceFormatTest { + @Test + fun testTraceExists() { + val input = File("src/test/resources/wtf-trace").toURI().toURL() + val format = WtfTraceFormat() + org.junit.jupiter.api.assertDoesNotThrow { + format.open(input) + } + } + + @Test + fun testTraceDoesNotExists() { + val input = File("src/test/resources/wtf-trace").toURI().toURL() + val format = WtfTraceFormat() + assertThrows { + format.open(URL(input.toString() + "help")) + } + } + + @Test + fun testTables() { + val input = File("src/test/resources/wtf-trace").toURI().toURL() + val format = WtfTraceFormat() + val trace = format.open(input) + + assertEquals(listOf(TABLE_TASKS), trace.tables) + } + + @Test + fun testTableExists() { + val input = File("src/test/resources/wtf-trace").toURI().toURL() + val format = WtfTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS) + + assertNotNull(table) + org.junit.jupiter.api.assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val input = File("src/test/resources/wtf-trace").toURI().toURL() + val format = WtfTraceFormat() + val trace = format.open(input) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + /** + * Smoke test for parsing WTF traces. + */ + @Test + fun testTableReader() { + val input = File("src/test/resources/wtf-trace") + val trace = WtfTraceFormat().open(input.toURI().toURL()) + val reader = trace.getTable(TABLE_TASKS)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals(362334516345962206, reader.getLong(TASK_ID)) }, + { assertEquals(1078341553348591493, reader.getLong(TASK_WORKFLOW_ID)) }, + { assertEquals(245604, reader.getLong(TASK_SUBMIT_TIME)) }, + { assertEquals(8163, reader.getLong(TASK_RUNTIME)) }, + { assertEquals(setOf(584055316413447529, 133113685133695608, 1008582348422865408), reader.get(TASK_PARENTS)) }, + ) + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals(502010169100446658, reader.getLong(TASK_ID)) }, + { assertEquals(1078341553348591493, reader.getLong(TASK_WORKFLOW_ID)) }, + { assertEquals(251325, reader.getLong(TASK_SUBMIT_TIME)) }, + { assertEquals(8216, reader.getLong(TASK_RUNTIME)) }, + { assertEquals(setOf(584055316413447529, 133113685133695608, 1008582348422865408), reader.get(TASK_PARENTS)) }, + ) + + reader.close() + } + + @Test + fun testTableReaderPartition() { + val input = File("src/test/resources/wtf-trace").toURI().toURL() + val format = WtfTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS)!! + + assertThrows { table.newReader("test") } + } +} diff --git a/opendc-trace/opendc-trace-wtf/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet b/opendc-trace/opendc-trace-wtf/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet new file mode 100644 index 00000000..d2044038 Binary files /dev/null and b/opendc-trace/opendc-trace-wtf/src/test/resources/wtf-trace/tasks/schema-1.0/part.0.parquet differ diff --git a/opendc-web/opendc-web-runner/build.gradle.kts b/opendc-web/opendc-web-runner/build.gradle.kts index 1f705b79..ec4a4673 100644 --- a/opendc-web/opendc-web-runner/build.gradle.kts +++ b/opendc-web/opendc-web-runner/build.gradle.kts @@ -36,7 +36,6 @@ application { dependencies { api(platform(projects.opendcPlatform)) implementation(projects.opendcCompute.opendcComputeSimulator) - implementation(projects.opendcFormat) implementation(projects.opendcExperiments.opendcExperimentsCapelin) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcTelemetry.opendcTelemetrySdk) diff --git a/settings.gradle.kts b/settings.gradle.kts index 73d9a151..5cae0a31 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,7 +30,6 @@ include(":opendc-workflow:opendc-workflow-service") include(":opendc-faas:opendc-faas-api") include(":opendc-faas:opendc-faas-service") include(":opendc-faas:opendc-faas-simulator") -include(":opendc-format") include(":opendc-experiments:opendc-experiments-capelin") include(":opendc-experiments:opendc-experiments-energy21") include(":opendc-experiments:opendc-experiments-serverless20") @@ -49,6 +48,7 @@ include(":opendc-telemetry:opendc-telemetry-sdk") include(":opendc-trace:opendc-trace-api") include(":opendc-trace:opendc-trace-gwf") include(":opendc-trace:opendc-trace-swf") +include(":opendc-trace:opendc-trace-wtf") include(":opendc-trace:opendc-trace-bitbrains") include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") -- cgit v1.2.3 From 8bae0f3053a53aac9d483ae97d99f2e7e80b42ef Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 1 Sep 2021 22:30:39 +0200 Subject: refactor(capelin): Migrate trace reader to new trace API This change updates the trace reading classes in the Capelin experiment to use the new trace API in order to re-use many of the trace reading parts. --- .../capelin/trace/RawParquetTraceReader.kt | 62 +++--- .../experiments/capelin/trace/TraceConverter.kt | 195 ++--------------- .../capelin/trace/bp/BPResourceStateTable.kt | 56 +++++ .../capelin/trace/bp/BPResourceStateTableReader.kt | 103 +++++++++ .../capelin/trace/bp/BPResourceTable.kt | 56 +++++ .../capelin/trace/bp/BPResourceTableReader.kt | 103 +++++++++ .../opendc/experiments/capelin/trace/bp/BPTrace.kt | 49 +++++ .../experiments/capelin/trace/bp/BPTraceFormat.kt | 47 +++++ .../capelin/trace/sv/SvResourceStateTable.kt | 140 +++++++++++++ .../capelin/trace/sv/SvResourceStateTableReader.kt | 230 +++++++++++++++++++++ .../opendc/experiments/capelin/trace/sv/SvTrace.kt | 45 ++++ .../experiments/capelin/trace/sv/SvTraceFormat.kt | 47 +++++ .../kotlin/org/opendc/trace/ResourceColumns.kt | 22 ++ .../org/opendc/trace/ResourceStateColumns.kt | 26 +++ 14 files changed, 975 insertions(+), 206 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt index 24ff0ba1..fa4e9ed8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt @@ -22,10 +22,10 @@ package org.opendc.experiments.capelin.trace -import org.apache.avro.generic.GenericData +import org.opendc.experiments.capelin.trace.bp.BPTraceFormat import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.trace.util.parquet.LocalParquetReader +import org.opendc.trace.* import java.io.File import java.util.UUID @@ -35,27 +35,30 @@ import java.util.UUID * @param path The directory of the traces. */ class RawParquetTraceReader(private val path: File) { + /** + * The [Trace] that represents this trace. + */ + private val trace = BPTraceFormat().open(path.toURI().toURL()) + /** * Read the fragments into memory. */ - private fun parseFragments(path: File): Map> { - val reader = LocalParquetReader(File(path, "trace.parquet")) + private fun parseFragments(): Map> { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() val fragments = mutableMapOf>() return try { - while (true) { - val record = reader.read() ?: break - - val id = record["id"].toString() - val time = record["time"] as Long - val duration = record["duration"] as Long - val cores = record["cores"] as Int - val cpuUsage = record["cpuUsage"] as Double + while (reader.nextRow()) { + val id = reader.get(RESOURCE_STATE_ID) + val time = reader.get(RESOURCE_STATE_TIMESTAMP) + val duration = reader.get(RESOURCE_STATE_DURATION) + val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) val fragment = SimTraceWorkload.Fragment( - time, - duration, + time.toEpochMilli(), + duration.toMillis(), cpuUsage, cores ) @@ -72,25 +75,24 @@ class RawParquetTraceReader(private val path: File) { /** * Read the metadata into a workload. */ - private fun parseMeta(path: File, fragments: Map>): List> { - val metaReader = LocalParquetReader(File(path, "meta.parquet")) + private fun parseMeta(fragments: Map>): List> { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() var counter = 0 val entries = mutableListOf>() return try { - while (true) { - val record = metaReader.read() ?: break + while (reader.nextRow()) { - val id = record["id"].toString() + val id = reader.get(RESOURCE_ID) if (!fragments.containsKey(id)) { continue } - val submissionTime = record["submissionTime"] as Long - val endTime = record["endTime"] as Long - val maxCores = record["maxCores"] as Int - val requiredMemory = record["requiredMemory"] as Long + val submissionTime = reader.get(RESOURCE_START_TIME) + val endTime = reader.get(RESOURCE_END_TIME) + val maxCores = reader.getInt(RESOURCE_NCPUS) + val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) val vmFragments = fragments.getValue(id).asSequence() @@ -98,13 +100,13 @@ class RawParquetTraceReader(private val path: File) { val workload = SimTraceWorkload(vmFragments) entries.add( TraceEntry( - uid, id, submissionTime, workload, + uid, id, submissionTime.toEpochMilli(), workload, mapOf( - "submit-time" to submissionTime, - "end-time" to endTime, + "submit-time" to submissionTime.toEpochMilli(), + "end-time" to endTime.toEpochMilli(), "total-load" to totalLoad, "cores" to maxCores, - "required-memory" to requiredMemory, + "required-memory" to requiredMemory.toLong(), "workload" to workload ) ) @@ -116,7 +118,7 @@ class RawParquetTraceReader(private val path: File) { e.printStackTrace() throw e } finally { - metaReader.close() + reader.close() } } @@ -126,8 +128,8 @@ class RawParquetTraceReader(private val path: File) { private val entries: List> init { - val fragments = parseFragments(path) - entries = parseMeta(path, fragments) + val fragments = parseFragments() + entries = parseMeta(fragments) } /** diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt index 0ded32f3..a021de8d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt @@ -36,8 +36,10 @@ import org.apache.avro.generic.GenericData import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.experiments.capelin.trace.sv.SvTraceFormat import org.opendc.trace.* import org.opendc.trace.bitbrains.BitbrainsTraceFormat +import org.opendc.trace.spi.TraceFormat import org.opendc.trace.util.parquet.LocalOutputFile import java.io.BufferedReader import java.io.File @@ -156,189 +158,19 @@ sealed class TraceConversion(name: String) : OptionGroup(name) { ): MutableList } -class SolvinityConversion : TraceConversion("Solvinity") { - private val clusters by option() - .split(",") - - private val vmPlacements by option("--vm-placements", help = "file containing the VM placements") - .file(canBeDir = false) - .convert { VmPlacementReader(it.inputStream()).use { reader -> reader.read() } } - .required() - - override fun read( - traceDirectory: File, - metaSchema: Schema, - metaWriter: ParquetWriter - ): MutableList { - val clusters = clusters?.toSet() ?: emptySet() - val timestampCol = 0 - val cpuUsageCol = 1 - val coreCol = 12 - val provisionedMemoryCol = 20 - val traceInterval = 5 * 60 * 1000L - - // Identify start time of the entire trace - var minTimestamp = Long.MAX_VALUE - traceDirectory.walk() - .filterNot { it.isDirectory } - .filter { it.extension == "csv" || it.extension == "txt" } - .toList() - .forEach file@{ vmFile -> - BufferedReader(FileReader(vmFile)).use { reader -> - reader.lineSequence() - .chunked(128) - .forEach { lines -> - for (line in lines) { - // Ignore comments in the trace - if (line.startsWith("#") || line.isBlank()) { - continue - } - - val vmId = vmFile.name - - // Check if VM in topology - val clusterName = vmPlacements[vmId] - if (clusterName == null || !clusters.contains(clusterName)) { - continue - } - - val values = line.split("\t") - val timestamp = (values[timestampCol].trim().toLong() - 5 * 60) * 1000L - - if (timestamp < minTimestamp) { - minTimestamp = timestamp - } - return@file - } - } - } - } - - println("Start of trace at $minTimestamp") - - val allFragments = mutableListOf() - - val begin = 15 * 24 * 60 * 60 * 1000L - val end = 45 * 24 * 60 * 60 * 1000L - - traceDirectory.walk() - .filterNot { it.isDirectory } - .filter { it.extension == "csv" || it.extension == "txt" } - .toList() - .forEach { vmFile -> - println(vmFile) - - var vmId = "" - var maxCores = -1 - var requiredMemory = -1L - var cores: Int - var minTime = Long.MAX_VALUE - - val flopsFragments = sequence { - var last: Fragment? = null - - BufferedReader(FileReader(vmFile)).use { reader -> - reader.lineSequence() - .chunked(128) - .forEach { lines -> - for (line in lines) { - // Ignore comments in the trace - if (line.startsWith("#") || line.isBlank()) { - continue - } - - val values = line.split("\t") - - vmId = vmFile.name - - // Check if VM in topology - val clusterName = vmPlacements[vmId] - if (clusterName == null || !clusters.contains(clusterName)) { - continue - } - - val timestamp = - (values[timestampCol].trim().toLong() - 5 * 60) * 1000L - minTimestamp - if (begin > timestamp || timestamp > end) { - continue - } - - cores = values[coreCol].trim().toInt() - requiredMemory = max(requiredMemory, values[provisionedMemoryCol].trim().toLong()) - maxCores = max(maxCores, cores) - minTime = min(minTime, timestamp) - val cpuUsage = values[cpuUsageCol].trim().toDouble() // MHz - requiredMemory = max(requiredMemory, values[provisionedMemoryCol].trim().toLong()) - maxCores = max(maxCores, cores) - - val flops: Long = (cpuUsage * 5 * 60).toLong() - - last = if (last != null && last!!.flops == 0L && flops == 0L) { - val oldFragment = last!! - Fragment( - vmId, - oldFragment.tick, - oldFragment.flops + flops, - oldFragment.duration + traceInterval, - cpuUsage, - cores - ) - } else { - val fragment = - Fragment( - vmId, - timestamp, - flops, - traceInterval, - cpuUsage, - cores - ) - if (last != null) { - yield(last!!) - } - fragment - } - } - } - } - - if (last != null) { - yield(last!!) - } - } - - var maxTime = Long.MIN_VALUE - flopsFragments.filter { it.tick in begin until end }.forEach { fragment -> - allFragments.add(fragment) - maxTime = max(maxTime, fragment.tick) - } - - if (minTime in begin until end) { - val metaRecord = GenericData.Record(metaSchema) - metaRecord.put("id", vmId) - metaRecord.put("submissionTime", minTime) - metaRecord.put("endTime", maxTime) - metaRecord.put("maxCores", maxCores) - metaRecord.put("requiredMemory", requiredMemory) - metaWriter.write(metaRecord) - } - } - - return allFragments - } -} - /** - * Conversion of the Bitbrains public trace. + * A [TraceConversion] that uses the Trace API to perform the conversion. */ -class BitbrainsConversion : TraceConversion("Bitbrains") { +abstract class AbstractConversion(name: String) : TraceConversion(name) { + abstract val format: TraceFormat + override fun read( traceDirectory: File, metaSchema: Schema, metaWriter: ParquetWriter ): MutableList { val fragments = mutableListOf() - val trace = BitbrainsTraceFormat().open(traceDirectory.toURI().toURL()) + val trace = format.open(traceDirectory.toURI().toURL()) val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() var lastId: String? = null @@ -364,7 +196,7 @@ class BitbrainsConversion : TraceConversion("Bitbrains") { val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP) val timestampMs = timestamp.toEpochMilli() - val cpuUsage = reader.getDouble(RESOURCE_STATE_MEM_USAGE) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) val cores = reader.getInt(RESOURCE_STATE_NCPUS) val memCapacity = reader.getDouble(RESOURCE_STATE_MEM_CAPACITY) @@ -410,6 +242,17 @@ class BitbrainsConversion : TraceConversion("Bitbrains") { } } +class SolvinityConversion : AbstractConversion("Solvinity") { + override val format: TraceFormat = SvTraceFormat() +} + +/** + * Conversion of the Bitbrains public trace. + */ +class BitbrainsConversion : AbstractConversion("Bitbrains") { + override val format: TraceFormat = BitbrainsTraceFormat() +} + /** * Conversion of the Azure public VM trace. */ diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt new file mode 100644 index 00000000..35bfd5ef --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * The resource state [Table] in the Bitbrains Parquet format. + */ +internal class BPResourceStateTable(private val path: Path) : Table { + override val name: String = TABLE_RESOURCE_STATES + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_DURATION -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_USAGE -> true + else -> false + } + } + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("trace.parquet")) + return BPResourceStateTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt new file mode 100644 index 00000000..0e7ee555 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Duration +import java.time.Instant + +/** + * A [TableReader] implementation for the Bitbrains Parquet format. + */ +internal class BPResourceStateTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_DURATION -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_USAGE -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + RESOURCE_STATE_ID -> record["id"].toString() + RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record["time"] as Long) + RESOURCE_STATE_DURATION -> Duration.ofMillis(record["duration"] as Long) + RESOURCE_STATE_NCPUS -> record["cores"] + RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_STATE_NCPUS -> record["cores"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + val record = checkNotNull(record) { "Reader in invalid state" } + return when (column) { + RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + override fun toString(): String = "BPResourceStateTableReader" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt new file mode 100644 index 00000000..74d1e574 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * The resource [Table] in the Bitbrains Parquet format. + */ +internal class BPResourceTable(private val path: Path) : Table { + override val name: String = TABLE_RESOURCES + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_END_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("meta.parquet")) + return BPResourceTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt new file mode 100644 index 00000000..0a105783 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Instant + +/** + * A [TableReader] implementation for the Bitbrains Parquet format. + */ +internal class BPResourceTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_END_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + RESOURCE_ID -> record["id"].toString() + RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) + RESOURCE_END_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) + RESOURCE_NCPUS -> record["maxCores"] + RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_NCPUS -> record["maxCores"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + override fun toString(): String = "BPResourceTableReader" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt new file mode 100644 index 00000000..486587b1 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.opendc.trace.TABLE_RESOURCES +import org.opendc.trace.TABLE_RESOURCE_STATES +import org.opendc.trace.Table +import org.opendc.trace.Trace +import java.nio.file.Path + +/** + * A [Trace] in the Bitbrains Parquet format. + */ +public class BPTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = + name == TABLE_RESOURCES || name == TABLE_RESOURCE_STATES + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_RESOURCES -> BPResourceTable(path) + TABLE_RESOURCE_STATES -> BPResourceStateTable(path) + else -> null + } + } + + override fun toString(): String = "BPTrace[$path]" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt new file mode 100644 index 00000000..49d5b4c5 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the GWF trace format. + */ +public class BPTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "bitbrains-parquet" + + /** + * Open a Bitbrains Parquet trace. + */ + override fun open(url: URL): BPTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return BPTrace(path) + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt new file mode 100644 index 00000000..71c9d52e --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.sv + +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.bufferedReader +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] in the Bitbrains format. + */ +internal class SvResourceStateTable(path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "txt" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_CLUSTER_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_STATE_CPU_USAGE -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + RESOURCE_STATE_CPU_DEMAND -> true + RESOURCE_STATE_CPU_READY_PCT -> true + RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_STATE_DISK_READ -> true + RESOURCE_STATE_DISK_WRITE -> true + else -> false + } + } + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (partition, path) = it.next() + val reader = path.bufferedReader() + return SvResourceStateTableReader(partition, reader) + } else { + null + } + } + + override fun toString(): String = "BitbrainsCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + val reader = path.bufferedReader() + return SvResourceStateTableReader(partition, reader) + } + + override fun toString(): String = "SvResourceStateTable" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt new file mode 100644 index 00000000..adcdb2ea --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.sv + +import org.opendc.trace.* +import java.io.BufferedReader +import java.time.Instant + +/** + * A [TableReader] for the Bitbrains resource state table. + */ +internal class SvResourceStateTableReader(partition: String, private val reader: BufferedReader) : TableReader { + /** + * The current parser state. + */ + private val state = RowState() + + override fun nextRow(): Boolean { + state.reset() + + var line: String + var num = 0 + + while (true) { + line = reader.readLine() ?: return false + num++ + + if (line[0] == '#' || line.isBlank()) { + // Ignore empty lines or comments + continue + } + + break + } + + line = line.trim() + + val length = line.length + var col = 0 + var start = 0 + var end = 0 + + while (end < length) { + // Trim all whitespace before the field + start = end + while (start < length && line[start].isWhitespace()) { + start++ + } + + end = line.indexOf(' ', start) + + if (end < 0) { + break + } + + val field = line.subSequence(start, end) as String + when (col++) { + COL_TIMESTAMP -> state.timestamp = Instant.ofEpochSecond(field.toLong(10)) + COL_CPU_USAGE -> state.cpuUsage = field.toDouble() + COL_CPU_DEMAND -> state.cpuDemand = field.toDouble() + COL_DISK_READ -> state.diskRead = field.toDouble() + COL_DISK_WRITE -> state.diskWrite = field.toDouble() + COL_CLUSTER_ID -> state.cluster = field.trim() + COL_NCPUS -> state.cpuCores = field.toInt(10) + COL_CPU_READY_PCT -> state.cpuReadyPct = field.toDouble() + COL_POWERED_ON -> state.poweredOn = field.toInt(10) == 1 + COL_CPU_CAPACITY -> state.cpuCapacity = field.toDouble() + COL_ID -> state.id = field.trim() + COL_MEM_CAPACITY -> state.memCapacity = field.toDouble() + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_CLUSTER_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_STATE_CPU_USAGE -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + RESOURCE_STATE_CPU_DEMAND -> true + RESOURCE_STATE_CPU_READY_PCT -> true + RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_STATE_DISK_READ -> true + RESOURCE_STATE_DISK_WRITE -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> state.id + RESOURCE_STATE_CLUSTER_ID -> state.cluster + RESOURCE_STATE_TIMESTAMP -> state.timestamp + RESOURCE_STATE_NCPUS -> state.cpuCores + RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity + RESOURCE_STATE_CPU_USAGE -> state.cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsage / state.cpuCapacity + RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity + RESOURCE_STATE_DISK_READ -> state.diskRead + RESOURCE_STATE_DISK_WRITE -> state.diskWrite + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + return when (column) { + RESOURCE_STATE_POWERED_ON -> state.poweredOn + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_STATE_NCPUS -> state.cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity + RESOURCE_STATE_CPU_USAGE -> state.cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsage / state.cpuCapacity + RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity + RESOURCE_STATE_DISK_READ -> state.diskRead + RESOURCE_STATE_DISK_WRITE -> state.diskWrite + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + /** + * The current row state. + */ + private class RowState { + @JvmField + var id: String? = null + @JvmField + var cluster: String? = null + @JvmField + var timestamp: Instant? = null + @JvmField + var cpuCores = -1 + @JvmField + var cpuCapacity = Double.NaN + @JvmField + var cpuUsage = Double.NaN + @JvmField + var cpuDemand = Double.NaN + @JvmField + var cpuReadyPct = Double.NaN + @JvmField + var memCapacity = Double.NaN + @JvmField + var diskRead = Double.NaN + @JvmField + var diskWrite = Double.NaN + @JvmField + var poweredOn: Boolean = false + + /** + * Reset the state. + */ + fun reset() { + id = null + timestamp = null + cluster = null + cpuCores = -1 + cpuCapacity = Double.NaN + cpuUsage = Double.NaN + cpuDemand = Double.NaN + cpuReadyPct = Double.NaN + memCapacity = Double.NaN + diskRead = Double.NaN + diskWrite = Double.NaN + poweredOn = false + } + } + + /** + * Default column indices for the extended Bitbrains format. + */ + private val COL_TIMESTAMP = 0 + private val COL_CPU_USAGE = 1 + private val COL_CPU_DEMAND = 2 + private val COL_DISK_READ = 4 + private val COL_DISK_WRITE = 6 + private val COL_CLUSTER_ID = 10 + private val COL_NCPUS = 12 + private val COL_CPU_READY_PCT = 13 + private val COL_POWERED_ON = 14 + private val COL_CPU_CAPACITY = 18 + private val COL_ID = 19 + private val COL_MEM_CAPACITY = 20 +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt new file mode 100644 index 00000000..dbd63de5 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.sv + +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the extended Bitbrains format. + */ +public class SvTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + + return SvResourceStateTable(path) + } + + override fun toString(): String = "SvTrace[$path]" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt new file mode 100644 index 00000000..0cce8559 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.sv + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the extended Bitbrains trace format. + */ +public class SvTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "sv" + + /** + * Open the trace file. + */ + override fun open(url: URL): SvTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return SvTrace(path) + } +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt index 65055762..8945823a 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt @@ -23,7 +23,29 @@ @file:JvmName("ResourceColumns") package org.opendc.trace +import java.time.Instant + /** * Identifier of the resource. */ public val RESOURCE_ID: TableColumn = stringColumn("resource:id") + +/** + * Start time for the resource. + */ +public val RESOURCE_START_TIME: TableColumn = TableColumn("resource:start_time", Instant::class.java) + +/** + * End time for the resource. + */ +public val RESOURCE_END_TIME: TableColumn = TableColumn("resource:end_time", Instant::class.java) + +/** + * Number of CPUs for the resource. + */ +public val RESOURCE_NCPUS: TableColumn = intColumn("resource:num_cpus") + +/** + * Memory capacity for the resource. + */ +public val RESOURCE_MEM_CAPACITY: TableColumn = doubleColumn("resource:mem_capacity") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt index 17f52ab6..c2d896a8 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt @@ -23,6 +23,7 @@ @file:JvmName("ResourceStateColumns") package org.opendc.trace +import java.time.Duration import java.time.Instant /** @@ -30,11 +31,26 @@ import java.time.Instant */ public val RESOURCE_STATE_ID: TableColumn = stringColumn("resource_state:id") +/** + * The cluster to which the resource belongs. + */ +public val RESOURCE_STATE_CLUSTER_ID: TableColumn = stringColumn("resource_state:cluster_id") + /** * Timestamp for the state. */ public val RESOURCE_STATE_TIMESTAMP: TableColumn = TableColumn("resource_state:timestamp", Instant::class.java) +/** + * Duration for the state. + */ +public val RESOURCE_STATE_DURATION: TableColumn = TableColumn("resource_state:duration", Duration::class.java) + +/** + * A flag to indicate that the resource is powered on. + */ +public val RESOURCE_STATE_POWERED_ON: TableColumn = booleanColumn("resource_state:powered_on") + /** * Number of CPUs for the resource. */ @@ -55,6 +71,16 @@ public val RESOURCE_STATE_CPU_USAGE: TableColumn = doubleColumn("resourc */ public val RESOURCE_STATE_CPU_USAGE_PCT: TableColumn = doubleColumn("resource_state:cpu_usage_pct") +/** + * Total CPU demand of the resource in MHz. + */ +public val RESOURCE_STATE_CPU_DEMAND: TableColumn = doubleColumn("resource_state:cpu_demand") + +/** + * CPU ready percentage. + */ +public val RESOURCE_STATE_CPU_READY_PCT: TableColumn = doubleColumn("resource_state:cpu_ready_pct") + /** * Memory capacity of the resource in KB. */ -- cgit v1.2.3 From 5935531137a22fdb920921580d491f86adec65c9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 2 Sep 2021 11:11:50 +0200 Subject: perf(trace): Improve performance of column lookup --- .../src/main/kotlin/org/opendc/trace/ResourceColumns.kt | 5 +++++ .../kotlin/org/opendc/trace/ResourceStateColumns.kt | 17 +++++++++++++++++ .../src/main/kotlin/org/opendc/trace/TableColumn.kt | 13 +++++++++++-- .../src/main/kotlin/org/opendc/trace/TaskColumns.kt | 12 ++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt index 8945823a..44dec95b 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt @@ -28,24 +28,29 @@ import java.time.Instant /** * Identifier of the resource. */ +@JvmField public val RESOURCE_ID: TableColumn = stringColumn("resource:id") /** * Start time for the resource. */ +@JvmField public val RESOURCE_START_TIME: TableColumn = TableColumn("resource:start_time", Instant::class.java) /** * End time for the resource. */ +@JvmField public val RESOURCE_END_TIME: TableColumn = TableColumn("resource:end_time", Instant::class.java) /** * Number of CPUs for the resource. */ +@JvmField public val RESOURCE_NCPUS: TableColumn = intColumn("resource:num_cpus") /** * Memory capacity for the resource. */ +@JvmField public val RESOURCE_MEM_CAPACITY: TableColumn = doubleColumn("resource:mem_capacity") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt index c2d896a8..1933967e 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt @@ -29,84 +29,101 @@ import java.time.Instant /** * Identifier of the resource. */ +@JvmField public val RESOURCE_STATE_ID: TableColumn = stringColumn("resource_state:id") /** * The cluster to which the resource belongs. */ +@JvmField public val RESOURCE_STATE_CLUSTER_ID: TableColumn = stringColumn("resource_state:cluster_id") /** * Timestamp for the state. */ +@JvmField public val RESOURCE_STATE_TIMESTAMP: TableColumn = TableColumn("resource_state:timestamp", Instant::class.java) /** * Duration for the state. */ +@JvmField public val RESOURCE_STATE_DURATION: TableColumn = TableColumn("resource_state:duration", Duration::class.java) /** * A flag to indicate that the resource is powered on. */ +@JvmField public val RESOURCE_STATE_POWERED_ON: TableColumn = booleanColumn("resource_state:powered_on") /** * Number of CPUs for the resource. */ +@JvmField public val RESOURCE_STATE_NCPUS: TableColumn = intColumn("resource_state:ncpus") /** * Total CPU capacity of the resource in MHz. */ +@JvmField public val RESOURCE_STATE_CPU_CAPACITY: TableColumn = doubleColumn("resource_state:cpu_capacity") /** * Total CPU usage of the resource in MHz. */ +@JvmField public val RESOURCE_STATE_CPU_USAGE: TableColumn = doubleColumn("resource_state:cpu_usage") /** * Total CPU usage of the resource in percentage. */ +@JvmField public val RESOURCE_STATE_CPU_USAGE_PCT: TableColumn = doubleColumn("resource_state:cpu_usage_pct") /** * Total CPU demand of the resource in MHz. */ +@JvmField public val RESOURCE_STATE_CPU_DEMAND: TableColumn = doubleColumn("resource_state:cpu_demand") /** * CPU ready percentage. */ +@JvmField public val RESOURCE_STATE_CPU_READY_PCT: TableColumn = doubleColumn("resource_state:cpu_ready_pct") /** * Memory capacity of the resource in KB. */ +@JvmField public val RESOURCE_STATE_MEM_CAPACITY: TableColumn = doubleColumn("resource_state:mem_capacity") /** * Memory usage of the resource in KB. */ +@JvmField public val RESOURCE_STATE_MEM_USAGE: TableColumn = doubleColumn("resource_state:mem_usage") /** * Disk read throughput of the resource in KB/s. */ +@JvmField public val RESOURCE_STATE_DISK_READ: TableColumn = doubleColumn("resource_state:disk_read") /** * Disk write throughput of the resource in KB/s. */ +@JvmField public val RESOURCE_STATE_DISK_WRITE: TableColumn = doubleColumn("resource_state:disk_write") /** * Network receive throughput of the resource in KB/s. */ +@JvmField public val RESOURCE_STATE_NET_RX: TableColumn = doubleColumn("resource_state:net_rx") /** * Network transmit throughput of the resource in KB/s. */ +@JvmField public val RESOURCE_STATE_NET_TX: TableColumn = doubleColumn("resource_state:net_tx") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt index 247e7312..776c40c0 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumn.kt @@ -39,7 +39,7 @@ public class TableColumn(public val name: String, type: Class) { * Determine whether the type of the column is a subtype of [column]. */ public fun isAssignableTo(column: TableColumn<*>): Boolean { - return type.isAssignableFrom(column.type) + return name == column.name && type.isAssignableFrom(column.type) } /** @@ -50,7 +50,16 @@ public class TableColumn(public val name: String, type: Class) { /** * Determine whether this column is equal to [other]. */ - public override fun equals(other: Any?): Boolean = other is TableColumn<*> && name == other.name && type == other.type + public override fun equals(other: Any?): Boolean { + // Fast-path: reference equality + if (this === other) { + return true + } else if (other == null || other !is TableColumn<*>) { + return false + } + + return name == other.name && type == other.type + } /** * Return a string representation of this column. diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt index 5d3143ff..88bbc623 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt @@ -26,61 +26,73 @@ package org.opendc.trace /** * A column containing the task identifier. */ +@JvmField public val TASK_ID: TableColumn = longColumn("task:id") /** * A column containing the identifier of the workflow. */ +@JvmField public val TASK_WORKFLOW_ID: TableColumn = longColumn("task:workflow_id") /** * A column containing the submit time of the task. */ +@JvmField public val TASK_SUBMIT_TIME: TableColumn = longColumn("task:submit_time") /** * A column containing the wait time of the task. */ +@JvmField public val TASK_WAIT_TIME: TableColumn = longColumn("task:wait_time") /** * A column containing the runtime time of the task. */ +@JvmField public val TASK_RUNTIME: TableColumn = longColumn("task:runtime") /** * A column containing the parents of a task. */ @Suppress("UNCHECKED_CAST") +@JvmField public val TASK_PARENTS: TableColumn> = TableColumn("task:parents", type = Set::class.java as Class>) /** * A column containing the children of a task. */ @Suppress("UNCHECKED_CAST") +@JvmField public val TASK_CHILDREN: TableColumn> = TableColumn("task:children", type = Set::class.java as Class>) /** * A column containing the requested CPUs of a task. */ +@JvmField public val TASK_REQ_NCPUS: TableColumn = intColumn("task:req_ncpus") /** * A column containing the allocated CPUs of a task. */ +@JvmField public val TASK_ALLOC_NCPUS: TableColumn = intColumn("task:alloc_ncpus") /** * A column containing the status of a task. */ +@JvmField public val TASK_STATUS: TableColumn = intColumn("task:status") /** * A column containing the group id of a task. */ +@JvmField public val TASK_GROUP_ID: TableColumn = intColumn("task:group_id") /** * A column containing the user id of a task. */ +@JvmField public val TASK_USER_ID: TableColumn = intColumn("task:user_id") -- cgit v1.2.3 From 67fb9de33fc0ab5289770b23210401948f63e5c3 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 2 Sep 2021 12:58:19 +0200 Subject: build: Update to Gradle 7.2 This change updates the Gradle version of the supplied Gradle wrapper to version 7.2. * Update Gradle to version 7.2 * Address incompatibilities with version catalog * Remove opendc-format module. --- .../main/kotlin/benchmark-conventions.gradle.kts | 4 +- .../src/main/kotlin/testing-conventions.gradle.kts | 6 +-- gradle/libs.versions.toml | 53 +++++++++++++-------- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- opendc-format/build.gradle.kts | 47 ------------------ 7 files changed, 40 insertions(+), 74 deletions(-) delete mode 100644 opendc-format/build.gradle.kts diff --git a/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts b/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts index 78ed5d1f..590f51cf 100644 --- a/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts @@ -50,14 +50,14 @@ benchmark { targets { register("jmh") { this as JvmBenchmarkTarget - jmhVersion = "1.32" + jmhVersion = "1.33" } } } dependencies { val libs = Libs(project) - implementation(libs["kotlinx-benchmark-runtime-jvm"]) + implementation(libs["kotlinx.benchmark.runtime.jvm"]) } // Workaround for https://github.com/Kotlin/kotlinx-benchmark/issues/39 diff --git a/buildSrc/src/main/kotlin/testing-conventions.gradle.kts b/buildSrc/src/main/kotlin/testing-conventions.gradle.kts index bceb9e00..ebeb58a4 100644 --- a/buildSrc/src/main/kotlin/testing-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/testing-conventions.gradle.kts @@ -36,8 +36,8 @@ tasks.test { dependencies { val libs = Libs(project) - testImplementation(libs["junit-jupiter-api"]) - testImplementation(libs["junit-jupiter-params"]) + testImplementation(libs["junit.jupiter.api"]) + testImplementation(libs["junit.jupiter.params"]) testImplementation(libs["mockk"]) - testRuntimeOnly(libs["junit-jupiter-engine"]) + testRuntimeOnly(libs["junit.jupiter.engine"]) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fd737393..76846104 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,23 +1,35 @@ [versions] +classgraph = "4.8.115" +clikt = "3.2.0" +config = "1.4.1" +hadoop = "3.3.1" +jackson = "2.12.5" junit-jupiter = "5.7.2" junit-platform = "1.7.2" -slf4j = "1.7.32" +kotlin-logging = "2.0.11" +kotlinx-benchmark = "0.3.1" +kotlinx-coroutines = "1.5.1" +ktor = "1.6.3" log4j = "2.14.1" +mockk = "1.12.0" opentelemetry-main = "1.5.0" opentelemetry-metrics = "1.5.0-alpha" opentelemetry-semconv = "1.5.0-alpha" -hadoop = "3.3.1" -ktor = "1.6.3" -jackson = "2.12.5" +parquet = "1.12.0" +progressbar = "0.9.0" +sentry = "5.1.2" +slf4j = "1.7.32" +yaml = "1.29" [libraries] -kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.5.1" } +# Kotlin +kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } # Logging -kotlin-logging = { module = "io.github.microutils:kotlin-logging", version = "2.0.11" } +kotlin-logging = { module = "io.github.microutils:kotlin-logging", version.ref = "kotlin-logging" } slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } log4j-slf4j = { module = "org.apache.logging.log4j:log4j-slf4j-impl", version.ref = "log4j" } -sentry-log4j2 = { module = "io.sentry:sentry-log4j2", version = "4.3.0" } +sentry-log4j2 = { module = "io.sentry:sentry-log4j2", version.ref = "sentry" } # Telemetry opentelemetry-api-main = { module = "io.opentelemetry:opentelemetry-api", version.ref = "opentelemetry-main" } @@ -26,35 +38,36 @@ opentelemetry-api-metrics = { module = "io.opentelemetry:opentelemetry-api-metri opentelemetry-sdk-metrics = { module = "io.opentelemetry:opentelemetry-sdk-metrics", version.ref = "opentelemetry-metrics" } opentelemetry-semconv = { module = "io.opentelemetry:opentelemetry-semconv", version.ref = "opentelemetry-semconv" } - # Testing junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-jupiter" } junit-platform-commons = { module = "org.junit.platform:junit-platform-commons", version.ref = "junit-platform" } junit-platform-engine = { module = "org.junit.platform:junit-platform-engine", version.ref = "junit-platform" } -mockk = { module = "io.mockk:mockk", version = "1.12.0" } +mockk = { module = "io.mockk:mockk", version.ref = "mockk" } # CLI -clikt = { module = "com.github.ajalt.clikt:clikt", version = "3.2.0" } -progressbar = { module = "me.tongfei:progressbar", version = "0.9.0" } +clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" } +progressbar = { module = "me.tongfei:progressbar", version.ref = "progressbar" } # Format jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } jackson-dataformat-csv = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-csv", version.ref = "jackson" } -parquet = { module = "org.apache.parquet:parquet-avro", version = "1.12.0" } -yaml = { module = "org.yaml:snakeyaml", version = "1.29" } -config = { module = "com.typesafe:config", version = "1.4.1" } +parquet = { module = "org.apache.parquet:parquet-avro", version.ref = "parquet" } +yaml = { module = "org.yaml:snakeyaml", version.ref = "yaml" } +config = { module = "com.typesafe:config", version.ref = "config" } + +# HTTP client +ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } +ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } +ktor-client-jackson = { module = "io.ktor:ktor-client-jackson", version.ref = "ktor" } +ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } # Benchmark -kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime-jvm", version = "0.3.1" } +kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime-jvm", version.ref = "kotlinx-benchmark" } # Other -classgraph = { module = "io.github.classgraph:classgraph", version = "4.8.115" } +classgraph = { module = "io.github.classgraph:classgraph", version.ref = "classgraph" } hadoop-common = { module = "org.apache.hadoop:hadoop-common", version.ref = "hadoop" } hadoop-mapreduce-client-core = { module = "org.apache.hadoop:hadoop-mapreduce-client-core", version.ref = "hadoop" } -ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } -ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } -ktor-client-jackson = { module = "io.ktor:ktor-client-jackson", version.ref = "ktor" } -ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c0..7454180f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 69a97150..ffed3a25 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c..744e882e 100755 --- a/gradlew +++ b/gradlew @@ -72,7 +72,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) diff --git a/opendc-format/build.gradle.kts b/opendc-format/build.gradle.kts deleted file mode 100644 index 0c7f2a51..00000000 --- a/opendc-format/build.gradle.kts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2019 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -description = "Library for reading common data formats for topology simulation" - -/* Build configuration */ -plugins { - `kotlin-library-conventions` - `testing-conventions` - `jacoco-conventions` -} - -dependencies { - api(platform(projects.opendcPlatform)) - api(projects.opendcCompute.opendcComputeApi) - api(projects.opendcWorkflow.opendcWorkflowApi) - implementation(projects.opendcSimulator.opendcSimulatorCompute) - implementation(projects.opendcCompute.opendcComputeSimulator) - api(libs.jackson.module.kotlin) { - exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") - } - implementation(libs.jackson.dataformat.csv) - implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.30") - - implementation(projects.opendcTrace.opendcTraceParquet) - - testRuntimeOnly(libs.slf4j.simple) -} -- cgit v1.2.3 From eb4de7f832c6d26725e0d7c29644c704ea82604e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Sep 2021 12:48:19 +0200 Subject: build(ui): Bump immer from 9.0.5 to 9.0.6 Bumps [immer](https://github.com/immerjs/immer) from 9.0.5 to 9.0.6. - [Release notes](https://github.com/immerjs/immer/releases) - [Commits](https://github.com/immerjs/immer/compare/v9.0.5...v9.0.6) --- updated-dependencies: - dependency-name: immer dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- opendc-web/opendc-web-ui/package.json | 2 +- opendc-web/opendc-web-ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index f7d671b2..8d941e88 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -30,7 +30,7 @@ "approximate-number": "~2.0.0", "classnames": "~2.2.5", "husky": "~4.2.5", - "immer": "^9.0.5", + "immer": "^9.0.6", "konva": "~7.2.5", "lint-staged": "~10.2.2", "mathjs": "~7.6.0", diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index f6c3d031..bdd6cdd6 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -2144,10 +2144,10 @@ image-size@1.0.0: dependencies: queue "6.0.2" -immer@^9.0.5: - version "9.0.5" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.5.tgz#a7154f34fe7064f15f00554cc94c66cc0bf453ec" - integrity sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ== +immer@^9.0.6: + version "9.0.6" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73" + integrity sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ== import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" -- cgit v1.2.3 From 2dd9cc6ded8c47046f4faa1b2dd6aed1085d6644 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 17 Aug 2021 17:38:53 +0200 Subject: feat(compute): Track provisioning response time This change adds a metric for the provisioning time of virtual machines by the compute service. --- opendc-compute/opendc-compute-service/build.gradle.kts | 1 + .../compute/service/internal/ComputeServiceImpl.kt | 17 +++++++++++++++-- .../org/opendc/compute/service/InternalServerTest.kt | 6 +++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/opendc-compute/opendc-compute-service/build.gradle.kts b/opendc-compute/opendc-compute-service/build.gradle.kts index e0e48b0f..33cafc45 100644 --- a/opendc-compute/opendc-compute-service/build.gradle.kts +++ b/opendc-compute/opendc-compute-service/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { api(projects.opendcTelemetry.opendcTelemetryApi) implementation(projects.opendcUtils) implementation(libs.kotlin.logging) + implementation(libs.opentelemetry.semconv) testImplementation(projects.opendcSimulator.opendcSimulatorCore) testRuntimeOnly(libs.log4j.slf4j) diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index d7a7e8f8..8c043142 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -22,7 +22,9 @@ package org.opendc.compute.service.internal +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import kotlinx.coroutines.* import mu.KotlinLogging import org.opendc.compute.api.* @@ -159,6 +161,15 @@ internal class ComputeServiceImpl( .setUnit("1") .build() + /** + * The response time of the service. + */ + private val _schedulerDuration = meter.histogramBuilder("scheduler.duration") + .setDescription("End to end latency for a server to be scheduled (in multiple attempts)") + .ofLongs() + .setUnit("ms") + .build() + /** * The [TimerScheduler] to use for scheduling the scheduler cycles. */ @@ -325,7 +336,7 @@ internal class ComputeServiceImpl( internal fun schedule(server: InternalServer): SchedulingRequest { logger.debug { "Enqueueing server ${server.uid} to be assigned to host." } - val request = SchedulingRequest(server) + val request = SchedulingRequest(server, clock.millis()) queue.add(request) _submittedServers.add(1) _waitingServers.add(1) @@ -368,6 +379,7 @@ internal class ComputeServiceImpl( * Run a single scheduling iteration. */ private fun doSchedule() { + val now = clock.millis() while (queue.isNotEmpty()) { val request = queue.peek() @@ -402,6 +414,7 @@ internal class ComputeServiceImpl( // Remove request from queue queue.poll() _waitingServers.add(-1) + _schedulerDuration.record(now - request.submitTime, Attributes.of(ResourceAttributes.HOST_ID, server.uid.toString())) logger.info { "Assigned server $server to host $host." } @@ -430,7 +443,7 @@ internal class ComputeServiceImpl( /** * A request to schedule an [InternalServer] onto one of the [Host]s. */ - internal data class SchedulingRequest(val server: InternalServer) { + internal data class SchedulingRequest(val server: InternalServer, val submitTime: Long) { /** * A flag to indicate that the request is cancelled. */ diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt index 20ea8d20..28fd8217 100644 --- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt @@ -102,7 +102,7 @@ class InternalServerTest { val image = mockk() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) - every { service.schedule(any()) } answers { ComputeServiceImpl.SchedulingRequest(it.invocation.args[0] as InternalServer) } + every { service.schedule(any()) } answers { ComputeServiceImpl.SchedulingRequest(it.invocation.args[0] as InternalServer, 0) } server.start() @@ -160,7 +160,7 @@ class InternalServerTest { val flavor = mockk() val image = mockk() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) - val request = ComputeServiceImpl.SchedulingRequest(server) + val request = ComputeServiceImpl.SchedulingRequest(server, 0) every { service.schedule(any()) } returns request @@ -223,7 +223,7 @@ class InternalServerTest { val flavor = mockk() val image = mockk() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) - val request = ComputeServiceImpl.SchedulingRequest(server) + val request = ComputeServiceImpl.SchedulingRequest(server, 0) every { service.schedule(any()) } returns request -- cgit v1.2.3 From 9236b3cfb7be1e9d44fe60cbdd699c19c70f6411 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 17 Aug 2021 19:22:34 +0200 Subject: feat(compute): Track host up/down time This change adds new metrics for tracking the up and downtime of hosts due to failures. In addition, this change adds a test to verify whether the metrics are collected correctly. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 55 ++++++++++++++++++++++ .../org/opendc/compute/simulator/SimHostTest.kt | 10 ++++ 2 files changed, 65 insertions(+) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 20e5a9db..e12bd37b 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -71,6 +71,11 @@ public class SimHost( */ override val scope: CoroutineScope = CoroutineScope(context + Job()) + /** + * The clock instance used by the host. + */ + private val clock = interpreter.clock + /** * The logger instance of this server. */ @@ -115,6 +120,8 @@ public class SimHost( _cpuDemand.record(cpuDemand) _cpuUsage.record(cpuUsage) _powerUsage.record(machine.powerDraw) + + reportTime() } } ) @@ -221,6 +228,33 @@ public class SimHost( .build() .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) + /** + * The amount of time in the system. + */ + private val _totalTime = meter.counterBuilder("host.time.total") + .setDescription("The amount of time in the system") + .setUnit("ms") + .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) + + /** + * The uptime of the host. + */ + private val _upTime = meter.counterBuilder("host.time.up") + .setDescription("The uptime of the host") + .setUnit("ms") + .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) + + /** + * The downtime of the host. + */ + private val _downTime = meter.counterBuilder("host.time.down") + .setDescription("The downtime of the host") + .setUnit("ms") + .build() + .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) + init { // Launch hypervisor onto machine scope.launch { @@ -238,6 +272,24 @@ public class SimHost( } } + private var _lastReport = clock.millis() + + private fun reportTime() { + if (!scope.isActive) + return + + val now = clock.millis() + val duration = now - _lastReport + + _totalTime.add(duration) + when (_state) { + HostState.UP -> _upTime.add(duration) + HostState.DOWN -> _downTime.add(duration) + } + + _lastReport = now + } + override fun canFit(server: Server): Boolean { val sufficientMemory = availableMemory > server.flavor.memorySize val enoughCpus = machine.model.cpus.size >= server.flavor.cpuCount @@ -291,6 +343,7 @@ public class SimHost( } override fun close() { + reportTime() scope.cancel() machine.close() } @@ -320,6 +373,7 @@ public class SimHost( } override suspend fun fail() { + reportTime() _state = HostState.DOWN for (guest in guests.values) { guest.fail() @@ -327,6 +381,7 @@ public class SimHost( } override suspend fun recover() { + reportTime() _state = HostState.UP for (guest in guests.values) { guest.start() diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 1ba3a9a1..0a2ced7b 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -189,6 +189,8 @@ internal class SimHostTest { fun testFailure() = runBlockingSimulation { var requestedWork = 0L var grantedWork = 0L + var totalTime = 0L + var downTime = 0L val meterProvider: MeterProvider = SdkMeterProvider .builder() @@ -238,6 +240,12 @@ internal class SimHostTest { metricsByName["cpu.work.granted"]?.let { grantedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() } + metricsByName["host.time.total"]?.let { + totalTime = it.longSumData.points.first().value + } + metricsByName["host.time.down"]?.let { + downTime = it.longSumData.points.first().value + } return CompletableResultCode.ofSuccess() } @@ -275,6 +283,8 @@ internal class SimHostTest { assertAll( { assertEquals(2226039, requestedWork, "Total time does not match") }, { assertEquals(1086039, grantedWork, "Down time does not match") }, + { assertEquals(1200001, totalTime, "Total time does not match") }, + { assertEquals(5000, downTime, "Down time does not match") }, ) } -- cgit v1.2.3 From d097d65851619483a85ce16ab56f61a726bbe756 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 24 Aug 2021 16:55:42 +0200 Subject: fix(compute): Support overcommitted memory in SimHost This change enables host to overcommit their memory when testing whether new servers can fit on the host. --- .../src/main/kotlin/org/opendc/compute/simulator/SimHost.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index e12bd37b..76cc7dfe 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -86,11 +86,6 @@ public class SimHost( */ private val listeners = mutableListOf() - /** - * Current total memory use of the images on this hypervisor. - */ - private var availableMemory: Long = model.memory.sumOf { it.size } - /** * The machine to run on. */ @@ -291,7 +286,7 @@ public class SimHost( } override fun canFit(server: Server): Boolean { - val sufficientMemory = availableMemory > server.flavor.memorySize + val sufficientMemory = machine.model.memory.size >= server.flavor.memorySize val enoughCpus = machine.model.cpus.size >= server.flavor.cpuCount val canFit = hypervisor.canFit(server.flavor.toMachineModel()) @@ -469,7 +464,6 @@ public class SimHost( else ServerState.ERROR - availableMemory += server.flavor.memorySize onGuestStop(this) } } -- cgit v1.2.3 From 83d7e45a6b749df0c208e56885402c66e54c4b23 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 24 Aug 2021 17:06:35 +0200 Subject: fix(compute): Start host even if it already exists on host --- .../src/main/kotlin/org/opendc/compute/simulator/SimHost.kt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 76cc7dfe..4526537d 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -294,16 +294,12 @@ public class SimHost( } override suspend fun spawn(server: Server, start: Boolean) { - // Return if the server already exists on this host - if (server in this) { - return + val guest = guests.computeIfAbsent(server) { key -> + require(canFit(key)) { "Server does not fit" } + _guests.add(1) + Guest(key, hypervisor.createMachine(key.flavor.toMachineModel(), key.name)) } - require(canFit(server)) { "Server does not fit" } - val guest = Guest(server, hypervisor.createMachine(server.flavor.toMachineModel(), server.name)) - guests[server] = guest - _guests.add(1) - if (start) { guest.start() } -- cgit v1.2.3 From 2c507c6ca4b7d809b410d351f0c1c5c3ddf7bb5c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 25 Aug 2021 14:38:08 +0200 Subject: feat(compute): Track guest up/down time This change updates the SimHost implementation to track the up and downtime of hypervisor guests. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 54 +++++++++++++++++++++- .../org/opendc/compute/simulator/SimHostTest.kt | 10 ++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 4526537d..9a1f05fc 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -22,6 +22,7 @@ package org.opendc.compute.simulator +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter import io.opentelemetry.semconv.resource.attributes.ResourceAttributes @@ -59,7 +60,7 @@ public class SimHost( override val meta: Map, context: CoroutineContext, interpreter: SimResourceInterpreter, - meter: Meter, + private val meter: Meter, hypervisor: SimHypervisorProvider, scalingGovernor: ScalingGovernor = PerformanceScalingGovernor(), powerDriver: PowerDriver = SimplePowerDriver(ConstantPowerModel(0.0)), @@ -282,6 +283,11 @@ public class SimHost( HostState.DOWN -> _downTime.add(duration) } + // Track time of guests + for (guest in guests.values) { + guest.reportTime() + } + _lastReport = now } @@ -385,6 +391,33 @@ public class SimHost( private inner class Guest(val server: Server, val machine: SimMachine) { var state: ServerState = ServerState.TERMINATED + /** + * The amount of time in the system. + */ + private val _totalTime = meter.counterBuilder("guest.time.total") + .setDescription("The amount of time in the system") + .setUnit("ms") + .build() + .bind(Attributes.of(AttributeKey.stringKey("server.id"), server.uid.toString())) + + /** + * The uptime of the guest. + */ + private val _runningTime = meter.counterBuilder("guest.time.running") + .setDescription("The uptime of the guest") + .setUnit("ms") + .build() + .bind(Attributes.of(AttributeKey.stringKey("server.id"), server.uid.toString())) + + /** + * The time the guest is in an error state. + */ + private val _errorTime = meter.counterBuilder("guest.time.error") + .setDescription("The time the guest is in an error state") + .setUnit("ms") + .build() + .bind(Attributes.of(AttributeKey.stringKey("server.id"), server.uid.toString())) + suspend fun start() { when (state) { ServerState.TERMINATED, ServerState.ERROR -> { @@ -462,5 +495,24 @@ public class SimHost( onGuestStop(this) } + + private var _lastReport = clock.millis() + + fun reportTime() { + if (state == ServerState.DELETED) + return + + val now = clock.millis() + val duration = now - _lastReport + + _totalTime.add(duration) + when (state) { + ServerState.RUNNING -> _runningTime.add(duration) + ServerState.ERROR -> _errorTime.add(duration) + else -> {} + } + + _lastReport = now + } } } diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 0a2ced7b..31215e9a 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -191,6 +191,8 @@ internal class SimHostTest { var grantedWork = 0L var totalTime = 0L var downTime = 0L + var guestTotalTime = 0L + var guestDownTime = 0L val meterProvider: MeterProvider = SdkMeterProvider .builder() @@ -246,6 +248,12 @@ internal class SimHostTest { metricsByName["host.time.down"]?.let { downTime = it.longSumData.points.first().value } + metricsByName["guest.time.total"]?.let { + guestTotalTime = it.longSumData.points.first().value + } + metricsByName["guest.time.error"]?.let { + guestDownTime = it.longSumData.points.first().value + } return CompletableResultCode.ofSuccess() } @@ -284,7 +292,9 @@ internal class SimHostTest { { assertEquals(2226039, requestedWork, "Total time does not match") }, { assertEquals(1086039, grantedWork, "Down time does not match") }, { assertEquals(1200001, totalTime, "Total time does not match") }, + { assertEquals(1200001, guestTotalTime, "Guest total time does not match") }, { assertEquals(5000, downTime, "Down time does not match") }, + { assertEquals(5000, guestDownTime, "Guest down time does not match") }, ) } -- cgit v1.2.3 From b6a8c642b598bfb2eaaea2a8a7e6ad6702d349b6 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 26 Aug 2021 10:29:41 +0200 Subject: fix(compute): Use correct memory size for host memory This change fixes an issue where all servers could not be scheduled due to the memory size of the host being computed incorrectly. --- .../src/main/kotlin/org/opendc/compute/simulator/SimHost.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 9a1f05fc..a4d24740 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -292,8 +292,8 @@ public class SimHost( } override fun canFit(server: Server): Boolean { - val sufficientMemory = machine.model.memory.size >= server.flavor.memorySize - val enoughCpus = machine.model.cpus.size >= server.flavor.cpuCount + val sufficientMemory = model.memorySize >= server.flavor.memorySize + val enoughCpus = model.cpuCount >= server.flavor.cpuCount val canFit = hypervisor.canFit(server.flavor.toMachineModel()) return sufficientMemory && enoughCpus && canFit -- cgit v1.2.3 From 561f07bd6547c8273627e9c860324ab892ba5fa7 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 26 Aug 2021 10:30:53 +0200 Subject: fix(compute): Do not allow failure of inactive guests This change fixes an issue in SimHost where guests that where inactive were also failed, causing an IllegalStateException. --- .../src/main/kotlin/org/opendc/compute/simulator/SimHost.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index a4d24740..213d20ee 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -452,6 +452,9 @@ public class SimHost( } suspend fun fail() { + if (state != ServerState.RUNNING) { + return + } stop() state = ServerState.ERROR } -- cgit v1.2.3 From 1e8c8ebd2b537d3795022c3222d3e37b6e61e624 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 26 Aug 2021 10:32:07 +0200 Subject: fix(compute): Mark unschedulable server as terminated This change updates the compute service to mark servers that cannot be scheduled as terminated instead of error. Error is instead reserved for cases where the server is in an error state while running. --- .../org/opendc/compute/service/internal/ComputeServiceImpl.kt | 2 +- .../test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index 8c043142..f1c055d4 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -402,7 +402,7 @@ internal class ComputeServiceImpl( logger.warn("Failed to spawn $server: does not fit [${clock.millis()}]") - server.state = ServerState.ERROR + server.state = ServerState.TERMINATED continue } else { break diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt index c6c01ea2..d036ec00 100644 --- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt @@ -170,7 +170,7 @@ internal class ComputeServiceTest { server.start() delay(5L * 60 * 1000) server.refresh() - assertEquals(ServerState.ERROR, server.state) + assertEquals(ServerState.TERMINATED, server.state) } @Test @@ -183,7 +183,7 @@ internal class ComputeServiceTest { server.start() delay(5L * 60 * 1000) server.refresh() - assertEquals(ServerState.ERROR, server.state) + assertEquals(ServerState.TERMINATED, server.state) } @Test @@ -196,7 +196,7 @@ internal class ComputeServiceTest { server.start() delay(5L * 60 * 1000) server.refresh() - assertEquals(ServerState.ERROR, server.state) + assertEquals(ServerState.TERMINATED, server.state) } @Test -- cgit v1.2.3 From 289cd3b6bc9d86b017dbb1ce6c50d346841a0ee6 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 26 Aug 2021 10:33:42 +0200 Subject: refactor(capelin): Make ExperimentMonitor optional for trace processing --- .../main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 46e11056..9d23a5dd 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -255,7 +255,7 @@ suspend fun processTrace( reader: TraceReader, scheduler: ComputeService, chan: Channel, - monitor: ExperimentMonitor + monitor: ExperimentMonitor? = null, ) { val client = scheduler.newClient() val image = client.newImage("vm-image") @@ -289,7 +289,7 @@ suspend fun processTrace( suspendCancellableCoroutine { cont -> server.watch(object : ServerWatcher { override fun onStateChanged(server: Server, newState: ServerState) { - monitor.reportVmStateChange(clock.millis(), server, newState) + monitor?.reportVmStateChange(clock.millis(), server, newState) if (newState == ServerState.TERMINATED) { cont.resume(Unit) -- cgit v1.2.3 From befec2f1ddf3a6e6d15d9d1b9fd1ecbbc4f38960 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 26 Aug 2021 10:34:18 +0200 Subject: feat(capelin): Report up/downtime metrics in experiment monitor --- .../capelin/monitor/ExperimentMetricExporter.kt | 40 ++++++++++------------ .../capelin/monitor/ExperimentMonitor.kt | 2 ++ .../capelin/monitor/ParquetExperimentMonitor.kt | 2 ++ .../experiments/capelin/CapelinIntegrationTest.kt | 2 ++ .../org/opendc/web/runner/WebExperimentMonitor.kt | 2 ++ 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index 42b7cbb8..79be9ac4 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -54,7 +54,6 @@ public class ExperimentMetricExporter( private fun reportHostMetrics(metrics: Collection) { val hostMetrics = mutableMapOf() - hosts.mapValuesTo(hostMetrics) { HostMetrics() } for (metric in metrics) { when (metric.name) { @@ -66,12 +65,15 @@ public class ExperimentMetricExporter( "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } "cpu.work.interference" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.interferedWork = v } "guests.active" -> mapLongSum(metric, hostMetrics) { m, v -> m.instanceCount = v.toInt() } + "host.time.up" -> mapLongSum(metric, hostMetrics) { m, v -> m.uptime = v } + "host.time.down" -> mapLongSum(metric, hostMetrics) { m, v -> m.downtime = v } } } for ((id, hostMetric) in hostMetrics) { val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) - val host = hosts.getValue(id) + val host = hosts[id] ?: continue + monitor.reportHostData( clock.millis(), hostMetric.totalWork - lastHostMetric.totalWork, @@ -82,6 +84,8 @@ public class ExperimentMetricExporter( hostMetric.cpuDemand, hostMetric.powerDraw, hostMetric.instanceCount, + hostMetric.uptime - lastHostMetric.uptime, + hostMetric.downtime - lastHostMetric.downtime, host ) } @@ -92,38 +96,28 @@ public class ExperimentMetricExporter( private fun mapDoubleSummary(data: MetricData, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { val points = data.doubleSummaryData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] - val hostMetric = hostMetrics[uid] - - if (hostMetric != null) { - // Take the average of the summary - val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2 - block(hostMetric, avg) - } + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HostMetrics() } + val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2 + block(hostMetric, avg) } } private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Long) -> Unit) { val points = data?.longSumData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] - val hostMetric = hostMetrics[uid] - - if (hostMetric != null) { - block(hostMetric, point.value) - } + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HostMetrics() } + block(hostMetric, point.value) } } private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { val points = data?.doubleSumData?.points ?: emptyList() for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] - val hostMetric = hostMetrics[uid] - - if (hostMetric != null) { - block(hostMetric, point.value) - } + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HostMetrics() } + block(hostMetric, point.value) } } @@ -151,6 +145,8 @@ public class ExperimentMetricExporter( var cpuDemand: Double = 0.0 var instanceCount: Int = 0 var powerDraw: Double = 0.0 + var uptime: Long = 0 + var downtime: Long = 0 } override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt index 9a4aec35..dc28b816 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt @@ -54,6 +54,8 @@ public interface ExperimentMonitor : AutoCloseable { cpuDemand: Double, powerDraw: Double, instanceCount: Int, + uptime: Long, + downtime: Long, host: Host ) {} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt index 83351c41..c49499da 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt @@ -67,6 +67,8 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: cpuDemand: Double, powerDraw: Double, instanceCount: Int, + uptime: Long, + downtime: Long, host: Host ) { hostWriter.write( diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 2934bbe6..24d8f768 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -300,6 +300,8 @@ class CapelinIntegrationTest { cpuDemand: Double, powerDraw: Double, instanceCount: Int, + uptime: Long, + downtime: Long, host: Host, ) { this.totalWork += totalWork.toLong() diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt index 82e2a334..281c8dbb 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt @@ -53,6 +53,8 @@ public class WebExperimentMonitor : ExperimentMonitor { cpuDemand: Double, powerDraw: Double, instanceCount: Int, + uptime: Long, + downtime: Long, host: Host, ) { processHostEvent( -- cgit v1.2.3 From aaedd4f3eed83d0c3ebc829fec08a1749a2bfba4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 27 Aug 2021 16:41:55 +0200 Subject: refactor(capelin): Move metric collection outside Capelin code This change moves the metric collection outside the Capelin codebase in a separate module so other modules can also benefit from the compute metric collection code. --- .../opendc-experiments-capelin/build.gradle.kts | 1 + .../experiments/capelin/ExperimentHelpers.kt | 98 +---------- .../org/opendc/experiments/capelin/Portfolio.kt | 19 +- .../capelin/export/parquet/ParquetDataWriter.kt | 127 ++++++++++++++ .../capelin/export/parquet/ParquetExportMonitor.kt | 55 ++++++ .../export/parquet/ParquetHostDataWriter.kt | 73 ++++++++ .../export/parquet/ParquetServiceDataWriter.kt | 65 +++++++ .../capelin/monitor/ExperimentMetricExporter.kt | 155 ----------------- .../capelin/monitor/ExperimentMonitor.kt | 75 -------- .../capelin/monitor/ParquetExperimentMonitor.kt | 120 ------------- .../opendc/experiments/capelin/telemetry/Event.kt | 35 ---- .../experiments/capelin/telemetry/HostEvent.kt | 43 ----- .../capelin/telemetry/ProvisionerEvent.kt | 39 ----- .../experiments/capelin/telemetry/RunEvent.kt | 34 ---- .../experiments/capelin/telemetry/VmEvent.kt | 41 ----- .../telemetry/parquet/ParquetEventWriter.kt | 126 -------------- .../telemetry/parquet/ParquetHostEventWriter.kt | 81 --------- .../parquet/ParquetProvisionerEventWriter.kt | 65 ------- .../telemetry/parquet/ParquetRunEventWriter.kt | 72 -------- .../experiments/capelin/CapelinIntegrationTest.kt | 92 +++++----- .../opendc-experiments-energy21/build.gradle.kts | 1 + .../experiments/energy21/EnergyExperiment.kt | 18 +- .../opendc-telemetry-compute/build.gradle.kts | 37 ++++ .../telemetry/compute/ComputeMetricExporter.kt | 149 ++++++++++++++++ .../org/opendc/telemetry/compute/ComputeMonitor.kt | 61 +++++++ .../kotlin/org/opendc/telemetry/compute/Helpers.kt | 111 ++++++++++++ .../org/opendc/telemetry/compute/table/HostData.kt | 43 +++++ .../opendc/telemetry/compute/table/ServerData.kt | 35 ++++ .../opendc/telemetry/compute/table/ServiceData.kt | 37 ++++ opendc-web/opendc-web-runner/build.gradle.kts | 1 + .../src/main/kotlin/org/opendc/web/runner/Main.kt | 20 ++- .../org/opendc/web/runner/ScenarioManager.kt | 10 +- .../org/opendc/web/runner/WebComputeMonitor.kt | 145 ++++++++++++++++ .../org/opendc/web/runner/WebExperimentMonitor.kt | 191 --------------------- settings.gradle.kts | 1 + 35 files changed, 1039 insertions(+), 1237 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/Event.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/HostEvent.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/ProvisionerEvent.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/RunEvent.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/VmEvent.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetProvisionerEventWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetRunEventWriter.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/build.gradle.kts create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt create mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 65cebe1b..1a4caf91 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { implementation(projects.opendcSimulator.opendcSimulatorFailures) implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTelemetry.opendcTelemetrySdk) + implementation(projects.opendcTelemetry.opendcTelemetryCompute) implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 9d23a5dd..0230409e 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -24,16 +24,10 @@ package org.opendc.experiments.capelin import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.metrics.data.MetricData -import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import mu.KotlinLogging import org.opendc.compute.api.* import org.opendc.compute.service.ComputeService -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostListener -import org.opendc.compute.service.driver.HostState import org.opendc.compute.service.scheduler.ComputeScheduler import org.opendc.compute.service.scheduler.FilterScheduler import org.opendc.compute.service.scheduler.ReplayScheduler @@ -46,8 +40,6 @@ import org.opendc.compute.service.scheduler.weights.RamWeigher import org.opendc.compute.service.scheduler.weights.VCpuWeigher import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.env.EnvironmentReader -import org.opendc.experiments.capelin.monitor.ExperimentMetricExporter -import org.opendc.experiments.capelin.monitor.ExperimentMonitor import org.opendc.experiments.capelin.trace.TraceReader import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel @@ -57,7 +49,7 @@ import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.failures.CorrelatedFaultInjector import org.opendc.simulator.failures.FaultInjector import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader +import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.sdk.toOtelClock import java.time.Clock import kotlin.coroutines.resume @@ -65,11 +57,6 @@ import kotlin.math.ln import kotlin.math.max import kotlin.random.Random -/** - * The logger for this experiment. - */ -private val logger = KotlinLogging.logger {} - /** * Construct the failure domain for the experiments. */ @@ -168,85 +155,6 @@ suspend fun withComputeService( } } -/** - * Attach the specified monitor to the VM provisioner. - */ -suspend fun withMonitor( - monitor: ExperimentMonitor, - clock: Clock, - metricProducer: MetricProducer, - scheduler: ComputeService, - block: suspend CoroutineScope.() -> Unit -): Unit = coroutineScope { - // Monitor host events - for (host in scheduler.hosts) { - monitor.reportHostStateChange(clock.millis(), host, HostState.UP) - host.addListener(object : HostListener { - override fun onStateChanged(host: Host, newState: HostState) { - monitor.reportHostStateChange(clock.millis(), host, newState) - } - }) - } - - val reader = CoroutineMetricReader( - this, - listOf(metricProducer), - ExperimentMetricExporter(monitor, clock, scheduler.hosts.associateBy { it.uid.toString() }), - exportInterval = 5L * 60 * 1000 /* Every 5 min (which is the granularity of the workload trace) */ - ) - - try { - block(this) - } finally { - reader.close() - monitor.close() - } -} - -class ComputeMetrics { - var submittedVms: Int = 0 - var queuedVms: Int = 0 - var runningVms: Int = 0 - var unscheduledVms: Int = 0 - var finishedVms: Int = 0 - var hosts: Int = 0 - var availableHosts = 0 -} - -/** - * Collect the metrics of the compute service. - */ -fun collectMetrics(metricProducer: MetricProducer): ComputeMetrics { - return extractComputeMetrics(metricProducer.collectAllMetrics()) -} - -/** - * Extract an [ComputeMetrics] object from the specified list of metric data. - */ -internal fun extractComputeMetrics(metrics: Collection): ComputeMetrics { - val res = ComputeMetrics() - for (metric in metrics) { - val points = metric.longSumData.points - - if (points.isEmpty()) { - continue - } - - val value = points.first().value.toInt() - when (metric.name) { - "servers.submitted" -> res.submittedVms = value - "servers.waiting" -> res.queuedVms = value - "servers.unscheduled" -> res.unscheduledVms = value - "servers.active" -> res.runningVms = value - "servers.finished" -> res.finishedVms = value - "hosts.total" -> res.hosts = value - "hosts.available" -> res.availableHosts = value - } - } - - return res -} - /** * Process the trace. */ @@ -255,7 +163,7 @@ suspend fun processTrace( reader: TraceReader, scheduler: ComputeService, chan: Channel, - monitor: ExperimentMonitor? = null, + monitor: ComputeMonitor? = null, ) { val client = scheduler.newClient() val image = client.newImage("vm-image") @@ -289,7 +197,7 @@ suspend fun processTrace( suspendCancellableCoroutine { cont -> server.watch(object : ServerWatcher { override fun onStateChanged(server: Server, newState: ServerState) { - monitor?.reportVmStateChange(clock.millis(), server, newState) + monitor?.onStateChange(clock.millis(), server, newState) if (newState == ServerState.TERMINATED) { cont.resume(Unit) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index ee832af8..d3bba182 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -29,11 +29,11 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.Channel import mu.KotlinLogging import org.opendc.experiments.capelin.env.ClusterEnvironmentReader +import org.opendc.experiments.capelin.export.parquet.ParquetExportMonitor import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload -import org.opendc.experiments.capelin.monitor.ParquetExperimentMonitor import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader @@ -41,6 +41,8 @@ import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.telemetry.compute.collectServiceMetrics +import org.opendc.telemetry.compute.withMonitor import java.io.File import java.io.FileInputStream import java.util.* @@ -127,7 +129,7 @@ abstract class Portfolio(name: String) : Experiment(name) { val trace = ParquetTraceReader(rawReaders, workload, seeder.nextInt()) - val monitor = ParquetExperimentMonitor( + val monitor = ParquetExportMonitor( File(config.getString("output-path")), "portfolio_id=$name/scenario_id=$id/run_id=$repeat", 4096 @@ -148,7 +150,7 @@ abstract class Portfolio(name: String) : Experiment(name) { null } - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, trace, @@ -159,9 +161,16 @@ abstract class Portfolio(name: String) : Experiment(name) { } failureDomain?.cancel() + monitor.close() } - val monitorResults = collectMetrics(meterProvider as MetricProducer) - logger.debug { "Finish SUBMIT=${monitorResults.submittedVms} FAIL=${monitorResults.unscheduledVms} QUEUE=${monitorResults.queuedVms} RUNNING=${monitorResults.runningVms}" } + val monitorResults = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + logger.debug { + "Finish " + + "SUBMIT=${monitorResults.instanceCount} " + + "FAIL=${monitorResults.failedInstanceCount} " + + "QUEUE=${monitorResults.queuedInstanceCount} " + + "RUNNING=${monitorResults.activeHostCount}" + } } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt new file mode 100644 index 00000000..c5cb80e2 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.export.parquet + +import mu.KotlinLogging +import org.apache.avro.Schema +import org.apache.avro.generic.GenericData +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetFileWriter +import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.trace.util.parquet.LocalOutputFile +import java.io.Closeable +import java.io.File +import java.util.concurrent.ArrayBlockingQueue +import java.util.concurrent.BlockingQueue +import kotlin.concurrent.thread + +/** + * A writer that writes data in Parquet format. + */ +public open class ParquetDataWriter( + private val path: File, + private val schema: Schema, + private val converter: (T, GenericData.Record) -> Unit, + private val bufferSize: Int = 4096 +) : Runnable, Closeable { + /** + * The logging instance to use. + */ + private val logger = KotlinLogging.logger {} + + /** + * The writer to write the Parquet file. + */ + private val writer = AvroParquetWriter.builder(LocalOutputFile(path)) + .withSchema(schema) + .withCompressionCodec(CompressionCodecName.SNAPPY) + .withPageSize(4 * 1024 * 1024) // For compression + .withRowGroupSize(16 * 1024 * 1024) // For write buffering (Page size) + .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) + .build() + + /** + * The queue of commands to process. + */ + private val queue: BlockingQueue = ArrayBlockingQueue(bufferSize) + + /** + * The thread that is responsible for writing the Parquet records. + */ + private val writerThread = thread(start = false, name = this.toString()) { run() } + + /** + * Write the specified metrics to the database. + */ + public fun write(event: T) { + queue.put(Action.Write(event)) + } + + /** + * Signal the writer to stop. + */ + public override fun close() { + queue.put(Action.Stop) + writerThread.join() + } + + init { + writerThread.start() + } + + /** + * Start the writer thread. + */ + override fun run() { + try { + loop@ while (true) { + val action = queue.take() + when (action) { + is Action.Stop -> break@loop + is Action.Write<*> -> { + val record = GenericData.Record(schema) + @Suppress("UNCHECKED_CAST") + converter(action.data as T, record) + writer.write(record) + } + } + } + } catch (e: Throwable) { + logger.error("Writer failed", e) + } finally { + writer.close() + } + } + + public sealed class Action { + /** + * A poison pill that will stop the writer thread. + */ + public object Stop : Action() + + /** + * Write the specified metrics to the database. + */ + public data class Write(val data: T) : Action() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt new file mode 100644 index 00000000..79b84e9d --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.export.parquet + +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServiceData +import java.io.File + +/** + * A [ComputeMonitor] that logs the events to a Parquet file. + */ +public class ParquetExportMonitor(base: File, partition: String, bufferSize: Int) : ComputeMonitor, AutoCloseable { + private val hostWriter = ParquetHostDataWriter( + File(base, "host/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + private val serviceWriter = ParquetServiceDataWriter( + File(base, "service/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + override fun record(data: HostData) { + hostWriter.write(data) + } + + override fun record(data: ServiceData) { + serviceWriter.write(data) + } + + override fun close() { + hostWriter.close() + serviceWriter.close() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt new file mode 100644 index 00000000..8912c12e --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.export.parquet + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericData +import org.opendc.telemetry.compute.table.HostData +import java.io.File + +/** + * A Parquet event writer for [HostData]s. + */ +public class ParquetHostDataWriter(path: File, bufferSize: Int) : + ParquetDataWriter(path, schema, convert, bufferSize) { + + override fun toString(): String = "host-writer" + + public companion object { + private val convert: (HostData, GenericData.Record) -> Unit = { data, record -> + record.put("host_id", data.host.name) + record.put("state", data.host.state.name) + record.put("timestamp", data.timestamp) + record.put("total_work", data.totalWork) + record.put("granted_work", data.grantedWork) + record.put("overcommitted_work", data.overcommittedWork) + record.put("interfered_work", data.interferedWork) + record.put("cpu_usage", data.cpuUsage) + record.put("cpu_demand", data.cpuDemand) + record.put("power_draw", data.powerDraw) + record.put("instance_count", data.instanceCount) + record.put("cores", data.host.model.cpuCount) + } + + private val schema: Schema = SchemaBuilder + .record("host") + .namespace("org.opendc.telemetry.compute") + .fields() + .name("timestamp").type().longType().noDefault() + .name("host_id").type().stringType().noDefault() + .name("state").type().stringType().noDefault() + .name("requested_work").type().longType().noDefault() + .name("granted_work").type().longType().noDefault() + .name("overcommitted_work").type().longType().noDefault() + .name("interfered_work").type().longType().noDefault() + .name("cpu_usage").type().doubleType().noDefault() + .name("cpu_demand").type().doubleType().noDefault() + .name("power_draw").type().doubleType().noDefault() + .name("instance_count").type().intType().noDefault() + .name("cores").type().intType().noDefault() + .endRecord() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt new file mode 100644 index 00000000..36d630f3 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.export.parquet + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericData +import org.opendc.telemetry.compute.table.ServiceData +import java.io.File + +/** + * A Parquet event writer for [ServiceData]s. + */ +public class ParquetServiceDataWriter(path: File, bufferSize: Int) : + ParquetDataWriter(path, schema, convert, bufferSize) { + + override fun toString(): String = "service-writer" + + public companion object { + private val convert: (ServiceData, GenericData.Record) -> Unit = { data, record -> + record.put("timestamp", data.timestamp) + record.put("host_total_count", data.hostCount) + record.put("host_available_count", data.activeHostCount) + record.put("instance_total_count", data.instanceCount) + record.put("instance_active_count", data.runningInstanceCount) + record.put("instance_inactive_count", data.finishedInstanceCount) + record.put("instance_waiting_count", data.queuedInstanceCount) + record.put("instance_failed_count", data.failedInstanceCount) + } + + private val schema: Schema = SchemaBuilder + .record("service") + .namespace("org.opendc.telemetry.compute") + .fields() + .name("timestamp").type().longType().noDefault() + .name("host_total_count").type().intType().noDefault() + .name("host_available_count").type().intType().noDefault() + .name("instance_total_count").type().intType().noDefault() + .name("instance_active_count").type().intType().noDefault() + .name("instance_inactive_count").type().intType().noDefault() + .name("instance_waiting_count").type().intType().noDefault() + .name("instance_failed_count").type().intType().noDefault() + .endRecord() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt deleted file mode 100644 index 79be9ac4..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.monitor - -import io.opentelemetry.sdk.common.CompletableResultCode -import io.opentelemetry.sdk.metrics.data.MetricData -import io.opentelemetry.sdk.metrics.export.MetricExporter -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes -import org.opendc.compute.service.driver.Host -import org.opendc.experiments.capelin.extractComputeMetrics -import java.time.Clock - -/** - * A [MetricExporter] that exports the metrics to the [ExperimentMonitor]. - */ -public class ExperimentMetricExporter( - private val monitor: ExperimentMonitor, - private val clock: Clock, - private val hosts: Map -) : MetricExporter { - - override fun export(metrics: Collection): CompletableResultCode { - return try { - reportHostMetrics(metrics) - reportProvisionerMetrics(metrics) - CompletableResultCode.ofSuccess() - } catch (e: Throwable) { - CompletableResultCode.ofFailure() - } - } - - private var lastHostMetrics: Map = emptyMap() - private val hostMetricsSingleton = HostMetrics() - - private fun reportHostMetrics(metrics: Collection) { - val hostMetrics = mutableMapOf() - - for (metric in metrics) { - when (metric.name) { - "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v } - "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v } - "power.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.powerDraw = v } - "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v } - "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v } - "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } - "cpu.work.interference" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.interferedWork = v } - "guests.active" -> mapLongSum(metric, hostMetrics) { m, v -> m.instanceCount = v.toInt() } - "host.time.up" -> mapLongSum(metric, hostMetrics) { m, v -> m.uptime = v } - "host.time.down" -> mapLongSum(metric, hostMetrics) { m, v -> m.downtime = v } - } - } - - for ((id, hostMetric) in hostMetrics) { - val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) - val host = hosts[id] ?: continue - - monitor.reportHostData( - clock.millis(), - hostMetric.totalWork - lastHostMetric.totalWork, - hostMetric.grantedWork - lastHostMetric.grantedWork, - hostMetric.overcommittedWork - lastHostMetric.overcommittedWork, - hostMetric.interferedWork - lastHostMetric.interferedWork, - hostMetric.cpuUsage, - hostMetric.cpuDemand, - hostMetric.powerDraw, - hostMetric.instanceCount, - hostMetric.uptime - lastHostMetric.uptime, - hostMetric.downtime - lastHostMetric.downtime, - host - ) - } - - lastHostMetrics = hostMetrics - } - - private fun mapDoubleSummary(data: MetricData, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { - val points = data.doubleSummaryData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HostMetrics() } - val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2 - block(hostMetric, avg) - } - } - - private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Long) -> Unit) { - val points = data?.longSumData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HostMetrics() } - block(hostMetric, point.value) - } - } - - private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { - val points = data?.doubleSumData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HostMetrics() } - block(hostMetric, point.value) - } - } - - private fun reportProvisionerMetrics(metrics: Collection) { - val res = extractComputeMetrics(metrics) - - monitor.reportServiceData( - clock.millis(), - res.hosts, - res.availableHosts, - res.submittedVms, - res.runningVms, - res.finishedVms, - res.queuedVms, - res.unscheduledVms - ) - } - - private class HostMetrics { - var totalWork: Double = 0.0 - var grantedWork: Double = 0.0 - var overcommittedWork: Double = 0.0 - var interferedWork: Double = 0.0 - var cpuUsage: Double = 0.0 - var cpuDemand: Double = 0.0 - var instanceCount: Int = 0 - var powerDraw: Double = 0.0 - var uptime: Long = 0 - var downtime: Long = 0 - } - - override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() - - override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt deleted file mode 100644 index dc28b816..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.monitor - -import org.opendc.compute.api.Server -import org.opendc.compute.api.ServerState -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostState - -/** - * A monitor watches the events of an experiment. - */ -public interface ExperimentMonitor : AutoCloseable { - /** - * This method is invoked when the state of a VM changes. - */ - public fun reportVmStateChange(time: Long, server: Server, newState: ServerState) {} - - /** - * This method is invoked when the state of a host changes. - */ - public fun reportHostStateChange(time: Long, host: Host, newState: HostState) {} - - /** - * This method is invoked for a host for each slice that is finishes. - */ - public fun reportHostData( - time: Long, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double, - powerDraw: Double, - instanceCount: Int, - uptime: Long, - downtime: Long, - host: Host - ) {} - - /** - * This method is invoked for reporting service data. - */ - public fun reportServiceData( - time: Long, - totalHostCount: Int, - availableHostCount: Int, - totalVmCount: Int, - activeVmCount: Int, - inactiveVmCount: Int, - waitingVmCount: Int, - failedVmCount: Int - ) {} -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt deleted file mode 100644 index c49499da..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.monitor - -import mu.KotlinLogging -import org.opendc.compute.api.Server -import org.opendc.compute.api.ServerState -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostState -import org.opendc.experiments.capelin.telemetry.HostEvent -import org.opendc.experiments.capelin.telemetry.ProvisionerEvent -import org.opendc.experiments.capelin.telemetry.parquet.ParquetHostEventWriter -import org.opendc.experiments.capelin.telemetry.parquet.ParquetProvisionerEventWriter -import java.io.File - -/** - * The logger instance to use. - */ -private val logger = KotlinLogging.logger {} - -/** - * An [ExperimentMonitor] that logs the events to a Parquet file. - */ -public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: Int) : ExperimentMonitor { - private val hostWriter = ParquetHostEventWriter( - File(base, "host-metrics/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - private val provisionerWriter = ParquetProvisionerEventWriter( - File(base, "provisioner-metrics/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - override fun reportVmStateChange(time: Long, server: Server, newState: ServerState) {} - - override fun reportHostStateChange(time: Long, host: Host, newState: HostState) { - logger.debug { "Host ${host.uid} changed state $newState [$time]" } - } - - override fun reportHostData( - time: Long, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double, - powerDraw: Double, - instanceCount: Int, - uptime: Long, - downtime: Long, - host: Host - ) { - hostWriter.write( - HostEvent( - time, - 5 * 60 * 1000L, - host, - instanceCount, - totalWork.toLong(), - grantedWork.toLong(), - overcommittedWork.toLong(), - interferedWork.toLong(), - cpuUsage, - cpuDemand, - powerDraw, - host.model.cpuCount - ) - ) - } - - override fun reportServiceData( - time: Long, - totalHostCount: Int, - availableHostCount: Int, - totalVmCount: Int, - activeVmCount: Int, - inactiveVmCount: Int, - waitingVmCount: Int, - failedVmCount: Int - ) { - provisionerWriter.write( - ProvisionerEvent( - time, - totalHostCount, - availableHostCount, - totalVmCount, - activeVmCount, - inactiveVmCount, - waitingVmCount, - failedVmCount - ) - ) - } - - override fun close() { - hostWriter.close() - provisionerWriter.close() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/Event.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/Event.kt deleted file mode 100644 index c29e116e..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/Event.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry - -/** - * An event that occurs within the system. - */ -public abstract class Event(public val name: String) { - /** - * The time of occurrence of this event. - */ - public abstract val timestamp: Long -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/HostEvent.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/HostEvent.kt deleted file mode 100644 index 899fc9b1..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/HostEvent.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry - -import org.opendc.compute.service.driver.Host - -/** - * A periodic report of the host machine metrics. - */ -public data class HostEvent( - override val timestamp: Long, - public val duration: Long, - public val host: Host, - public val vmCount: Int, - public val requestedBurst: Long, - public val grantedBurst: Long, - public val overcommissionedBurst: Long, - public val interferedBurst: Long, - public val cpuUsage: Double, - public val cpuDemand: Double, - public val powerDraw: Double, - public val cores: Int -) : Event("host-metrics") diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/ProvisionerEvent.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/ProvisionerEvent.kt deleted file mode 100644 index 539c9bc9..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/ProvisionerEvent.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry - -/** - * A periodic report of the provisioner's metrics. - */ -public data class ProvisionerEvent( - override val timestamp: Long, - public val totalHostCount: Int, - public val availableHostCount: Int, - public val totalVmCount: Int, - public val activeVmCount: Int, - public val inactiveVmCount: Int, - public val waitingVmCount: Int, - public val failedVmCount: Int -) : Event("provisioner-metrics") diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/RunEvent.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/RunEvent.kt deleted file mode 100644 index 6c8fc941..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/RunEvent.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry - -import org.opendc.experiments.capelin.Portfolio - -/** - * A periodic report of the host machine metrics. - */ -public data class RunEvent( - val portfolio: Portfolio, - val repeat: Int, - override val timestamp: Long -) : Event("run") diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/VmEvent.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/VmEvent.kt deleted file mode 100644 index 7631f55f..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/VmEvent.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry - -import org.opendc.compute.api.Server - -/** - * A periodic report of a virtual machine's metrics. - */ -public data class VmEvent( - override val timestamp: Long, - public val duration: Long, - public val vm: Server, - public val host: Server, - public val requestedBurst: Long, - public val grantedBurst: Long, - public val overcommissionedBurst: Long, - public val interferedBurst: Long, - public val cpuUsage: Double, - public val cpuDemand: Double -) : Event("vm-metrics") diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt deleted file mode 100644 index 897a6692..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetEventWriter.kt +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry.parquet - -import mu.KotlinLogging -import org.apache.avro.Schema -import org.apache.avro.generic.GenericData -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.experiments.capelin.telemetry.Event -import org.opendc.trace.util.parquet.LocalOutputFile -import java.io.Closeable -import java.io.File -import java.util.concurrent.ArrayBlockingQueue -import java.util.concurrent.BlockingQueue -import kotlin.concurrent.thread - -/** - * The logging instance to use. - */ -private val logger = KotlinLogging.logger {} - -/** - * A writer that writes events in Parquet format. - */ -public open class ParquetEventWriter( - private val path: File, - private val schema: Schema, - private val converter: (T, GenericData.Record) -> Unit, - private val bufferSize: Int = 4096 -) : Runnable, Closeable { - /** - * The writer to write the Parquet file. - */ - private val writer = AvroParquetWriter.builder(LocalOutputFile(path)) - .withSchema(schema) - .withCompressionCodec(CompressionCodecName.SNAPPY) - .withPageSize(4 * 1024 * 1024) // For compression - .withRowGroupSize(16 * 1024 * 1024) // For write buffering (Page size) - .build() - - /** - * The queue of commands to process. - */ - private val queue: BlockingQueue = ArrayBlockingQueue(bufferSize) - - /** - * The thread that is responsible for writing the Parquet records. - */ - private val writerThread = thread(start = false, name = "parquet-writer") { run() } - - /** - * Write the specified metrics to the database. - */ - public fun write(event: T) { - queue.put(Action.Write(event)) - } - - /** - * Signal the writer to stop. - */ - public override fun close() { - queue.put(Action.Stop) - writerThread.join() - } - - init { - writerThread.start() - } - - /** - * Start the writer thread. - */ - override fun run() { - try { - loop@ while (true) { - val action = queue.take() - when (action) { - is Action.Stop -> break@loop - is Action.Write<*> -> { - val record = GenericData.Record(schema) - @Suppress("UNCHECKED_CAST") - converter(action.event as T, record) - writer.write(record) - } - } - } - } catch (e: Throwable) { - logger.error("Writer failed", e) - } finally { - writer.close() - } - } - - public sealed class Action { - /** - * A poison pill that will stop the writer thread. - */ - public object Stop : Action() - - /** - * Write the specified metrics to the database. - */ - public data class Write(val event: T) : Action() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt deleted file mode 100644 index c8fe1cb2..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry.parquet - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData -import org.opendc.experiments.capelin.telemetry.HostEvent -import java.io.File - -/** - * A Parquet event writer for [HostEvent]s. - */ -public class ParquetHostEventWriter(path: File, bufferSize: Int) : - ParquetEventWriter(path, schema, convert, bufferSize) { - - override fun toString(): String = "host-writer" - - public companion object { - private val convert: (HostEvent, GenericData.Record) -> Unit = { event, record -> - // record.put("portfolio_id", event.run.parent.parent.id) - // record.put("scenario_id", event.run.parent.id) - // record.put("run_id", event.run.id) - record.put("host_id", event.host.name) - record.put("state", event.host.state.name) - record.put("timestamp", event.timestamp) - record.put("duration", event.duration) - record.put("vm_count", event.vmCount) - record.put("requested_burst", event.requestedBurst) - record.put("granted_burst", event.grantedBurst) - record.put("overcommissioned_burst", event.overcommissionedBurst) - record.put("interfered_burst", event.interferedBurst) - record.put("cpu_usage", event.cpuUsage) - record.put("cpu_demand", event.cpuDemand) - record.put("power_draw", event.powerDraw) - record.put("cores", event.cores) - } - - private val schema: Schema = SchemaBuilder - .record("host_metrics") - .namespace("org.opendc.experiments.sc20") - .fields() - // .name("portfolio_id").type().intType().noDefault() - // .name("scenario_id").type().intType().noDefault() - // .name("run_id").type().intType().noDefault() - .name("timestamp").type().longType().noDefault() - .name("duration").type().longType().noDefault() - .name("host_id").type().stringType().noDefault() - .name("state").type().stringType().noDefault() - .name("vm_count").type().intType().noDefault() - .name("requested_burst").type().longType().noDefault() - .name("granted_burst").type().longType().noDefault() - .name("overcommissioned_burst").type().longType().noDefault() - .name("interfered_burst").type().longType().noDefault() - .name("cpu_usage").type().doubleType().noDefault() - .name("cpu_demand").type().doubleType().noDefault() - .name("power_draw").type().doubleType().noDefault() - .name("cores").type().intType().noDefault() - .endRecord() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetProvisionerEventWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetProvisionerEventWriter.kt deleted file mode 100644 index 8feff8d9..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetProvisionerEventWriter.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry.parquet - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData -import org.opendc.experiments.capelin.telemetry.ProvisionerEvent -import java.io.File - -/** - * A Parquet event writer for [ProvisionerEvent]s. - */ -public class ParquetProvisionerEventWriter(path: File, bufferSize: Int) : - ParquetEventWriter(path, schema, convert, bufferSize) { - - override fun toString(): String = "provisioner-writer" - - public companion object { - private val convert: (ProvisionerEvent, GenericData.Record) -> Unit = { event, record -> - record.put("timestamp", event.timestamp) - record.put("host_total_count", event.totalHostCount) - record.put("host_available_count", event.availableHostCount) - record.put("vm_total_count", event.totalVmCount) - record.put("vm_active_count", event.activeVmCount) - record.put("vm_inactive_count", event.inactiveVmCount) - record.put("vm_waiting_count", event.waitingVmCount) - record.put("vm_failed_count", event.failedVmCount) - } - - private val schema: Schema = SchemaBuilder - .record("provisioner_metrics") - .namespace("org.opendc.experiments.sc20") - .fields() - .name("timestamp").type().longType().noDefault() - .name("host_total_count").type().intType().noDefault() - .name("host_available_count").type().intType().noDefault() - .name("vm_total_count").type().intType().noDefault() - .name("vm_active_count").type().intType().noDefault() - .name("vm_inactive_count").type().intType().noDefault() - .name("vm_waiting_count").type().intType().noDefault() - .name("vm_failed_count").type().intType().noDefault() - .endRecord() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetRunEventWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetRunEventWriter.kt deleted file mode 100644 index 946410eb..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetRunEventWriter.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.telemetry.parquet - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData -import org.opendc.experiments.capelin.telemetry.RunEvent -import java.io.File - -/** - * A Parquet event writer for [RunEvent]s. - */ -public class ParquetRunEventWriter(path: File, bufferSize: Int) : - ParquetEventWriter(path, schema, convert, bufferSize) { - - override fun toString(): String = "run-writer" - - public companion object { - private val convert: (RunEvent, GenericData.Record) -> Unit = { event, record -> - val portfolio = event.portfolio - record.put("portfolio_name", portfolio.name) - record.put("scenario_id", portfolio.id) - record.put("run_id", event.repeat) - record.put("topology", portfolio.topology.name) - record.put("workload_name", portfolio.workload.name) - record.put("workload_fraction", portfolio.workload.fraction) - record.put("workload_sampler", portfolio.workload.samplingStrategy) - record.put("allocation_policy", portfolio.allocationPolicy) - record.put("failure_frequency", portfolio.operationalPhenomena.failureFrequency) - record.put("interference", portfolio.operationalPhenomena.hasInterference) - record.put("seed", event.repeat) - } - - private val schema: Schema = SchemaBuilder - .record("runs") - .namespace("org.opendc.experiments.sc20") - .fields() - .name("portfolio_name").type().stringType().noDefault() - .name("scenario_id").type().intType().noDefault() - .name("run_id").type().intType().noDefault() - .name("topology").type().stringType().noDefault() - .name("workload_name").type().stringType().noDefault() - .name("workload_fraction").type().doubleType().noDefault() - .name("workload_sampler").type().stringType().noDefault() - .name("allocation_policy").type().stringType().noDefault() - .name("failure_frequency").type().doubleType().noDefault() - .name("interference").type().booleanType().noDefault() - .name("seed").type().intType().noDefault() - .endRecord() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 24d8f768..abd8efeb 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -29,7 +29,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll -import org.opendc.compute.service.driver.Host import org.opendc.compute.service.scheduler.FilterScheduler import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.filters.RamFilter @@ -38,7 +37,6 @@ import org.opendc.compute.service.scheduler.weights.CoreRamWeigher import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload -import org.opendc.experiments.capelin.monitor.ExperimentMonitor import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader @@ -46,6 +44,10 @@ import org.opendc.experiments.capelin.trace.TraceReader import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.collectServiceMetrics +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.withMonitor import java.io.File import java.util.* @@ -80,7 +82,6 @@ class CapelinIntegrationTest { ) val traceReader = createTestTraceReader() val environmentReader = createTestEnvironmentReader() - lateinit var monitorResults: ComputeMetrics val meterProvider = createMeterProvider(clock) withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> @@ -98,7 +99,7 @@ class CapelinIntegrationTest { null } - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, traceReader, @@ -111,15 +112,21 @@ class CapelinIntegrationTest { failureDomain?.cancel() } - monitorResults = collectMetrics(meterProvider as MetricProducer) - println("Finish SUBMIT=${monitorResults.submittedVms} FAIL=${monitorResults.unscheduledVms} QUEUE=${monitorResults.queuedVms} RUNNING=${monitorResults.runningVms}") + val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + println( + "Finish " + + "SUBMIT=${serviceMetrics.instanceCount} " + + "FAIL=${serviceMetrics.failedInstanceCount} " + + "QUEUE=${serviceMetrics.queuedInstanceCount} " + + "RUNNING=${serviceMetrics.runningInstanceCount}" + ) // Note that these values have been verified beforehand assertAll( - { assertEquals(50, monitorResults.submittedVms, "The trace contains 50 VMs") }, - { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, - { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, - { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, + { assertEquals(50, serviceMetrics.instanceCount, "The trace contains 50 VMs") }, + { assertEquals(0, serviceMetrics.runningInstanceCount, "All VMs should finish after a run") }, + { assertEquals(0, serviceMetrics.failedInstanceCount, "No VM should not be unscheduled") }, + { assertEquals(0, serviceMetrics.queuedInstanceCount, "No VM should not be in the queue") }, { assertEquals(220346369753, monitor.totalWork) { "Incorrect requested burst" } }, { assertEquals(206667809529, monitor.totalGrantedWork) { "Incorrect granted burst" } }, { assertEquals(1151611104, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, @@ -145,7 +152,7 @@ class CapelinIntegrationTest { val meterProvider = createMeterProvider(clock) withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, traceReader, @@ -156,8 +163,14 @@ class CapelinIntegrationTest { } } - val metrics = collectMetrics(meterProvider as MetricProducer) - println("Finish SUBMIT=${metrics.submittedVms} FAIL=${metrics.unscheduledVms} QUEUE=${metrics.queuedVms} RUNNING=${metrics.runningVms}") + val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + println( + "Finish " + + "SUBMIT=${serviceMetrics.instanceCount} " + + "FAIL=${serviceMetrics.failedInstanceCount} " + + "QUEUE=${serviceMetrics.queuedInstanceCount} " + + "RUNNING=${serviceMetrics.runningInstanceCount}" + ) // Note that these values have been verified beforehand assertAll( @@ -189,7 +202,7 @@ class CapelinIntegrationTest { val meterProvider = createMeterProvider(clock) withComputeService(clock, meterProvider, environmentReader, allocationPolicy, performanceInterferenceModel) { scheduler -> - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, traceReader, @@ -200,8 +213,14 @@ class CapelinIntegrationTest { } } - val metrics = collectMetrics(meterProvider as MetricProducer) - println("Finish SUBMIT=${metrics.submittedVms} FAIL=${metrics.unscheduledVms} QUEUE=${metrics.queuedVms} RUNNING=${metrics.runningVms}") + val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + println( + "Finish " + + "SUBMIT=${serviceMetrics.instanceCount} " + + "FAIL=${serviceMetrics.failedInstanceCount} " + + "QUEUE=${serviceMetrics.queuedInstanceCount} " + + "RUNNING=${serviceMetrics.runningInstanceCount}" + ) // Note that these values have been verified beforehand assertAll( @@ -239,7 +258,7 @@ class CapelinIntegrationTest { chan ) - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, traceReader, @@ -252,8 +271,14 @@ class CapelinIntegrationTest { failureDomain.cancel() } - val metrics = collectMetrics(meterProvider as MetricProducer) - println("Finish SUBMIT=${metrics.submittedVms} FAIL=${metrics.unscheduledVms} QUEUE=${metrics.queuedVms} RUNNING=${metrics.runningVms}") + val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + println( + "Finish " + + "SUBMIT=${serviceMetrics.instanceCount} " + + "FAIL=${serviceMetrics.failedInstanceCount} " + + "QUEUE=${serviceMetrics.queuedInstanceCount} " + + "RUNNING=${serviceMetrics.runningInstanceCount}" + ) // Note that these values have been verified beforehand assertAll( @@ -283,34 +308,19 @@ class CapelinIntegrationTest { return ClusterEnvironmentReader(stream) } - class TestExperimentReporter : ExperimentMonitor { + class TestExperimentReporter : ComputeMonitor { var totalWork = 0L var totalGrantedWork = 0L var totalOvercommittedWork = 0L var totalInterferedWork = 0L var totalPowerDraw = 0.0 - override fun reportHostData( - time: Long, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double, - powerDraw: Double, - instanceCount: Int, - uptime: Long, - downtime: Long, - host: Host, - ) { - this.totalWork += totalWork.toLong() - totalGrantedWork += grantedWork.toLong() - totalOvercommittedWork += overcommittedWork.toLong() - totalInterferedWork += interferedWork.toLong() - totalPowerDraw += powerDraw + override fun record(data: HostData) { + this.totalWork += data.totalWork.toLong() + totalGrantedWork += data.grantedWork.toLong() + totalOvercommittedWork += data.overcommittedWork.toLong() + totalInterferedWork += data.interferedWork.toLong() + totalPowerDraw += data.powerDraw } - - override fun close() {} } } diff --git a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts index 7d34d098..40ac2967 100644 --- a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcExperiments.opendcExperimentsCapelin) implementation(projects.opendcTelemetry.opendcTelemetrySdk) + implementation(projects.opendcTelemetry.opendcTelemetryCompute) implementation(libs.kotlin.logging) implementation(libs.config) diff --git a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt index e64e20a2..02aaab3c 100644 --- a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt +++ b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt @@ -37,7 +37,7 @@ import org.opendc.compute.service.scheduler.filters.RamFilter import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.* -import org.opendc.experiments.capelin.monitor.ParquetExperimentMonitor +import org.opendc.experiments.capelin.export.parquet.ParquetExportMonitor import org.opendc.experiments.capelin.trace.StreamingParquetTraceReader import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf @@ -50,6 +50,8 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.* import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.telemetry.compute.collectServiceMetrics +import org.opendc.telemetry.compute.withMonitor import java.io.File import java.time.Clock import java.util.* @@ -87,11 +89,11 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { ) val meterProvider: MeterProvider = createMeterProvider(clock) - val monitor = ParquetExperimentMonitor(File(config.getString("output-path")), "power_model=$powerModel/run_id=$repeat", 4096) + val monitor = ParquetExportMonitor(File(config.getString("output-path")), "power_model=$powerModel/run_id=$repeat", 4096) val trace = StreamingParquetTraceReader(File(config.getString("trace-path"), trace)) withComputeService(clock, meterProvider, allocationPolicy) { scheduler -> - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, trace, @@ -102,12 +104,12 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { } } - val monitorResults = collectMetrics(meterProvider as MetricProducer) + val monitorResults = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) logger.debug { - "Finish SUBMIT=${monitorResults.submittedVms} " + - "FAIL=${monitorResults.unscheduledVms} " + - "QUEUE=${monitorResults.queuedVms} " + - "RUNNING=${monitorResults.runningVms}" + "Finish SUBMIT=${monitorResults.instanceCount} " + + "FAIL=${monitorResults.failedInstanceCount} " + + "QUEUE=${monitorResults.queuedInstanceCount} " + + "RUNNING=${monitorResults.runningInstanceCount}" } } diff --git a/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts b/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts new file mode 100644 index 00000000..6a3de9bc --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Telemetry for OpenDC Compute" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTelemetry.opendcTelemetrySdk) + + implementation(projects.opendcCompute.opendcComputeSimulator) + implementation(libs.opentelemetry.semconv) + implementation(libs.kotlin.logging) +} diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt new file mode 100644 index 00000000..95e7ff9e --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute + +import io.opentelemetry.sdk.common.CompletableResultCode +import io.opentelemetry.sdk.metrics.data.MetricData +import io.opentelemetry.sdk.metrics.export.MetricExporter +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import org.opendc.compute.service.driver.Host +import org.opendc.telemetry.compute.table.HostData +import java.time.Clock + +/** + * A [MetricExporter] that redirects data to a [ComputeMonitor] implementation. + */ +public class ComputeMetricExporter( + private val clock: Clock, + private val hosts: Map, + private val monitor: ComputeMonitor +) : MetricExporter { + + override fun export(metrics: Collection): CompletableResultCode { + return try { + reportHostMetrics(metrics) + reportServiceMetrics(metrics) + CompletableResultCode.ofSuccess() + } catch (e: Throwable) { + CompletableResultCode.ofFailure() + } + } + + private var lastHostMetrics: Map = emptyMap() + private val hostMetricsSingleton = HBuffer() + + private fun reportHostMetrics(metrics: Collection) { + val hostMetrics = mutableMapOf() + + for (metric in metrics) { + when (metric.name) { + "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v } + "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v } + "power.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.powerDraw = v } + "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v } + "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v } + "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } + "cpu.work.interference" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.interferedWork = v } + "guests.active" -> mapLongSum(metric, hostMetrics) { m, v -> m.instanceCount = v.toInt() } + "host.time.up" -> mapLongSum(metric, hostMetrics) { m, v -> m.uptime = v } + "host.time.down" -> mapLongSum(metric, hostMetrics) { m, v -> m.downtime = v } + } + } + + for ((id, hostMetric) in hostMetrics) { + val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) + val host = hosts[id] ?: continue + + monitor.record( + HostData( + clock.millis(), + host, + hostMetric.totalWork - lastHostMetric.totalWork, + hostMetric.grantedWork - lastHostMetric.grantedWork, + hostMetric.overcommittedWork - lastHostMetric.overcommittedWork, + hostMetric.interferedWork - lastHostMetric.interferedWork, + hostMetric.cpuUsage, + hostMetric.cpuDemand, + hostMetric.instanceCount, + hostMetric.powerDraw, + hostMetric.uptime - lastHostMetric.uptime, + hostMetric.downtime - lastHostMetric.downtime, + ) + ) + } + + lastHostMetrics = hostMetrics + } + + private fun mapDoubleSummary(data: MetricData, hostMetrics: MutableMap, block: (HBuffer, Double) -> Unit) { + val points = data.doubleSummaryData?.points ?: emptyList() + for (point in points) { + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } + val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2 + block(hostMetric, avg) + } + } + + private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HBuffer, Long) -> Unit) { + val points = data?.longSumData?.points ?: emptyList() + for (point in points) { + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } + block(hostMetric, point.value) + } + } + + private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HBuffer, Double) -> Unit) { + val points = data?.doubleSumData?.points ?: emptyList() + for (point in points) { + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } + block(hostMetric, point.value) + } + } + + /** + * A buffer for host metrics before they are reported. + */ + private class HBuffer { + var totalWork: Double = 0.0 + var grantedWork: Double = 0.0 + var overcommittedWork: Double = 0.0 + var interferedWork: Double = 0.0 + var cpuUsage: Double = 0.0 + var cpuDemand: Double = 0.0 + var instanceCount: Int = 0 + var powerDraw: Double = 0.0 + var uptime: Long = 0 + var downtime: Long = 0 + } + + private fun reportServiceMetrics(metrics: Collection) { + monitor.record(extractServiceMetrics(clock.millis(), metrics)) + } + + override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() + + override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() +} diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt new file mode 100644 index 00000000..ec303b37 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute + +import org.opendc.compute.api.Server +import org.opendc.compute.api.ServerState +import org.opendc.compute.service.driver.Host +import org.opendc.compute.service.driver.HostState +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServerData +import org.opendc.telemetry.compute.table.ServiceData + +/** + * A monitor that tracks the metrics and events of the OpenDC Compute service. + */ +public interface ComputeMonitor { + /** + * This method is invoked when the state of a [Server] changes. + */ + public fun onStateChange(timestamp: Long, server: Server, newState: ServerState) {} + + /** + * This method is invoked when the state of a [Host] changes. + */ + public fun onStateChange(time: Long, host: Host, newState: HostState) {} + + /** + * Record the specified [data]. + */ + public fun record(data: ServerData) {} + + /** + * Record the specified [data]. + */ + public fun record(data: HostData) {} + + /** + * Record the specified [data]. + */ + public fun record(data: ServiceData) {} +} diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt new file mode 100644 index 00000000..d3d983b9 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute + +import io.opentelemetry.sdk.metrics.data.MetricData +import io.opentelemetry.sdk.metrics.export.MetricProducer +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope +import org.opendc.compute.service.ComputeService +import org.opendc.compute.service.driver.Host +import org.opendc.compute.service.driver.HostListener +import org.opendc.compute.service.driver.HostState +import org.opendc.telemetry.compute.table.ServiceData +import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader +import java.time.Clock + +/** + * Attach the specified monitor to the OpenDC Compute service. + */ +public suspend fun withMonitor( + scheduler: ComputeService, + clock: Clock, + metricProducer: MetricProducer, + monitor: ComputeMonitor, + exportInterval: Long = 5L * 60 * 1000, /* Every 5 min (which is the granularity of the workload trace) */ + block: suspend CoroutineScope.() -> Unit +): Unit = coroutineScope { + // Monitor host events + for (host in scheduler.hosts) { + monitor.onStateChange(clock.millis(), host, HostState.UP) + host.addListener(object : HostListener { + override fun onStateChanged(host: Host, newState: HostState) { + monitor.onStateChange(clock.millis(), host, newState) + } + }) + } + + val reader = CoroutineMetricReader( + this, + listOf(metricProducer), + ComputeMetricExporter(clock, scheduler.hosts.associateBy { it.uid.toString() }, monitor), + exportInterval + ) + + try { + block(this) + } finally { + reader.close() + } +} + +/** + * Collect the metrics of the compute service. + */ +public fun collectServiceMetrics(timestamp: Long, metricProducer: MetricProducer): ServiceData { + return extractServiceMetrics(timestamp, metricProducer.collectAllMetrics()) +} + +/** + * Extract a [ServiceData] object from the specified list of metric data. + */ +public fun extractServiceMetrics(timestamp: Long, metrics: Collection): ServiceData { + var submittedVms = 0 + var queuedVms = 0 + var unscheduledVms = 0 + var runningVms = 0 + var finishedVms = 0 + var hosts = 0 + var availableHosts = 0 + + for (metric in metrics) { + val points = metric.longSumData.points + + if (points.isEmpty()) { + continue + } + + val value = points.first().value.toInt() + when (metric.name) { + "servers.submitted" -> submittedVms = value + "servers.waiting" -> queuedVms = value + "servers.unscheduled" -> unscheduledVms = value + "servers.active" -> runningVms = value + "servers.finished" -> finishedVms = value + "hosts.total" -> hosts = value + "hosts.available" -> availableHosts = value + } + } + + return ServiceData(timestamp, hosts, availableHosts, submittedVms, runningVms, finishedVms, queuedVms, unscheduledVms) +} diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt new file mode 100644 index 00000000..8e6c34d0 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute.table + +import org.opendc.compute.service.driver.Host + +/** + * A trace entry for a particular host. + */ +public data class HostData( + public val timestamp: Long, + public val host: Host, + public val totalWork: Double, + public val grantedWork: Double, + public val overcommittedWork: Double, + public val interferedWork: Double, + public val cpuUsage: Double, + public val cpuDemand: Double, + public val instanceCount: Int, + public val powerDraw: Double, + public val uptime: Long, + public val downtime: Long, +) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt new file mode 100644 index 00000000..2a9fa8a6 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute.table + +import org.opendc.compute.api.Server + +/** + * A trace entry for a particular server. + */ +public data class ServerData( + public val timestamp: Long, + public val server: Server, + public val uptime: Long, + public val downtime: Long, +) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt new file mode 100644 index 00000000..f6ff5db5 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute.table + +/** + * A trace entry for the compute service. + */ +public data class ServiceData( + public val timestamp: Long, + public val hostCount: Int, + public val activeHostCount: Int, + public val instanceCount: Int, + public val runningInstanceCount: Int, + public val finishedInstanceCount: Int, + public val queuedInstanceCount: Int, + public val failedInstanceCount: Int +) diff --git a/opendc-web/opendc-web-runner/build.gradle.kts b/opendc-web/opendc-web-runner/build.gradle.kts index ec4a4673..99051e8e 100644 --- a/opendc-web/opendc-web-runner/build.gradle.kts +++ b/opendc-web/opendc-web-runner/build.gradle.kts @@ -39,6 +39,7 @@ dependencies { implementation(projects.opendcExperiments.opendcExperimentsCapelin) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcTelemetry.opendcTelemetrySdk) + implementation(projects.opendcTelemetry.opendcTelemetryCompute) implementation(libs.kotlin.logging) implementation(libs.clikt) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 53d50357..65527141 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -47,6 +47,8 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.LinearPowerModel import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.telemetry.compute.collectServiceMetrics +import org.opendc.telemetry.compute.withMonitor import org.opendc.telemetry.sdk.toOtelClock import org.opendc.web.client.ApiClient import org.opendc.web.client.AuthConfiguration @@ -131,7 +133,7 @@ class RunnerCli : CliktCommand(name = "runner") { /** * Run a single scenario. */ - private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, environment: EnvironmentReader): List { + private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, environment: EnvironmentReader): List { val id = scenario.id logger.info { "Constructing performance interference model" } @@ -176,8 +178,8 @@ class RunnerCli : CliktCommand(name = "runner") { environment: EnvironmentReader, traceReader: RawParquetTraceReader, interferenceModel: VmInterferenceModel? - ): WebExperimentMonitor.Result { - val monitor = WebExperimentMonitor() + ): WebComputeMonitor.Result { + val monitor = WebComputeMonitor() try { runBlockingSimulation { @@ -220,7 +222,7 @@ class RunnerCli : CliktCommand(name = "runner") { null } - withMonitor(monitor, clock, meterProvider as MetricProducer, scheduler) { + withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, trace, @@ -233,8 +235,14 @@ class RunnerCli : CliktCommand(name = "runner") { failureDomain?.cancel() } - val monitorResults = collectMetrics(metricProducer) - logger.debug { "Finish SUBMIT=${monitorResults.submittedVms} FAIL=${monitorResults.unscheduledVms} QUEUE=${monitorResults.queuedVms} RUNNING=${monitorResults.runningVms}" } + val monitorResults = collectServiceMetrics(clock.millis(), metricProducer) + logger.debug { + "Finish " + + "SUBMIT=${monitorResults.instanceCount} " + + "FAIL=${monitorResults.failedInstanceCount} " + + "QUEUE=${monitorResults.queuedInstanceCount} " + + "RUNNING=${monitorResults.runningInstanceCount}" + } } } catch (cause: Throwable) { logger.warn(cause) { "Experiment failed" } diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt index 4044cec9..e0e3488f 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt @@ -61,14 +61,14 @@ public class ScenarioManager(private val client: ApiClient) { /** * Persist the specified results. */ - public suspend fun finish(id: String, results: List) { + public suspend fun finish(id: String, results: List) { client.updateJob( id, SimulationState.FINISHED, mapOf( - "total_requested_burst" to results.map { it.totalRequestedBurst }, - "total_granted_burst" to results.map { it.totalGrantedBurst }, - "total_overcommitted_burst" to results.map { it.totalOvercommittedBurst }, - "total_interfered_burst" to results.map { it.totalInterferedBurst }, + "total_requested_burst" to results.map { it.totalWork }, + "total_granted_burst" to results.map { it.totalGrantedWork }, + "total_overcommitted_burst" to results.map { it.totalOvercommittedWork }, + "total_interfered_burst" to results.map { it.totalInterferedWork }, "mean_cpu_usage" to results.map { it.meanCpuUsage }, "mean_cpu_demand" to results.map { it.meanCpuDemand }, "mean_num_deployed_images" to results.map { it.meanNumDeployedImages }, diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt new file mode 100644 index 00000000..c8e58dde --- /dev/null +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.web.runner + +import mu.KotlinLogging +import org.opendc.compute.service.driver.Host +import org.opendc.compute.service.driver.HostState +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServiceData +import kotlin.math.max + +/** + * A [ComputeMonitor] that tracks the aggregate metrics for each repeat. + */ +public class WebComputeMonitor : ComputeMonitor { + private val logger = KotlinLogging.logger {} + + override fun onStateChange(time: Long, host: Host, newState: HostState) { + logger.debug { "Host ${host.uid} changed state $newState [$time]" } + } + + override fun record(data: HostData) { + val duration = 5 * 60 * 1000L + val slices = duration / SLICE_LENGTH + + hostAggregateMetrics = AggregateHostMetrics( + hostAggregateMetrics.totalWork + data.totalWork, + hostAggregateMetrics.totalGrantedWork + data.grantedWork, + hostAggregateMetrics.totalOvercommittedWork + data.overcommittedWork, + hostAggregateMetrics.totalInterferedWork + data.overcommittedWork, + hostAggregateMetrics.totalPowerDraw + (duration * data.powerDraw) / 3600, + hostAggregateMetrics.totalFailureSlices + if (data.host.state != HostState.UP) slices else 0, + hostAggregateMetrics.totalFailureVmSlices + if (data.host.state != HostState.UP) data.instanceCount * slices else 0 + ) + + hostMetrics.compute(data.host) { _, prev -> + HostMetrics( + (data.cpuUsage.takeIf { data.host.state == HostState.UP } ?: 0.0) + (prev?.cpuUsage ?: 0.0), + (data.cpuDemand.takeIf { data.host.state == HostState.UP } ?: 0.0) + (prev?.cpuDemand ?: 0.0), + data.instanceCount + (prev?.instanceCount ?: 0), + 1 + (prev?.count ?: 0) + ) + } + } + + private var hostAggregateMetrics: AggregateHostMetrics = AggregateHostMetrics() + private val hostMetrics: MutableMap = mutableMapOf() + private val SLICE_LENGTH: Long = 5 * 60 * 1000 + + data class AggregateHostMetrics( + val totalWork: Double = 0.0, + val totalGrantedWork: Double = 0.0, + val totalOvercommittedWork: Double = 0.0, + val totalInterferedWork: Double = 0.0, + val totalPowerDraw: Double = 0.0, + val totalFailureSlices: Long = 0, + val totalFailureVmSlices: Long = 0, + ) + + data class HostMetrics( + val cpuUsage: Double, + val cpuDemand: Double, + val instanceCount: Long, + val count: Long + ) + + private var serviceMetrics: AggregateServiceMetrics = AggregateServiceMetrics() + + override fun record(data: ServiceData) { + serviceMetrics = AggregateServiceMetrics( + max(data.instanceCount, serviceMetrics.vmTotalCount), + max(data.queuedInstanceCount, serviceMetrics.vmWaitingCount), + max(data.runningInstanceCount, serviceMetrics.vmActiveCount), + max(data.finishedInstanceCount, serviceMetrics.vmInactiveCount), + max(data.failedInstanceCount, serviceMetrics.vmFailedCount), + ) + } + + public data class AggregateServiceMetrics( + val vmTotalCount: Int = 0, + val vmWaitingCount: Int = 0, + val vmActiveCount: Int = 0, + val vmInactiveCount: Int = 0, + val vmFailedCount: Int = 0 + ) + + public fun getResult(): Result { + return Result( + hostAggregateMetrics.totalWork, + hostAggregateMetrics.totalGrantedWork, + hostAggregateMetrics.totalOvercommittedWork, + hostAggregateMetrics.totalInterferedWork, + hostMetrics.map { it.value.cpuUsage / it.value.count }.average(), + hostMetrics.map { it.value.cpuDemand / it.value.count }.average(), + hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.average(), + hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.maxOrNull() ?: 0.0, + hostAggregateMetrics.totalPowerDraw, + hostAggregateMetrics.totalFailureSlices, + hostAggregateMetrics.totalFailureVmSlices, + serviceMetrics.vmTotalCount, + serviceMetrics.vmWaitingCount, + serviceMetrics.vmInactiveCount, + serviceMetrics.vmFailedCount, + ) + } + + data class Result( + val totalWork: Double, + val totalGrantedWork: Double, + val totalOvercommittedWork: Double, + val totalInterferedWork: Double, + val meanCpuUsage: Double, + val meanCpuDemand: Double, + val meanNumDeployedImages: Double, + val maxNumDeployedImages: Double, + val totalPowerDraw: Double, + val totalFailureSlices: Long, + val totalFailureVmSlices: Long, + val totalVmsSubmitted: Int, + val totalVmsQueued: Int, + val totalVmsFinished: Int, + val totalVmsFailed: Int + ) +} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt deleted file mode 100644 index 281c8dbb..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebExperimentMonitor.kt +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.runner - -import mu.KotlinLogging -import org.opendc.compute.api.Server -import org.opendc.compute.api.ServerState -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostState -import org.opendc.experiments.capelin.monitor.ExperimentMonitor -import org.opendc.experiments.capelin.telemetry.HostEvent -import kotlin.math.max - -/** - * An [ExperimentMonitor] that tracks the aggregate metrics for each repeat. - */ -public class WebExperimentMonitor : ExperimentMonitor { - private val logger = KotlinLogging.logger {} - - override fun reportVmStateChange(time: Long, server: Server, newState: ServerState) {} - - override fun reportHostStateChange(time: Long, host: Host, newState: HostState) { - logger.debug { "Host ${host.uid} changed state $newState [$time]" } - } - - override fun reportHostData( - time: Long, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double, - powerDraw: Double, - instanceCount: Int, - uptime: Long, - downtime: Long, - host: Host, - ) { - processHostEvent( - HostEvent( - time, - 5 * 60 * 1000L, - host, - instanceCount, - totalWork.toLong(), - grantedWork.toLong(), - overcommittedWork.toLong(), - interferedWork.toLong(), - cpuUsage, - cpuDemand, - powerDraw, - host.model.cpuCount - ) - ) - } - - private var hostAggregateMetrics: AggregateHostMetrics = AggregateHostMetrics() - private val hostMetrics: MutableMap = mutableMapOf() - - private fun processHostEvent(event: HostEvent) { - val slices = event.duration / SLICE_LENGTH - - hostAggregateMetrics = AggregateHostMetrics( - hostAggregateMetrics.totalRequestedBurst + event.requestedBurst, - hostAggregateMetrics.totalGrantedBurst + event.grantedBurst, - hostAggregateMetrics.totalOvercommittedBurst + event.overcommissionedBurst, - hostAggregateMetrics.totalInterferedBurst + event.interferedBurst, - hostAggregateMetrics.totalPowerDraw + (event.duration * event.powerDraw) / 3600, - hostAggregateMetrics.totalFailureSlices + if (event.host.state != HostState.UP) slices else 0, - hostAggregateMetrics.totalFailureVmSlices + if (event.host.state != HostState.UP) event.vmCount * slices else 0 - ) - - hostMetrics.compute(event.host) { _, prev -> - HostMetrics( - (event.cpuUsage.takeIf { event.host.state == HostState.UP } ?: 0.0) + (prev?.cpuUsage ?: 0.0), - (event.cpuDemand.takeIf { event.host.state == HostState.UP } ?: 0.0) + (prev?.cpuDemand ?: 0.0), - event.vmCount + (prev?.vmCount ?: 0), - 1 + (prev?.count ?: 0) - ) - } - } - - private val SLICE_LENGTH: Long = 5 * 60 * 1000 - - public data class AggregateHostMetrics( - val totalRequestedBurst: Long = 0, - val totalGrantedBurst: Long = 0, - val totalOvercommittedBurst: Long = 0, - val totalInterferedBurst: Long = 0, - val totalPowerDraw: Double = 0.0, - val totalFailureSlices: Long = 0, - val totalFailureVmSlices: Long = 0, - ) - - public data class HostMetrics( - val cpuUsage: Double, - val cpuDemand: Double, - val vmCount: Long, - val count: Long - ) - - private var provisionerMetrics: AggregateProvisionerMetrics = AggregateProvisionerMetrics() - - override fun reportServiceData( - time: Long, - totalHostCount: Int, - availableHostCount: Int, - totalVmCount: Int, - activeVmCount: Int, - inactiveVmCount: Int, - waitingVmCount: Int, - failedVmCount: Int - ) { - provisionerMetrics = AggregateProvisionerMetrics( - max(totalVmCount, provisionerMetrics.vmTotalCount), - max(waitingVmCount, provisionerMetrics.vmWaitingCount), - max(activeVmCount, provisionerMetrics.vmActiveCount), - max(inactiveVmCount, provisionerMetrics.vmInactiveCount), - max(failedVmCount, provisionerMetrics.vmFailedCount), - ) - } - - public data class AggregateProvisionerMetrics( - val vmTotalCount: Int = 0, - val vmWaitingCount: Int = 0, - val vmActiveCount: Int = 0, - val vmInactiveCount: Int = 0, - val vmFailedCount: Int = 0 - ) - - override fun close() {} - - public fun getResult(): Result { - return Result( - hostAggregateMetrics.totalRequestedBurst, - hostAggregateMetrics.totalGrantedBurst, - hostAggregateMetrics.totalOvercommittedBurst, - hostAggregateMetrics.totalInterferedBurst, - hostMetrics.map { it.value.cpuUsage / it.value.count }.average(), - hostMetrics.map { it.value.cpuDemand / it.value.count }.average(), - hostMetrics.map { it.value.vmCount.toDouble() / it.value.count }.average(), - hostMetrics.map { it.value.vmCount.toDouble() / it.value.count }.maxOrNull() ?: 0.0, - hostAggregateMetrics.totalPowerDraw, - hostAggregateMetrics.totalFailureSlices, - hostAggregateMetrics.totalFailureVmSlices, - provisionerMetrics.vmTotalCount, - provisionerMetrics.vmWaitingCount, - provisionerMetrics.vmInactiveCount, - provisionerMetrics.vmFailedCount, - ) - } - - public data class Result( - public val totalRequestedBurst: Long, - public val totalGrantedBurst: Long, - public val totalOvercommittedBurst: Long, - public val totalInterferedBurst: Long, - public val meanCpuUsage: Double, - public val meanCpuDemand: Double, - public val meanNumDeployedImages: Double, - public val maxNumDeployedImages: Double, - public val totalPowerDraw: Double, - public val totalFailureSlices: Long, - public val totalFailureVmSlices: Long, - public val totalVmsSubmitted: Int, - public val totalVmsQueued: Int, - public val totalVmsFinished: Int, - public val totalVmsFailed: Int - ) -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 5cae0a31..cee8887b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,6 +45,7 @@ include(":opendc-simulator:opendc-simulator-compute") include(":opendc-simulator:opendc-simulator-failures") include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") +include(":opendc-telemetry:opendc-telemetry-compute") include(":opendc-trace:opendc-trace-api") include(":opendc-trace:opendc-trace-gwf") include(":opendc-trace:opendc-trace-swf") -- cgit v1.2.3 From 05aeb87093903df3fa00e05353a5f135293fca7e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 2 Sep 2021 13:34:35 +0200 Subject: build(web): Resolve kotlin-reflect incompatibility This change addresses an incompatibility issue with the kotlin-reflect transitive dependency in the opendc-web-runner module. --- opendc-web/opendc-web-runner/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/opendc-web/opendc-web-runner/build.gradle.kts b/opendc-web/opendc-web-runner/build.gradle.kts index 99051e8e..bfbb1687 100644 --- a/opendc-web/opendc-web-runner/build.gradle.kts +++ b/opendc-web/opendc-web-runner/build.gradle.kts @@ -48,6 +48,7 @@ dependencies { implementation(libs.ktor.client.auth) implementation(libs.ktor.client.jackson) implementation(libs.jackson.datatype.jsr310) + implementation(kotlin("reflect")) runtimeOnly(libs.log4j.slf4j) -- cgit v1.2.3 From 18ff316a6b6ab984ebf8283ea48ed98ec69d8295 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 2 Sep 2021 13:20:05 +0200 Subject: refactor(capelin): Restructure input reading classes --- .../opendc-experiments-capelin/build.gradle.kts | 5 ++--- .../org/opendc/experiments/capelin/Portfolio.kt | 5 +++-- .../capelin/trace/PerformanceInterferenceReader.kt | 21 ++++++++------------- .../capelin/trace/StreamingParquetTraceReader.kt | 4 ++-- .../experiments/capelin/trace/VmPlacementReader.kt | 19 +++++++------------ .../capelin/trace/sv/SvResourceStateTable.kt | 6 +++--- .../capelin/trace/sv/SvResourceStateTableReader.kt | 4 ++-- .../experiments/capelin/CapelinIntegrationTest.kt | 4 +++- .../trace/PerformanceInterferenceReaderTest.kt | 4 +--- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 3 +-- 10 files changed, 32 insertions(+), 43 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 1a4caf91..b2330af0 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -45,9 +45,8 @@ dependencies { implementation(libs.config) implementation(libs.progressbar) implementation(libs.clikt) - implementation(libs.jackson.module.kotlin) { - exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect") - } + implementation(libs.jackson.module.kotlin) + implementation(kotlin("reflect")) implementation(libs.parquet) testImplementation(libs.log4j.slf4j) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index d3bba182..4db04591 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -122,8 +122,9 @@ abstract class Portfolio(name: String) : Experiment(name) { } val performanceInterferenceModel = if (operationalPhenomena.hasInterference) - PerformanceInterferenceReader(FileInputStream(config.getString("interference-model"))) - .use { VmInterferenceModel(it.read(), Random(seeder.nextLong())) } + PerformanceInterferenceReader() + .read(FileInputStream(config.getString("interference-model"))) + .let { VmInterferenceModel(it, Random(seeder.nextLong())) } else null diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt index a19f5699..9549af42 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt @@ -31,14 +31,13 @@ import java.io.InputStream /** * A parser for the JSON performance interference setup files used for the TPDS article on Capelin. - * - * @param input The input stream to read from. - * @param mapper The Jackson object mapper to use. */ -class PerformanceInterferenceReader( - private val input: InputStream, - private val mapper: ObjectMapper = jacksonObjectMapper() -) : AutoCloseable { +class PerformanceInterferenceReader { + /** + * The [ObjectMapper] to use. + */ + private val mapper = jacksonObjectMapper() + init { mapper.addMixIn(VmInterferenceGroup::class.java, GroupMixin::class.java) } @@ -46,12 +45,8 @@ class PerformanceInterferenceReader( /** * Read the performance interface model from the input. */ - fun read(): List { - return mapper.readValue(input) - } - - override fun close() { - input.close() + fun read(input: InputStream): List { + return input.use { mapper.readValue(input) } } private data class GroupMixin( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt index 61e4cab5..ed82217d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt @@ -41,8 +41,6 @@ import java.util.UUID import java.util.concurrent.ArrayBlockingQueue import kotlin.concurrent.thread -private val logger = KotlinLogging.logger {} - /** * A [TraceReader] for the internal VM workload trace format that streams workloads on the fly. * @@ -50,6 +48,8 @@ private val logger = KotlinLogging.logger {} * @param selectedVms The list of VMs to read from the trace. */ class StreamingParquetTraceReader(traceFile: File, selectedVms: List = emptyList()) : TraceReader { + private val logger = KotlinLogging.logger {} + /** * The internal iterator to use for this reader. */ diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt index 7a1683f0..b55bd577 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt @@ -29,24 +29,19 @@ import java.io.InputStream /** * A parser for the JSON VM placement data files used for the TPDS article on Capelin. - * - * @param input The input stream to read from. - * @param mapper The Jackson object mapper to use. */ -public class VmPlacementReader( - private val input: InputStream, - private val mapper: ObjectMapper = jacksonObjectMapper() -) : AutoCloseable { +class VmPlacementReader { + /** + * The [ObjectMapper] to parse the placement. + */ + private val mapper = jacksonObjectMapper() + /** * Read the VM placements from the input. */ - public fun read(): Map { + fun read(input: InputStream): Map { return mapper.readValue>(input) .mapKeys { "vm__workload__${it.key}.txt" } .mapValues { it.value.split("/")[1] } // Clusters have format XX0 / X00 } - - override fun close() { - input.close() - } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt index 71c9d52e..24abb109 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt @@ -118,9 +118,9 @@ internal class SvResourceStateTable(path: Path) : Table { private fun nextDelegate(): TableReader? { return if (it.hasNext()) { - val (partition, path) = it.next() + val (_, path) = it.next() val reader = path.bufferedReader() - return SvResourceStateTableReader(partition, reader) + return SvResourceStateTableReader(reader) } else { null } @@ -133,7 +133,7 @@ internal class SvResourceStateTable(path: Path) : Table { override fun newReader(partition: String): TableReader { val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } val reader = path.bufferedReader() - return SvResourceStateTableReader(partition, reader) + return SvResourceStateTableReader(reader) } override fun toString(): String = "SvResourceStateTable" diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt index adcdb2ea..1a556f8d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt @@ -29,7 +29,7 @@ import java.time.Instant /** * A [TableReader] for the Bitbrains resource state table. */ -internal class SvResourceStateTableReader(partition: String, private val reader: BufferedReader) : TableReader { +internal class SvResourceStateTableReader(private val reader: BufferedReader) : TableReader { /** * The current parser state. */ @@ -57,7 +57,7 @@ internal class SvResourceStateTableReader(partition: String, private val reader: val length = line.length var col = 0 - var start = 0 + var start: Int var end = 0 while (end < length) { diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index abd8efeb..aed9a4bb 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -197,7 +197,9 @@ class CapelinIntegrationTest { val perfInterferenceInput = checkNotNull(CapelinIntegrationTest::class.java.getResourceAsStream("/bitbrains-perf-interference.json")) val performanceInterferenceModel = - PerformanceInterferenceReader(perfInterferenceInput).use { VmInterferenceModel(it.read(), Random(seed.toLong())) } + PerformanceInterferenceReader() + .read(perfInterferenceInput) + .let { VmInterferenceModel(it, Random(seed.toLong())) } val meterProvider = createMeterProvider(clock) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt index 9b1513dc..fbc39b87 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt @@ -33,9 +33,7 @@ class PerformanceInterferenceReaderTest { @Test fun testSmoke() { val input = checkNotNull(PerformanceInterferenceReader::class.java.getResourceAsStream("/perf-interference.json")) - val reader = PerformanceInterferenceReader(input) - - val result = reader.use { reader.read() } + val result = PerformanceInterferenceReader().read(input) assertAll( { assertEquals(2, result.size) }, diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 65527141..5d481270 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -32,7 +32,6 @@ import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import mu.KotlinLogging -import org.opendc.compute.service.scheduler.weights.* import org.opendc.experiments.capelin.* import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.env.MachineDef @@ -152,7 +151,7 @@ class RunnerCli : CliktCommand(name = "runner") { return@let null } - PerformanceInterferenceReader(path.inputStream()).use { reader -> reader.read() } + PerformanceInterferenceReader().read(path.inputStream()) } val targets = portfolio.targets -- cgit v1.2.3 From 8cd5ea777450dae6a86bde23dce1579016783749 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 7 Sep 2021 18:08:18 +0200 Subject: build(ui): Update dependencies This change updates the dependencies of the OpenDC frontend module. --- opendc-web/opendc-web-ui/package.json | 48 +- opendc-web/opendc-web-ui/yarn.lock | 2279 +++++++++++++++++---------------- 2 files changed, 1220 insertions(+), 1107 deletions(-) diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index 8d941e88..427e3cbd 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -17,47 +17,47 @@ "license": "MIT", "private": true, "dependencies": { - "@auth0/auth0-react": "^1.5.0", + "@auth0/auth0-react": "^1.7.0", "@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/free-brands-svg-icons": "^5.15.3", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.14", - "@patternfly/react-core": "^4.135.7", - "@patternfly/react-icons": "^4.11.2", - "@patternfly/react-table": "^4.29.8", + "@patternfly/react-core": "^4.152.4", + "@patternfly/react-icons": "^4.11.14", + "@patternfly/react-table": "^4.29.58", "@sentry/react": "^5.30.0", "@sentry/tracing": "^5.30.0", - "approximate-number": "~2.0.0", - "classnames": "~2.2.5", - "husky": "~4.2.5", + "approximate-number": "^2.1.0", + "classnames": "^2.3.1", + "husky": "^4.3.8", "immer": "^9.0.6", - "konva": "~7.2.5", - "lint-staged": "~10.2.2", - "mathjs": "~7.6.0", - "next": "^11.1.1", + "konva": "^7.2.5", + "lint-staged": "^10.5.4", + "mathjs": "^7.6.0", + "next": "^11.1.2", "next-transpile-modules": "^8.0.0", "normalizr": "^3.6.1", - "prettier": "~2.0.5", - "prop-types": "~15.7.2", + "prettier": "^2.3.2", + "prop-types": "^15.7.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-hotkeys": "^2.0.0", - "react-konva": "~17.0.2-0", - "react-query": "^3.18.1", - "react-redux": "~7.2.0", - "recharts": "~2.0.9", - "redux": "~4.0.5", + "react-konva": "^17.0.2-5", + "react-query": "^3.22.0", + "react-redux": "^7.2.5", + "recharts": "^2.1.2", + "redux": "^4.1.1", "redux-logger": "~3.0.6", "redux-saga": "~1.1.3", "redux-thunk": "~2.3.0", - "sass": "^1.32.12", - "svgsaver": "~0.9.0", - "use-resize-observer": "^7.0.0", - "uuidv4": "~6.1.1" + "sass": "^1.39.0", + "svgsaver": "^0.9.0", + "use-resize-observer": "^8.0.0", + "uuidv4": "^6.2.12" }, "devDependencies": { - "eslint": "^7.27.0", - "eslint-config-next": "^10.2.3" + "eslint": "^7.32.0", + "eslint-config-next": "^11.1.2" }, "lint-staged": { "src/**/*.{js,jsx,json}": [ diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index bdd6cdd6..704213f0 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -2,21 +2,21 @@ # yarn lockfile v1 -"@auth0/auth0-react@^1.5.0": - version "1.5.0" - resolved "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-1.5.0.tgz" - integrity sha512-LFJUd3V6aKCKxblJvrz3JIHzyBCz2X3ax5RdSjxZwGr5XxPwdhogeBWcyijnuB8moKD2ncl56OpOslbVGLIJ/w== +"@auth0/auth0-react@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@auth0/auth0-react/-/auth0-react-1.7.0.tgz#0fbfaf69b7ce5b50fcd82fb087a5fc6fc314e91e" + integrity sha512-D0JVqt8kvB8t+KkYAVyfTXxkMx0bJBTPNiQKWbiSwy9rm1PNVKgbS1/ABpf6DNbPeSdpOzVOQp0NVw5s6JivXw== dependencies: - "@auth0/auth0-spa-js" "^1.15.0" + "@auth0/auth0-spa-js" "^1.17.1" -"@auth0/auth0-spa-js@^1.15.0": - version "1.15.0" - resolved "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-1.15.0.tgz" - integrity sha512-d/crchAbhncl9irIMuw1zNSZgX+id0U7mzASQr2htMJ73JCYaAvBSdGXL0WcYS4yBm1Xsx1JYm3b5tEZ5p/ncg== +"@auth0/auth0-spa-js@^1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@auth0/auth0-spa-js/-/auth0-spa-js-1.17.1.tgz#038f356019d1a0a7a48c694f95cf3cca69082317" + integrity sha512-1XfySBfqZnqrWeaCROZ2IMLD+8rQ9TlfttLv0utS91d4rjIKX1g/zTcLYqP68QnqKKGHaMOIee/eQJLnk/o+ow== dependencies: - abortcontroller-polyfill "^1.7.1" - browser-tabs-lock "^1.2.13" - core-js "^3.11.0" + abortcontroller-polyfill "^1.7.3" + browser-tabs-lock "^1.2.14" + core-js "^3.16.1" es-cookie "^1.3.2" fast-text-encoding "^1.0.3" promise-polyfill "^8.2.0" @@ -24,39 +24,34 @@ "@babel/code-frame@7.12.11": version "7.12.11" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" "@babel/code-frame@^7.0.0": - version "7.12.13" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" + integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== dependencies: - "@babel/highlight" "^7.12.13" + "@babel/highlight" "^7.14.5" "@babel/helper-plugin-utils@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-validator-identifier@^7.14.0": - version "7.14.0" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz" - integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== - -"@babel/helper-validator-identifier@^7.14.9": +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": version "7.14.9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== -"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": - version "7.14.0" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz" - integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== dependencies: - "@babel/helper-validator-identifier" "^7.14.0" + "@babel/helper-validator-identifier" "^7.14.5" chalk "^2.0.0" js-tokens "^4.0.0" @@ -67,13 +62,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/runtime@7.15.3", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.9.2": +"@babel/runtime-corejs3@^7.10.2": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz#403139af262b9a6e8f9ba04a6fdcebf8de692bf1" + integrity sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg== + dependencies: + core-js-pure "^3.16.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@7.15.3": version "7.15.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b" integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.9.2": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" + integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/types@7.15.0": version "7.15.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" @@ -82,98 +92,119 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" -"@eslint/eslintrc@^0.4.1": - version "0.4.1" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz" - integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== dependencies: ajv "^6.12.4" debug "^4.1.1" espree "^7.3.0" - globals "^12.1.0" + globals "^13.9.0" ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@fortawesome/fontawesome-common-types@^0.2.35": - version "0.2.35" - resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz" - integrity sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw== +"@fortawesome/fontawesome-common-types@^0.2.36": + version "0.2.36" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz#b44e52db3b6b20523e0c57ef8c42d315532cb903" + integrity sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg== "@fortawesome/fontawesome-svg-core@^1.2.35": - version "1.2.35" - resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz" - integrity sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg== + version "1.2.36" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz#4f2ea6f778298e0c47c6524ce2e7fd58eb6930e3" + integrity sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA== dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.35" + "@fortawesome/fontawesome-common-types" "^0.2.36" "@fortawesome/free-brands-svg-icons@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz" - integrity sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw== + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.4.tgz#ec8a44dd383bcdd58aa7d1c96f38251e6fec9733" + integrity sha512-f1witbwycL9cTENJegcmcZRYyawAFbm8+c6IirLmwbbpqz46wyjbQYLuxOc7weXFXfB7QR8/Vd2u5R3q6JYD9g== dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.35" + "@fortawesome/fontawesome-common-types" "^0.2.36" "@fortawesome/free-solid-svg-icons@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz" - integrity sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q== + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz#2a68f3fc3ddda12e52645654142b9e4e8fbb6cc5" + integrity sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w== dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.35" + "@fortawesome/fontawesome-common-types" "^0.2.36" "@fortawesome/react-fontawesome@^0.1.14": - version "0.1.14" - resolved "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz" - integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA== + version "0.1.15" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.15.tgz#1450b838f905981d721bf07e14e3b52c0e9a91ed" + integrity sha512-/HFHdcoLESxxMkqZAcZ6RXDJ69pVApwdwRos/B2kiMWxDSAX2dFK8Er2/+rG+RsrzWB/dsAyjefLmemgmfE18g== dependencies: prop-types "^15.7.2" "@hapi/accept@5.0.2": version "5.0.2" - resolved "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.2.tgz" + resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.2.tgz#ab7043b037e68b722f93f376afb05e85c0699523" integrity sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw== dependencies: "@hapi/boom" "9.x.x" "@hapi/hoek" "9.x.x" "@hapi/boom@9.x.x": - version "9.1.2" - resolved "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.2.tgz" - integrity sha512-uJEJtiNHzKw80JpngDGBCGAmWjBtzxDCz17A9NO2zCi8LLBlb5Frpq4pXwyN+2JQMod4pKz5BALwyneCgDg89Q== + version "9.1.4" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.4.tgz#1f9dad367c6a7da9f8def24b4a986fc5a7bd9db6" + integrity sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw== dependencies: "@hapi/hoek" "9.x.x" "@hapi/hoek@9.x.x": version "9.2.0" - resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +"@juggle/resize-observer@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.3.1.tgz#b50a781709c81e10701004214340f25475a171a0" + integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw== + "@napi-rs/triples@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c" integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA== -"@next/env@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.1.tgz#d403282accbe8795aa2341f0e02c2e8bfc92bfb0" - integrity sha512-UEAzlfKofotLmj9LIgNixAfXpRck9rt/1CU9Q4ZtNDueGBJQP3HUzPHlrLChltWY2TA5MOzDQGL82H0a3+i5Ag== +"@next/env@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.2.tgz#27996efbbc54c5f949f5e8c0a156e3aa48369b99" + integrity sha512-+fteyVdQ7C/OoulfcF6vd1Yk0FEli4453gr8kSFbU8sKseNSizYq6df5MKz/AjwLptsxrUeIkgBdAzbziyJ3mA== -"@next/eslint-plugin-next@10.2.3": - version "10.2.3" - resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-10.2.3.tgz" - integrity sha512-XkYm3cMxY2RZgbGyZLDN3vR9StFyiQVdwdS/EL6NxOerzt0To03/coY22p4jcFLtLYlQxAivJRicMTDNhRzPog== +"@next/eslint-plugin-next@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-11.1.2.tgz#f26cf90bcb6cd2e4645e2ba253bbc9aaaa43a170" + integrity sha512-cN+ojHRsufr9Yz0rtvjv8WI5En0RPZRJnt0y16Ha7DD+0n473evz8i1ETEJHmOLeR7iPJR0zxRrxeTN/bJMOjg== + dependencies: + glob "7.1.7" -"@next/polyfill-module@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.1.tgz#89d5a70685a52a0fad79f05a1f97a6b15cc727aa" - integrity sha512-9FyVSnz00WGdlLsgc2w1xL1Lm/Q25y6FYIyA+1WlJvT6LA2lbR78GKiHgedzUvrAatVGAcg/Og+d0d7B4tsJOg== +"@next/polyfill-module@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.2.tgz#1fe92c364fdc81add775a16c678f5057c6aace98" + integrity sha512-xZmixqADM3xxtqBV0TpAwSFzWJP0MOQzRfzItHXf1LdQHWb0yofHHC+7eOrPFic8+ZGz5y7BdPkkgR1S25OymA== -"@next/react-dev-overlay@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.1.tgz#3cd99202a85412bada8ba9c8e3f4cf7c19294b24" - integrity sha512-CXc/A0DbSk5VXYu4+zr0fHm52Zh/LhPlLyVPEctJOZL64ccxkls5xGoXvgolJCku9L0pLjJzvdfAmhNLOp5dyw== +"@next/react-dev-overlay@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.2.tgz#73795dc5454b7af168bac93df7099965ebb603be" + integrity sha512-rDF/mGY2NC69mMg2vDqzVpCOlWqnwPUXB2zkARhvknUHyS6QJphPYv9ozoPJuoT/QBs49JJd9KWaAzVBvq920A== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -187,30 +218,30 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.1.tgz#8d1a5432a53c9f987503d5ab07d3241230afb33f" - integrity sha512-j186y+lWc8BHAuysAWvlOqO9Bp7E3BLK/d/Ju3W2sP5BCH5ZLyLG/p308zSy/O0MGTag0B038ZA1dCy/msouRQ== +"@next/react-refresh-utils@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.2.tgz#44ea40d8e773e4b77bad85e24f6ac041d5e4b4a5" + integrity sha512-hsoJmPfhVqjZ8w4IFzoo8SyECVnN+8WMnImTbTKrRUHOVJcYMmKLL7xf7T0ft00tWwAl/3f3Q3poWIN2Ueql/Q== -"@next/swc-darwin-arm64@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.1.tgz#ea9a76bcff00945df29a81bc43b3b22dd0a6cb53" - integrity sha512-KyB0aLpfQ+B2dsyGYpkM0ZwK3PV0t4C4b9yjgQc1VoTVnIjzXdDPnNOuVvmD849ZNOHfj3x8e2rlbxkj0lPm3A== +"@next/swc-darwin-arm64@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.2.tgz#93226c38db488c4b62b30a53b530e87c969b8251" + integrity sha512-hZuwOlGOwBZADA8EyDYyjx3+4JGIGjSHDHWrmpI7g5rFmQNltjlbaefAbiU5Kk7j3BUSDwt30quJRFv3nyJQ0w== -"@next/swc-darwin-x64@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.1.tgz#95838e9116897ae734d02fdbbfa601b6f52adaf3" - integrity sha512-B3ZXgrGx0bQplbrk2oggPjKPPsmyg8Fl0PJLMTVQ+erQ8g1m5QzyS9P6tB3SiIZa180JgENuguTHlVK5qEj4UA== +"@next/swc-darwin-x64@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.2.tgz#792003989f560c00677b5daeff360b35b510db83" + integrity sha512-PGOp0E1GisU+EJJlsmJVGE+aPYD0Uh7zqgsrpD3F/Y3766Ptfbe1lEPPWnRDl+OzSSrSrX1lkyM/Jlmh5OwNvA== -"@next/swc-linux-x64-gnu@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.1.tgz#42c4973213a880977ebdfad01474217d7d71e8c2" - integrity sha512-qvZL7gSKF+E+GZ3L1XiTnE3cOh9rk0wkqimT/q+wwcZA4E720Lu4lrT79I3HPuj6i/JPgGvmNskcnYrDeaoFaw== +"@next/swc-linux-x64-gnu@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.2.tgz#8216b2ae1f21f0112958735c39dd861088108f37" + integrity sha512-YcDHTJjn/8RqvyJVB6pvEKXihDcdrOwga3GfMv/QtVeLphTouY4BIcEUfrG5+26Nf37MP1ywN3RRl1TxpurAsQ== -"@next/swc-win32-x64-msvc@11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.1.tgz#1ffcbd01a0155fa8558f7aefffea1066e9bebe74" - integrity sha512-jhnCiA1De1L+kA0gmHG1AJijHoxOcrETWziDWy8fcqSrM1NlC4aJ5Mnu6k0QMcM9MnmXTA4TQZOEv3kF7vhJUQ== +"@next/swc-win32-x64-msvc@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.2.tgz#e15824405df137129918205e43cb5e9339589745" + integrity sha512-e/pIKVdB+tGQYa1cW3sAeHm8gzEri/HYLZHT4WZojrUxgWXqx8pk7S7Xs47uBcFTqBDRvK3EcQpPLf3XdVsDdg== "@node-rs/helper@1.2.1": version "1.2.1" @@ -221,7 +252,7 @@ "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -229,60 +260,60 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.7" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz" - integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@patternfly/react-core@^4.135.7": - version "4.135.7" - resolved "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.135.7.tgz" - integrity sha512-bxYLJ7TTXiEVHscfzqGbI+YFqwQMYWfG2Yknw/b/QqwN/bv5eCpioYOo35Wr4jvFAWkXvUUKp/DUpcSHrrFgTg== +"@patternfly/react-core@^4.152.4": + version "4.152.4" + resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.152.4.tgz#fa008d155ab0c4161aab27bb67ad88fb8689dee2" + integrity sha512-saMnAoF3KnYB5k6K04Y6NtO61bXYl71yzGPYSrM/DjyWDlIGLqPPhMe4kbWafLTpSgJdkxPoODgVMDp2ZIJ0Jw== dependencies: - "@patternfly/react-icons" "^4.11.2" - "@patternfly/react-styles" "^4.11.2" - "@patternfly/react-tokens" "^4.12.3" + "@patternfly/react-icons" "^4.11.14" + "@patternfly/react-styles" "^4.11.13" + "@patternfly/react-tokens" "^4.12.15" focus-trap "6.2.2" react-dropzone "9.0.0" tippy.js "5.1.2" - tslib "1.13.0" - -"@patternfly/react-icons@^4.11.2": - version "4.11.2" - resolved "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.11.2.tgz" - integrity sha512-BPRWHAopry4a8aFd3VWaqO8h7QDA4NeYZ80YAY1iGqWeClIAmZlxs6jGCUhTC7iuYmjKruiVoDQwuwr/u+p6JQ== - -"@patternfly/react-styles@^4.11.2": - version "4.11.2" - resolved "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-4.11.2.tgz" - integrity sha512-rUtw2tfniBiVIYEXPO8buisWFEHVR6dO5PH6C2MvbMk+VyUIS31TzOeNFyJs/gCurt7t1dEKjI9yNEGuAOjUPQ== - -"@patternfly/react-table@^4.29.8": - version "4.29.8" - resolved "https://registry.npmjs.org/@patternfly/react-table/-/react-table-4.29.8.tgz" - integrity sha512-N6oKSE0sRHvkc9KWF03oTISfsc6G5NRBRCedi81hnpOSVo2515lGnA/r1ipR1DwM9qHYxmPNsrkPeoYtDQBOSQ== - dependencies: - "@patternfly/react-core" "^4.135.7" - "@patternfly/react-icons" "^4.11.2" - "@patternfly/react-styles" "^4.11.2" - "@patternfly/react-tokens" "^4.12.3" + tslib "^2.0.0" + +"@patternfly/react-icons@^4.11.14": + version "4.11.14" + resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.11.14.tgz#ef7a2de3f78d5bd83715afb9651a185a89901c22" + integrity sha512-SBwID1p+UaQ9BSmzIRFr+BJEhYgx1rWHlm2HIZzhoz7BG3Q7byaQ8ZNfZLm0D+ZGVJQ+fq0zUHGE1nzxDPFqNQ== + +"@patternfly/react-styles@^4.11.13": + version "4.11.13" + resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.11.13.tgz#6595adc5ff40585add0128d27d420322b65b86a9" + integrity sha512-svhnWIqZwJt1cOxwYjvz6lVYeL+c9D17xpKqlkJapXRxJL3ppTfIqwBrT3o9+02ElaXUTKt4xjMkSnEVjw4qxA== + +"@patternfly/react-table@^4.29.58": + version "4.29.58" + resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.29.58.tgz#be77a6eee6a60c26e1f6939aaae007f21be52355" + integrity sha512-0KaypqnO1baaS8ESpaMyPcGmOsAva7vO9GzBiiiKnYizfjsPPE58KryyiLu0fEXBT6ESzYYm8I6pZNzzlI50Ww== + dependencies: + "@patternfly/react-core" "^4.152.4" + "@patternfly/react-icons" "^4.11.14" + "@patternfly/react-styles" "^4.11.13" + "@patternfly/react-tokens" "^4.12.15" lodash "^4.17.19" - tslib "1.13.0" + tslib "^2.0.0" -"@patternfly/react-tokens@^4.12.3": - version "4.12.3" - resolved "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-4.12.3.tgz" - integrity sha512-RgXPEDdgx/p2VPQyCCxvv+ff9lmgYm4QDcI3c8iIwQjpPnJ5KF/bT6lPoAfeLFocRIZDnDSDcwSINbQwPQGp2A== +"@patternfly/react-tokens@^4.12.15": + version "4.12.15" + resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.12.15.tgz#af760a1b378edce85fd2f7394553911b6ee3c4f0" + integrity sha512-lRW0qxGjuFEPMweBSQFHNRNoxavx5uR8b28f0lPN0Jlz4QsaCFVTmHM2XqflOHDpjE8SPJW/hJMSsyUrqnM5dw== "@redux-saga/core@^1.1.3": version "1.1.3" - resolved "https://registry.npmjs.org/@redux-saga/core/-/core-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4" integrity sha512-8tInBftak8TPzE6X13ABmEtRJGjtK17w7VUs7qV17S8hCO5S3+aUTWZ/DBsBJPdE8Z5jOPwYALyvofgq1Ws+kg== dependencies: "@babel/runtime" "^7.6.3" @@ -296,19 +327,19 @@ "@redux-saga/deferred@^1.1.2": version "1.1.2" - resolved "https://registry.npmjs.org/@redux-saga/deferred/-/deferred-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.1.2.tgz#59937a0eba71fff289f1310233bc518117a71888" integrity sha512-908rDLHFN2UUzt2jb4uOzj6afpjgJe3MjICaUNO3bvkV/kN/cNeI9PMr8BsFXB/MR8WTAZQq/PlTq8Kww3TBSQ== "@redux-saga/delay-p@^1.1.2": version "1.1.2" - resolved "https://registry.npmjs.org/@redux-saga/delay-p/-/delay-p-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.1.2.tgz#8f515f4b009b05b02a37a7c3d0ca9ddc157bb355" integrity sha512-ojc+1IoC6OP65Ts5+ZHbEYdrohmIw1j9P7HS9MOJezqMYtCDgpkoqB5enAAZrNtnbSL6gVCWPHaoaTY5KeO0/g== dependencies: "@redux-saga/symbols" "^1.1.2" "@redux-saga/is@^1.1.2": version "1.1.2" - resolved "https://registry.npmjs.org/@redux-saga/is/-/is-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.1.2.tgz#ae6c8421f58fcba80faf7cadb7d65b303b97e58e" integrity sha512-OLbunKVsCVNTKEf2cH4TYyNbbPgvmZ52iaxBD4I1fTif4+MTXMa4/Z07L83zW/hTCXwpSZvXogqMqLfex2Tg6w== dependencies: "@redux-saga/symbols" "^1.1.2" @@ -316,22 +347,22 @@ "@redux-saga/symbols@^1.1.2": version "1.1.2" - resolved "https://registry.npmjs.org/@redux-saga/symbols/-/symbols-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.1.2.tgz#216a672a487fc256872b8034835afc22a2d0595d" integrity sha512-EfdGnF423glv3uMwLsGAtE6bg+R9MdqlHEzExnfagXPrIiuxwr3bdiAwz3gi+PsrQ3yBlaBpfGLtDG8rf3LgQQ== "@redux-saga/types@^1.1.0": version "1.1.0" - resolved "https://registry.npmjs.org/@redux-saga/types/-/types-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204" integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg== "@rushstack/eslint-patch@^1.0.6": version "1.0.6" - resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz#023d72a5c4531b4ce204528971700a78a85a0c50" integrity sha512-Myxw//kzromB9yWgS8qYGuGVf91oBUUJpNvy5eM50sqvmKLbKjwLxohJnkWGTeeI9v9IBMtPLxz5Gc60FIfvCA== "@sentry/browser@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/browser/-/browser-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.30.0.tgz#c28f49d551db3172080caef9f18791a7fd39e3b3" integrity sha512-rOb58ZNVJWh1VuMuBG1mL9r54nZqKeaIlwSlvzJfc89vyfd7n6tQ1UXMN383QBz/MS5H5z44Hy5eE+7pCrYAfw== dependencies: "@sentry/core" "5.30.0" @@ -341,7 +372,7 @@ "@sentry/core@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== dependencies: "@sentry/hub" "5.30.0" @@ -352,7 +383,7 @@ "@sentry/hub@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== dependencies: "@sentry/types" "5.30.0" @@ -361,7 +392,7 @@ "@sentry/minimal@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== dependencies: "@sentry/hub" "5.30.0" @@ -370,7 +401,7 @@ "@sentry/react@^5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/react/-/react-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.30.0.tgz#320e05f766b6a26faefa8d76d1101fd50c69f541" integrity sha512-dvn4mqCgbeEuUXEGp5P9PaW5j4GWTFUSdx/yG8f9IxNZv5zM+7otjog9ukrubFZvlxVxD/PrIxK0MhadfFY/Dw== dependencies: "@sentry/browser" "5.30.0" @@ -382,7 +413,7 @@ "@sentry/tracing@^5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== dependencies: "@sentry/hub" "5.30.0" @@ -393,44 +424,44 @@ "@sentry/types@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== "@sentry/utils@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== dependencies: "@sentry/types" "5.30.0" tslib "^1.9.3" -"@types/d3-path@^1": - version "1.0.9" - resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz" - integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== +"@types/d3-path@^2": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-2.0.1.tgz#ca03dfa8b94d8add97ad0cd97e96e2006b4763cb" + integrity sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw== "@types/d3-scale@^3.0.0": - version "3.2.2" - resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.2.2.tgz" - integrity sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ== + version "3.3.2" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.3.2.tgz#18c94e90f4f1c6b1ee14a70f14bfca2bd1c61d06" + integrity sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ== dependencies: - "@types/d3-time" "*" + "@types/d3-time" "^2" "@types/d3-shape@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.0.0.tgz" - integrity sha512-NLzD02m5PiD1KLEDjLN+MtqEcFYn4ZL9+Rqc9ZwARK1cpKZXd91zBETbe6wpBB6Ia0D0VZbpmbW3+BsGPGnCpA== + version "2.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.1.3.tgz#35d397b9e687abaa0de82343b250b9897b8cacf3" + integrity sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ== dependencies: - "@types/d3-path" "^1" + "@types/d3-path" "^2" -"@types/d3-time@*": - version "2.0.0" - resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.0.0.tgz" - integrity sha512-Abz8bTzy8UWDeYs9pCa3D37i29EWDjNTjemdk0ei1ApYVNqulYlGUKip/jLOpogkPSsPz/GvZCYiC7MFlEk0iQ== +"@types/d3-time@^2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342" + integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg== "@types/hoist-non-react-statics@^3.3.0": version "3.3.1" - resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== dependencies: "@types/react" "*" @@ -438,28 +469,28 @@ "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/node@*": - version "15.0.2" - resolved "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz" - integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== + version "16.7.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.13.tgz#86fae356b03b5a12f2506c6cf6cd9287b205973f" + integrity sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA== "@types/parse-json@^4.0.0": version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prop-types@*": - version "15.7.3" - resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + version "15.7.4" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" + integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== "@types/react-redux@^7.1.16": - version "7.1.16" - resolved "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz" - integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== + version "7.1.18" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.18.tgz#2bf8fd56ebaae679a90ebffe48ff73717c438e04" + integrity sha512-9iwAsPyJ9DLTRH+OFeIrm9cAbIj1i2ANL3sKQFATqnPWRbg+jEFXyZOKHiQK/N86pNRXbb4HRxAxo0SIX1XwzQ== dependencies: "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" @@ -467,91 +498,91 @@ redux "^4.0.0" "@types/react@*": - version "17.0.5" - resolved "https://registry.npmjs.org/@types/react/-/react-17.0.5.tgz" - integrity sha512-bj4biDB9ZJmGAYTWSKJly6bMr4BLUiBrx9ujiJEoP9XIDY9CTaPGxE5QWN/1WjpPLzYF7/jRNnV2nNxNe970sw== + version "17.0.20" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.20.tgz#a4284b184d47975c71658cd69e759b6bd37c3b8c" + integrity sha512-wWZrPlihslrPpcKyCSlmIlruakxr57/buQN1RjlIeaaTWDLtJkTtRW429MoQJergvVKc4IWBpRhWw7YNh/7GVA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" -"@types/resize-observer-browser@^0.1.5": - version "0.1.5" - resolved "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz" - integrity sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ== +"@types/resize-observer-browser@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.6.tgz#d8e6c2f830e2650dc06fe74464472ff64b54a302" + integrity sha512-61IfTac0s9jvNtBCpyo86QeaN8qqpMGHdK0uGKCCIy2dt5/Yk84VduHIdWAcmkC5QvdkPL0p5eWYgUZtHKKUVg== "@types/scheduler@*": - version "0.16.1" - resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== -"@types/uuid@8.0.0": - version "8.0.0" - resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.0.0.tgz" - integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== +"@types/uuid@8.3.1": + version "8.3.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" + integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg== "@typescript-eslint/parser@^4.20.0": - version "4.26.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.0.tgz" - integrity sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg== + version "4.31.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.31.0.tgz#87b7cd16b24b9170c77595d8b1363f8047121e05" + integrity sha512-oWbzvPh5amMuTmKaf1wp0ySxPt2ZXHnFQBN2Szu1O//7LmOvgaKTCIDNLK2NvzpmVd5A2M/1j/rujBqO37hj3w== dependencies: - "@typescript-eslint/scope-manager" "4.26.0" - "@typescript-eslint/types" "4.26.0" - "@typescript-eslint/typescript-estree" "4.26.0" + "@typescript-eslint/scope-manager" "4.31.0" + "@typescript-eslint/types" "4.31.0" + "@typescript-eslint/typescript-estree" "4.31.0" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.26.0": - version "4.26.0" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz" - integrity sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg== +"@typescript-eslint/scope-manager@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.31.0.tgz#9be33aed4e9901db753803ba233b70d79a87fc3e" + integrity sha512-LJ+xtl34W76JMRLjbaQorhR0hfRAlp3Lscdiz9NeI/8i+q0hdBZ7BsiYieLoYWqy+AnRigaD3hUwPFugSzdocg== dependencies: - "@typescript-eslint/types" "4.26.0" - "@typescript-eslint/visitor-keys" "4.26.0" + "@typescript-eslint/types" "4.31.0" + "@typescript-eslint/visitor-keys" "4.31.0" -"@typescript-eslint/types@4.26.0": - version "4.26.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.0.tgz" - integrity sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A== +"@typescript-eslint/types@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.31.0.tgz#9a7c86fcc1620189567dc4e46cad7efa07ee8dce" + integrity sha512-9XR5q9mk7DCXgXLS7REIVs+BaAswfdHhx91XqlJklmqWpTALGjygWVIb/UnLh4NWhfwhR5wNe1yTyCInxVhLqQ== -"@typescript-eslint/typescript-estree@4.26.0": - version "4.26.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz" - integrity sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg== +"@typescript-eslint/typescript-estree@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.0.tgz#4da4cb6274a7ef3b21d53f9e7147cc76f278a078" + integrity sha512-QHl2014t3ptg+xpmOSSPn5hm4mY8D4s97ftzyk9BZ8RxYQ3j73XcwuijnJ9cMa6DO4aLXeo8XS3z1omT9LA/Eg== dependencies: - "@typescript-eslint/types" "4.26.0" - "@typescript-eslint/visitor-keys" "4.26.0" + "@typescript-eslint/types" "4.31.0" + "@typescript-eslint/visitor-keys" "4.31.0" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.26.0": - version "4.26.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz" - integrity sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg== +"@typescript-eslint/visitor-keys@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.0.tgz#4e87b7761cb4e0e627dc2047021aa693fc76ea2b" + integrity sha512-HUcRp2a9I+P21+O21yu3ezv3GEPGjyGiXoEUQwZXjR8UxRApGeLyWH4ZIIUSalE28aG4YsV6GjtaAVB3QKOu0w== dependencies: - "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/types" "4.31.0" eslint-visitor-keys "^2.0.0" -abortcontroller-polyfill@^1.7.1: +abortcontroller-polyfill@^1.7.3: version "1.7.3" - resolved "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn@^7.4.0: version "7.4.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -559,7 +590,7 @@ aggregate-error@^3.0.0: ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -568,9 +599,9 @@ ajv@^6.10.0, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1: - version "8.5.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz" - integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== + version "8.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" + integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -579,68 +610,71 @@ ajv@^8.0.1: anser@1.4.9: version "1.4.9" - resolved "https://registry.npmjs.org/anser/-/anser-1.4.9.tgz" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== ansi-colors@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-regex@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -anymatch@~3.1.1: +anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" -approximate-number@~2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/approximate-number/-/approximate-number-2.0.0.tgz" - integrity sha1-Q8f7+7sAcKQSEx1lWB+GiyTR6yk= +approximate-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/approximate-number/-/approximate-number-2.1.0.tgz#8dbb27957f4f230e386b57258f8f0c75f32313c8" + integrity sha512-EioK6nto/hEnwaJ7d/TG1WOZ9o0zTyIFVP4Lk7zzR/3I4O7ivkBNo7EvLC2Xh2j2HD/cb9sUqXHdexfGXCXYDA== argparse@^1.0.7: version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== + dependencies: + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" -array-includes@^3.1.2, array-includes@^3.1.3: +array-includes@^3.1.1, array-includes@^3.1.2, array-includes@^3.1.3: version "3.1.3" - resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== dependencies: call-bind "^1.0.2" @@ -651,12 +685,12 @@ array-includes@^3.1.2, array-includes@^3.1.3: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.flat@^1.2.4: version "1.2.4" - resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== dependencies: call-bind "^1.0.0" @@ -665,7 +699,7 @@ array.prototype.flat@^1.2.4: array.prototype.flatmap@^1.2.4: version "1.2.4" - resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== dependencies: call-bind "^1.0.0" @@ -675,7 +709,7 @@ array.prototype.flatmap@^1.2.4: asn1.js@^5.2.0: version "5.4.1" - resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" @@ -685,7 +719,7 @@ asn1.js@^5.2.0: assert@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== dependencies: es6-object-assign "^1.1.0" @@ -695,74 +729,87 @@ assert@2.0.0: assert@^1.1.1: version "1.5.0" - resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: object-assign "^4.1.1" util "0.10.3" +ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + ast-types@0.13.2: version "0.13.2" - resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.2.tgz" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== attr-accept@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-1.1.3.tgz#48230c79f93790ef2775fcec4f0db0f5db41ca52" integrity sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ== dependencies: core-js "^2.5.0" -available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axe-core@^4.0.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" + integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== + +axobject-query@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" + integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2: version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== big-integer@^1.6.16: version "1.6.48" - resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== big.js@^5.2.2: version "5.2.2" - resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.0.0, bn.js@^5.1.1: version "5.2.0" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -770,14 +817,14 @@ brace-expansion@^1.1.7: braces@^3.0.1, braces@~3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" broadcast-channel@^3.4.1: version "3.7.0" - resolved "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937" integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg== dependencies: "@babel/runtime" "^7.7.2" @@ -791,19 +838,19 @@ broadcast-channel@^3.4.1: brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= -browser-tabs-lock@^1.2.13: - version "1.2.14" - resolved "https://registry.npmjs.org/browser-tabs-lock/-/browser-tabs-lock-1.2.14.tgz" - integrity sha512-ssSpCRcvFe4vc098LDnrJOQDfZiG35KhQGB9hthTbwJk5mmUkePwhcMlW61NH3YuIE2Y9uGLqf9yxEBKbaDlaw== +browser-tabs-lock@^1.2.14: + version "1.2.15" + resolved "https://registry.yarnpkg.com/browser-tabs-lock/-/browser-tabs-lock-1.2.15.tgz#d5012e652e2a0cb4eba471b0a2300c2fa5d92788" + integrity sha512-J8K9vdivK0Di+b8SBdE7EZxDr88TnATing7XoLw6+nFkXMQ6sVBh92K3NQvZlZU91AIkFRi0w3sztk5Z+vsswA== dependencies: lodash ">=4.17.21" browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" - resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" @@ -815,7 +862,7 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: browserify-cipher@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" @@ -824,7 +871,7 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" @@ -834,7 +881,7 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: version "4.1.0" - resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: bn.js "^5.0.0" @@ -842,7 +889,7 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: browserify-sign@^4.0.0: version "4.2.1" - resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== dependencies: bn.js "^5.1.1" @@ -857,14 +904,14 @@ browserify-sign@^4.0.0: browserify-zlib@0.2.0, browserify-zlib@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: pako "~1.0.5" browserslist@4.16.6: version "4.16.6" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: caniuse-lite "^1.0.30001219" @@ -875,12 +922,12 @@ browserslist@4.16.6: buffer-xor@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@5.6.0: version "5.6.0" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== dependencies: base64-js "^1.0.2" @@ -888,7 +935,7 @@ buffer@5.6.0: buffer@^4.3.0: version "4.9.2" - resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" @@ -897,17 +944,17 @@ buffer@^4.3.0: builtin-status-codes@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= bytes@3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" @@ -915,17 +962,17 @@ call-bind@^1.0.0, call-bind@^1.0.2: callsites@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: - version "1.0.30001232" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz" - integrity sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg== + version "1.0.30001255" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001255.tgz#f3b09b59ab52e39e751a569523618f47c4298ca0" + integrity sha512-F+A3N9jTZL882f/fg/WWVnKSu6IOo3ueLz4zwaOPbPYHNmM/ZaDUyzyJwS1mZhX7Ex5jqTyW599Gdelh5PDYLQ== chalk@2.4.2, chalk@^2.0.0: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -934,23 +981,23 @@ chalk@2.4.2, chalk@^2.0.0: chalk@4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" chalk@^4.0.0, chalk@^4.1.0: - version "4.1.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0": +chokidar@3.5.1: version "3.5.1" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" @@ -963,44 +1010,59 @@ chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0": optionalDependencies: fsevents "~2.3.1" +"chokidar@>=3.0.0 <4.0.0": + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + ci-info@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" -classnames@2.2.6, classnames@~2.2.5: +classnames@2.2.6: version "2.2.6" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -classnames@^2.2.5: +classnames@^2.2.5, classnames@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-truncate@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== dependencies: slice-ansi "^3.0.0" @@ -1008,110 +1070,104 @@ cli-truncate@^2.1.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= color-name@~1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.3.0.tgz#ff45d2f0edb244069d3b772adeb04fed38d0a0af" + integrity sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w== -commander@^6.0.0: +commander@^6.2.0: version "6.2.1" - resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== commondir@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= compare-versions@^3.6.0: version "3.6.0" - resolved "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== complex.js@^2.0.11: - version "2.0.12" - resolved "https://registry.npmjs.org/complex.js/-/complex.js-2.0.12.tgz" - integrity sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw== + version "2.0.15" + resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.15.tgz#7add6848b4c1d12aa9262f7df925ebe7a51a7406" + integrity sha512-gDBvQU8IG139ZBQTSo2qvDFP+lANMGluM779csXOr6ny1NUtA3wkUnCFjlDNH/moAVfXtvClYt6G0zarFbtz5w== computed-styles@^1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/computed-styles/-/computed-styles-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/computed-styles/-/computed-styles-1.1.2.tgz#a7e732ba145149399ade70c2f94b353dd8ad629d" integrity sha1-p+cyuhRRSTma3nDC+Us1PditYp0= concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= console-browserify@^1.1.0: version "1.2.0" - resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== constants-browserify@1.0.0, constants-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= convert-source-map@1.7.0: version "1.7.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" +core-js-pure@^3.16.0: + version "3.17.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.17.2.tgz#ba6311b6aa1e2f2adeba4ac6ec51a9ff40bdc1af" + integrity sha512-2VV7DlIbooyTI7Bh+yzOOWL9tGwLnQKHno7qATE+fqZzDKYr6llVjVQOzpD/QLZFgXDPb8T71pJokHEZHEYJhQ== + core-js@^2.5.0: version "2.6.12" - resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-js@^3.11.0: - version "3.12.1" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz" - integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== +core-js@^3.16.1: + version "3.17.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.17.2.tgz#f960eae710dc62c29cca93d5332e3660e289db10" + integrity sha512-XkbXqhcXeMHPRk2ItS+zQYliAMilea2euoMsnpRRdDad6b2VY6CQQcwz1K8AnWesfw4p165RzY0bTnr3UrbYiA== core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== dependencies: "@types/parse-json" "^4.0.0" import-fresh "^3.2.1" @@ -1121,7 +1177,7 @@ cosmiconfig@^7.0.0: create-ecdh@^4.0.0: version "4.0.4" - resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" @@ -1129,7 +1185,7 @@ create-ecdh@^4.0.0: create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" @@ -1140,7 +1196,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" - resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" @@ -1152,7 +1208,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -1161,7 +1217,7 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: crypto-browserify@3.12.0, crypto-browserify@^3.11.0: version "3.12.0" - resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" @@ -1178,12 +1234,12 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0: css-unit-converter@^1.1.1: version "1.1.2" - resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== css.escape@1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= cssnano-preset-simple@^3.0.0: @@ -1202,41 +1258,41 @@ cssnano-simple@3.0.0: csstype@^3.0.2: version "3.0.8" - resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== d3-array@2, d3-array@^2.3.0: version "2.12.1" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== dependencies: internmap "^1.0.0" "d3-color@1 - 2": version "2.0.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== "d3-format@1 - 2": version "2.0.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== "d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== dependencies: d3-color "1 - 2" "d3-path@1 - 2": version "2.0.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== d3-scale@^3.2.3: version "3.3.0" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== dependencies: d3-array "^2.3.0" @@ -1247,91 +1303,96 @@ d3-scale@^3.2.3: d3-shape@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== dependencies: d3-path "1 - 2" "d3-time-format@2 - 3": version "3.0.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== dependencies: d3-time "1 - 2" "d3-time@1 - 2", d3-time@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== dependencies: d3-array "2" +damerau-levenshtein@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" + integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== + data-uri-to-buffer@3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== debug@2, debug@^2.6.9: version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.2.7: version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@^4.0.1, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" decimal.js-light@^2.4.1: version "2.5.1" - resolved "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== dedent@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= deep-diff@^0.3.5: version "0.3.8" - resolved "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz" + resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= deep-is@^0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== define-properties@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" depd@~1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" @@ -1339,12 +1400,12 @@ des.js@^1.0.0: detect-node@^2.0.4, detect-node@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== diffie-hellman@^5.0.0: version "5.0.3" - resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" @@ -1353,50 +1414,50 @@ diffie-hellman@^5.0.0: dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-helpers@^3.4.0: version "3.4.0" - resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== dependencies: "@babel/runtime" "^7.1.2" domain-browser@4.19.0: version "4.19.0" - resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-4.19.0.tgz" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1" integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ== domain-browser@^1.1.1: version "1.2.0" - resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== electron-to-chromium@^1.3.723: - version "1.3.743" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz" - integrity sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg== + version "1.3.831" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.831.tgz#96201f83f6eef05054b532a897fd3cd73cd60250" + integrity sha512-0tc2lPzgEipHCyRcvDTTaBk5+jSPfNaCvbQdevNMqJkHLvrBiwhygPR0hDyPZEK7Xztvv+58gSFKJ/AUVT1yYQ== elliptic@^6.5.3: version "6.5.4" - resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: bn.js "^4.11.9" @@ -1409,31 +1470,36 @@ elliptic@^6.5.3: emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.0.0: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= encoding@0.1.13: version "0.1.13" - resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: iconv-lite "^0.6.2" end-of-stream@^1.1.0: version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enhanced-resolve@^5.7.0: version "5.8.2" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== dependencies: graceful-fs "^4.2.4" @@ -1441,44 +1507,22 @@ enhanced-resolve@^5.7.0: enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: - version "1.18.0" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.0" - -es-abstract@^1.18.2: - version "1.18.3" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz" - integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.18.5: + version "1.18.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19" + integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" @@ -1486,11 +1530,12 @@ es-abstract@^1.18.2: get-intrinsic "^1.1.1" has "^1.0.3" has-symbols "^1.0.2" + internal-slot "^1.0.3" is-callable "^1.2.3" is-negative-zero "^2.0.1" is-regex "^1.1.3" is-string "^1.0.6" - object-inspect "^1.10.3" + object-inspect "^1.11.0" object-keys "^1.1.1" object.assign "^4.1.2" string.prototype.trimend "^1.0.4" @@ -1499,12 +1544,12 @@ es-abstract@^1.18.2: es-cookie@^1.3.2: version "1.3.2" - resolved "https://registry.npmjs.org/es-cookie/-/es-cookie-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/es-cookie/-/es-cookie-1.3.2.tgz#80e831597f72a25721701bdcb21d990319acd831" integrity sha512-UTlYYhXGLOy05P/vKVT2Ui7WtC7NiRzGtJyAKKn32g5Gvcjn7KAClLPWlipCtxIus934dFg9o9jXiBL0nP+t9Q== es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -1513,92 +1558,123 @@ es-to-primitive@^1.2.1: es6-object-assign@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= escalade@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-latex@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-next@^10.2.3: - version "10.2.3" - resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-10.2.3.tgz" - integrity sha512-ubpv6YHqd3UFVPTz8z+Nih+H77rORLXrB7ZinIhrI7ZzZn5rvZ6V7AkcVrI8mVoYVyOo0qZ7vN8D2/Q7vxLMfg== +eslint-config-next@^11.1.2: + version "11.1.2" + resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-11.1.2.tgz#73c918f2fa6120d5f65080bf3fcf6b154905707e" + integrity sha512-dFutecxX2Z5/QVlLwdtKt+gIfmNMP8Qx6/qZh3LM/DFVdGJEAnUKrr4VwGmACB2kx/PQ5bx3R+QxnEg4fDPiTg== dependencies: - "@next/eslint-plugin-next" "10.2.3" + "@next/eslint-plugin-next" "11.1.2" "@rushstack/eslint-patch" "^1.0.6" "@typescript-eslint/parser" "^4.20.0" eslint-import-resolver-node "^0.3.4" + eslint-import-resolver-typescript "^2.4.0" eslint-plugin-import "^2.22.1" + eslint-plugin-jsx-a11y "^6.4.1" eslint-plugin-react "^7.23.1" eslint-plugin-react-hooks "^4.2.0" -eslint-import-resolver-node@^0.3.4: - version "0.3.4" - resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz" - integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== +eslint-import-resolver-node@^0.3.4, eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== dependencies: - debug "^2.6.9" - resolve "^1.13.1" + debug "^3.2.7" + resolve "^1.20.0" -eslint-module-utils@^2.6.1: - version "2.6.1" - resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz" - integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== +eslint-import-resolver-typescript@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.4.0.tgz#ec1e7063ebe807f0362a7320543aaed6fe1100e1" + integrity sha512-useJKURidCcldRLCNKWemr1fFQL1SzB3G4a0li6lFGvlc5xGe1hY343bvG07cbpCzPuM/lK19FIJB3XGFSkplA== + dependencies: + debug "^4.1.1" + glob "^7.1.6" + is-glob "^4.0.1" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" + +eslint-module-utils@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" + integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== dependencies: debug "^3.2.7" pkg-dir "^2.0.0" eslint-plugin-import@^2.22.1: - version "2.23.4" - resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz" - integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ== + version "2.24.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" + integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== dependencies: array-includes "^3.1.3" array.prototype.flat "^1.2.4" debug "^2.6.9" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.1" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.6.2" find-up "^2.0.0" has "^1.0.3" - is-core-module "^2.4.0" + is-core-module "^2.6.0" minimatch "^3.0.4" - object.values "^1.1.3" + object.values "^1.1.4" pkg-up "^2.0.0" read-pkg-up "^3.0.0" resolve "^1.20.0" - tsconfig-paths "^3.9.0" + tsconfig-paths "^3.11.0" + +eslint-plugin-jsx-a11y@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" + integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== + dependencies: + "@babel/runtime" "^7.11.2" + aria-query "^4.2.2" + array-includes "^3.1.1" + ast-types-flow "^0.0.7" + axe-core "^4.0.2" + axobject-query "^2.2.0" + damerau-levenshtein "^1.0.6" + emoji-regex "^9.0.0" + has "^1.0.3" + jsx-ast-utils "^3.1.0" + language-tags "^1.0.5" eslint-plugin-react-hooks@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== eslint-plugin-react@^7.23.1: - version "7.24.0" - resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz" - integrity sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q== + version "7.25.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.25.1.tgz#9286b7cd9bf917d40309760f403e53016eda8331" + integrity sha512-P4j9K1dHoFXxDNP05AtixcJEvIT6ht8FhYKsrkY0MPCPaUMYijhpWwNiRDZVtA8KFuZOkGSeft6QwH8KuVpJug== dependencies: array-includes "^3.1.3" array.prototype.flatmap "^1.2.4" doctrine "^2.1.0" + estraverse "^5.2.0" has "^1.0.3" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.0.4" @@ -1611,7 +1687,7 @@ eslint-plugin-react@^7.23.1: eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -1619,28 +1695,29 @@ eslint-scope@^5.1.1: eslint-utils@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@^7.27.0: - version "7.27.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-7.27.0.tgz" - integrity sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA== +eslint@^7.32.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== dependencies: "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.1" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -1657,7 +1734,7 @@ eslint@^7.27.0: fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" + glob-parent "^5.1.2" globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" @@ -1681,7 +1758,7 @@ eslint@^7.27.0: espree@^7.3.0, espree@^7.3.1: version "7.3.1" - resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" @@ -1690,64 +1767,64 @@ espree@^7.3.0, espree@^7.3.1: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@1.8.1: version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eventemitter3@^4.0.1: version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: version "3.3.0" - resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^4.0.3: +execa@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" @@ -1762,84 +1839,76 @@ execa@^4.0.3: fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-equals@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.2.tgz" - integrity sha512-ehHsR38w6sqy5E0QrWQxclb+zl3ulNsgCVWt1cMoZ6QBFgtkr4lKZWpQP1kfEFn6bWnm78pmiDGak+zUvQ2/DQ== + version "2.0.3" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.3.tgz#7039b0a039909f345a2ce53f6202a14e5f392efc" + integrity sha512-0EMw4TTUxsMDpDkCg0rXor2gsg+npVrMIHbEhvD0HZyIhUX6AktC/yasm+qKwfyswd06Qy95ZKk8p2crTo0iPA== fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-text-encoding@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + version "1.12.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.12.0.tgz#ed7b6ab5d62393fb2cc591c853652a5c318bf794" + integrity sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg== dependencies: reusify "^1.0.4" -figures@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" file-saver@^1.3.3: version "1.3.8" - resolved "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz" + resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.8.tgz#e68a30c7cb044e2fb362b428469feb291c2e09d8" integrity sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg== file-selector@^0.1.8: version "0.1.19" - resolved "https://registry.npmjs.org/file-selector/-/file-selector-0.1.19.tgz" + resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.19.tgz#8ecc9d069a6f544f2e4a096b64a8052e70ec8abf" integrity sha512-kCWw3+Aai8Uox+5tHCNgMFaUdgidxvMnLWO6fM5sZ0hA2wlHP5/DHGF0ECe84BiB95qdJbKNEJhWKVDvMN+JDQ== dependencies: tslib "^2.0.1" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" find-cache-dir@3.3.1: version "3.3.1" - resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== dependencies: commondir "^1.0.1" @@ -1848,79 +1917,87 @@ find-cache-dir@3.3.1: find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= dependencies: locate-path "^2.0.0" find-up@^4.0.0: version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" path-exists "^4.0.0" -find-versions@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz" - integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: - semver-regex "^2.0.0" + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-versions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" + integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== + dependencies: + semver-regex "^3.1.2" flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" rimraf "^3.0.2" flatted@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + version "3.2.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" + integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== focus-trap@6.2.2: version "6.2.2" - resolved "https://registry.npmjs.org/focus-trap/-/focus-trap-6.2.2.tgz" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.2.2.tgz#0e6f391415b0697c99da932702dedd13084fa131" integrity sha512-qWovH9+LGoKqREvJaTCzJyO0hphQYGz+ap5Hc4NqXHNhZBdxCi5uBPPcaOUw66fHmzXLVwvETLvFgpwPILqKpg== dependencies: tabbable "^5.1.4" foreach@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= fraction.js@^4.0.12: - version "4.0.13" - resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz" - integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== + version "4.1.1" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff" + integrity sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: +fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== functional-red-black-tree@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" @@ -1929,38 +2006,38 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: get-orientation@1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/get-orientation/-/get-orientation-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/get-orientation/-/get-orientation-1.1.2.tgz#20507928951814f8a91ded0a0e67b29dfab98947" integrity sha512-/pViTfifW+gBbh/RnlFYHINvELT9Znt+SYyDKAUL6uV6By019AK/s+i9XP4jSwq7lwP38Fd8HVeTxym3+hkwmQ== dependencies: stream-parser "^0.3.1" get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-stream@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" -glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-to-regexp@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.1.3: +glob@7.1.7, glob@^7.1.3, glob@^7.1.6: version "7.1.7" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" @@ -1970,24 +2047,17 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -globals@^13.6.0: - version "13.9.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz" - integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== +globals@^13.6.0, globals@^13.9.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" + integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== dependencies: type-fest "^0.20.2" globby@^11.0.3: - version "11.0.3" - resolved "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -1997,40 +2067,47 @@ globby@^11.0.3: slash "^3.0.0" graceful-fs@^4.1.2, graceful-fs@^4.2.4: - version "4.2.6" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== has-bigints@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hash-base@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: inherits "^2.0.4" @@ -2039,7 +2116,7 @@ hash-base@^3.0.0: hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" - resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" @@ -2047,12 +2124,12 @@ hash.js@^1.0.0, hash.js@^1.0.3: he@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" @@ -2061,19 +2138,19 @@ hmac-drbg@^1.0.1: hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" - resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: react-is "^16.7.0" hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== http-errors@1.7.3: version "1.7.3" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== dependencies: depd "~1.1.2" @@ -2084,62 +2161,62 @@ http-errors@1.7.3: https-browserify@1.0.0, https-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= human-signals@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -husky@~4.2.5: - version "4.2.5" - resolved "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz" - integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ== +husky@^4.3.8: + version "4.3.8" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" + integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== dependencies: chalk "^4.0.0" ci-info "^2.0.0" compare-versions "^3.6.0" - cosmiconfig "^6.0.0" - find-versions "^3.2.0" + cosmiconfig "^7.0.0" + find-versions "^4.0.0" opencollective-postinstall "^2.0.2" - pkg-dir "^4.2.0" + pkg-dir "^5.0.0" please-upgrade-node "^3.2.0" slash "^3.0.0" which-pm-runs "^1.0.0" iconv-lite@0.4.24: version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" ieee754@^1.1.4: version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^4.0.6: version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.4: version "5.1.8" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== image-size@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.0.tgz#58b31fe4743b1cec0a0ac26f5c914d3c5b2f0750" integrity sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw== dependencies: queue "6.0.2" @@ -2149,9 +2226,9 @@ immer@^9.0.6: resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73" integrity sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ== -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -2159,17 +2236,17 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" @@ -2177,22 +2254,22 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inherits@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= inherits@2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= internal-slot@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== dependencies: get-intrinsic "^1.1.0" @@ -2201,82 +2278,90 @@ internal-slot@^1.0.3: internmap@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-bigint@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz" - integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz" - integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-callable@^1.1.4, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== -is-core-module@^2.2.0, is-core-module@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== +is-core-module@^2.2.0, is-core-module@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19" + integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ== dependencies: has "^1.0.3" is-date-object@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz" - integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-function@^1.0.7: - version "1.0.9" - resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz" - integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" is-nan@^1.2.1: version "1.3.2" - resolved "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== dependencies: call-bind "^1.0.0" @@ -2284,88 +2369,92 @@ is-nan@^1.2.1: is-negative-zero@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number-object@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz" - integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= -is-regex@^1.1.2, is-regex@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz" - integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== +is-regex@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" - has-symbols "^1.0.2" + has-tostringtag "^1.0.0" is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.0.5, is-string@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz" - integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.3: - version "1.1.5" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz" - integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== +is-typed-array@^1.1.3, is-typed-array@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" + integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA== dependencies: - available-typed-arrays "^1.0.2" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" - es-abstract "^1.18.0-next.2" + es-abstract "^1.18.5" foreach "^2.0.5" - has-symbols "^1.0.1" + has-tostringtag "^1.0.0" is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= javascript-natural-sort@^0.7.1: version "0.7.1" - resolved "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz" + resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k= jest-worker@27.0.0-next.5: version "27.0.0-next.5" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.0-next.5.tgz" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28" integrity sha512-mk0umAQ5lT+CaOJ+Qp01N6kz48sJG2kr2n1rX0koqKf6FIygQV0qLOdN9SCYID4IVeSigDOcPeGLozdMLYfb5g== dependencies: "@types/node" "*" @@ -2374,17 +2463,17 @@ jest-worker@27.0.0-next.5: js-sha3@0.8.0: version "0.8.0" - resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -2392,52 +2481,64 @@ js-yaml@^3.13.1: json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= json5@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: minimist "^1.2.0" -"jsx-ast-utils@^2.4.1 || ^3.0.0": +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: version "3.2.0" - resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== dependencies: array-includes "^3.1.2" object.assign "^4.1.2" -konva@~7.2.5: +konva@^7.2.5: version "7.2.5" - resolved "https://registry.npmjs.org/konva/-/konva-7.2.5.tgz" + resolved "https://registry.yarnpkg.com/konva/-/konva-7.2.5.tgz#9b4ac3a353e6be66e3e69123bf2a0cbc61efeb26" integrity sha512-yk/li8rUF+09QNlOdkwbEId+QvfATMe/aMGVouWW1oFoUVTYWHsQuIAE6lWy11DK8mLJEJijkNAXC5K+NVlMew== +language-subtag-registry@~0.3.2: + version "0.3.21" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" + integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== + +language-tags@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= + dependencies: + language-subtag-registry "~0.3.2" + levn@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -2445,23 +2546,23 @@ levn@^0.4.1: lines-and-columns@^1.1.6: version "1.1.6" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@~10.2.2: - version "10.2.13" - resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.2.13.tgz" - integrity sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA== +lint-staged@^10.5.4: + version "10.5.4" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665" + integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" - commander "^6.0.0" + commander "^6.2.0" cosmiconfig "^7.0.0" - debug "^4.1.1" + debug "^4.2.0" dedent "^0.7.0" enquirer "^2.3.6" - execa "^4.0.3" - listr2 "^2.6.0" + execa "^4.1.0" + listr2 "^3.2.2" log-symbols "^4.0.0" micromatch "^4.0.2" normalize-path "^3.0.0" @@ -2469,23 +2570,22 @@ lint-staged@~10.2.2: string-argv "0.3.1" stringify-object "^3.3.0" -listr2@^2.6.0: - version "2.6.2" - resolved "https://registry.npmjs.org/listr2/-/listr2-2.6.2.tgz" - integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== +listr2@^3.2.2: + version "3.11.1" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.11.1.tgz#a9bab5cd5874fd3cb7827118dbea6fedefbcb43f" + integrity sha512-ZXQvQfmH9iWLlb4n3hh31yicXDxlzB0pE7MM1zu6kgbVL4ivEsO4H8IPh4E682sC8RjnYO9anose+zT52rrpyg== dependencies: - chalk "^4.1.0" cli-truncate "^2.1.0" - figures "^3.2.0" - indent-string "^4.0.0" + colorette "^1.2.2" log-update "^4.0.0" p-map "^4.0.0" - rxjs "^6.6.2" + rxjs "^6.6.7" through "^2.3.8" + wrap-ansi "^7.0.0" load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= dependencies: graceful-fs "^4.1.2" @@ -2495,7 +2595,7 @@ load-json-file@^4.0.0: loader-utils@1.2.3: version "1.2.3" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== dependencies: big.js "^5.2.2" @@ -2504,7 +2604,7 @@ loader-utils@1.2.3: locate-path@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= dependencies: p-locate "^2.0.0" @@ -2512,49 +2612,56 @@ locate-path@^2.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.clonedeep@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= lodash.debounce@^4.0.8: version "4.0.8" - resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.sortby@^4.7.0: version "4.7.0" - resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= lodash.throttle@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= lodash.truncate@^4.4.2: version "4.4.2" - resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= lodash@>=4.17.21, lodash@^4.17.19: version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^4.0.0: version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -2562,7 +2669,7 @@ log-symbols@^4.0.0: log-update@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: ansi-escapes "^4.3.0" @@ -2572,36 +2679,36 @@ log-update@^4.0.0: loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" make-dir@^3.0.2: version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" match-sorter@^6.0.2: version "6.3.0" - resolved "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.0.tgz" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.0.tgz#454a1b31ed218cddbce6231a0ecb5fdc549fed01" integrity sha512-efYOf/wUpNb8FgNY+cOD2EIJI1S5I7YPKsw0LBp7wqPh5pmMS6i/wr3ZWwfwrAw1NvqTA2KUReVRWDX84lUcOQ== dependencies: "@babel/runtime" "^7.12.5" remove-accents "0.4.2" -mathjs@~7.6.0: +mathjs@^7.6.0: version "7.6.0" - resolved "https://registry.npmjs.org/mathjs/-/mathjs-7.6.0.tgz" + resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-7.6.0.tgz#f0b7579e0756b13422995d0c4f29bd17d65d4dcc" integrity sha512-abywR28hUpKF4at5jE8Ys+Kigk40eKMT5mcBLD0/dtsqjfOLbtzd3WjlRqIopNo7oQ6FME51qph6lb8h/bhpUg== dependencies: complex.js "^2.0.11" @@ -2615,7 +2722,7 @@ mathjs@~7.6.0: md5.js@^1.3.4: version "1.3.5" - resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" @@ -2624,17 +2731,17 @@ md5.js@^1.3.4: merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0: version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.2: +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: braces "^3.0.1" @@ -2642,12 +2749,12 @@ micromatch@^4.0.2: microseconds@0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== miller-rabin@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" @@ -2655,49 +2762,49 @@ miller-rabin@^4.0.0: mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= minimatch@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@^1.2.0: version "1.2.5" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== ms@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== ms@^2.1.1: version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== nano-time@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= dependencies: big-integer "^1.6.16" @@ -2709,35 +2816,35 @@ nanoid@^3.1.23: native-url@0.3.4: version "0.3.4" - resolved "https://registry.npmjs.org/native-url/-/native-url-0.3.4.tgz" + resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA== dependencies: querystring "^0.2.0" natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= next-transpile-modules@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/next-transpile-modules/-/next-transpile-modules-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-8.0.0.tgz#56375cdc25ae5d23a834195f277fc2737b26cb97" integrity sha512-Q2f2yB0zMJ8KJbIYAeZoIxG6cSfVk813zr6B5HzsLMBVcJ3FaF8lKr7WG66n0KlHCwjLSmf/6EkgI6QQVWHrDw== dependencies: enhanced-resolve "^5.7.0" escalade "^3.1.1" -next@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/next/-/next-11.1.1.tgz#ca15c6d6b4b4bf8c3e859f7fc4f9657ce59bcb63" - integrity sha512-vfLJDkwAHsZUho5R1K4w49nfYhftUMWNmeNSjCtulOvnRBuEFb7ROyRZOQk7f29rMz02eLQrPZ9yiAmPsexL2g== +next@^11.1.2: + version "11.1.2" + resolved "https://registry.yarnpkg.com/next/-/next-11.1.2.tgz#527475787a9a362f1bc916962b0c0655cc05bc91" + integrity sha512-azEYL0L+wFjv8lstLru3bgvrzPvK0P7/bz6B/4EJ9sYkXeW8r5Bjh78D/Ol7VOg0EIPz0CXoe72hzAlSAXo9hw== dependencies: "@babel/runtime" "7.15.3" "@hapi/accept" "5.0.2" - "@next/env" "11.1.1" - "@next/polyfill-module" "11.1.1" - "@next/react-dev-overlay" "11.1.1" - "@next/react-refresh-utils" "11.1.1" + "@next/env" "11.1.2" + "@next/polyfill-module" "11.1.2" + "@next/react-dev-overlay" "11.1.2" + "@next/react-refresh-utils" "11.1.2" "@node-rs/helper" "1.2.1" assert "2.0.0" ast-types "0.13.2" @@ -2775,7 +2882,7 @@ next@^11.1.1: stream-browserify "3.0.0" stream-http "3.1.1" string_decoder "1.3.0" - styled-jsx "4.0.0" + styled-jsx "4.0.1" timers-browserify "2.0.12" tty-browserify "0.0.1" use-subscription "1.5.1" @@ -2783,26 +2890,26 @@ next@^11.1.1: vm-browserify "1.1.2" watchpack "2.1.1" optionalDependencies: - "@next/swc-darwin-arm64" "11.1.1" - "@next/swc-darwin-x64" "11.1.1" - "@next/swc-linux-x64-gnu" "11.1.1" - "@next/swc-win32-x64-msvc" "11.1.1" + "@next/swc-darwin-arm64" "11.1.2" + "@next/swc-darwin-x64" "11.1.2" + "@next/swc-linux-x64-gnu" "11.1.2" + "@next/swc-win32-x64-msvc" "11.1.2" node-fetch@2.6.1: version "2.6.1" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== node-html-parser@1.4.9: version "1.4.9" - resolved "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.4.9.tgz" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-1.4.9.tgz#3c8f6cac46479fae5800725edb532e9ae8fd816c" integrity sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw== dependencies: he "1.2.0" node-libs-browser@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== dependencies: assert "^1.1.1" @@ -2830,13 +2937,13 @@ node-libs-browser@^2.2.1: vm-browserify "^1.0.1" node-releases@^1.1.71: - version "1.1.72" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz" - integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== + version "1.1.75" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.75.tgz#6dd8c876b9897a1b8e5a02de26afa79bb54ebbfe" + integrity sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw== normalize-package-data@^2.3.2: version "2.5.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -2846,34 +2953,34 @@ normalize-package-data@^2.3.2: normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalizr@^3.6.1: version "3.6.1" - resolved "https://registry.npmjs.org/normalizr/-/normalizr-3.6.1.tgz" + resolved "https://registry.yarnpkg.com/normalizr/-/normalizr-3.6.1.tgz#d367ab840e031ff382141b8d81ce279292ff69fe" integrity sha512-8iEmqXmPtll8PwbEFrbPoDxVw7MKnNvt3PZzR2Xvq9nggEEOgBlNICPXYzyZ4w4AkHUzCU998mdatER3n2VaMA== npm-run-path@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-inspect@^1.10.3, object-inspect@^1.9.0: - version "1.10.3" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz" - integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== object-is@^1.0.1: version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: call-bind "^1.0.2" @@ -2881,12 +2988,12 @@ object-is@^1.0.1: object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.2: version "4.1.2" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: call-bind "^1.0.0" @@ -2896,7 +3003,7 @@ object.assign@^4.1.2: object.entries@^1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== dependencies: call-bind "^1.0.2" @@ -2905,7 +3012,7 @@ object.entries@^1.1.4: object.fromentries@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8" integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ== dependencies: call-bind "^1.0.2" @@ -2913,9 +3020,9 @@ object.fromentries@^2.0.4: es-abstract "^1.18.0-next.2" has "^1.0.3" -object.values@^1.1.3, object.values@^1.1.4: +object.values@^1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== dependencies: call-bind "^1.0.2" @@ -2924,31 +3031,31 @@ object.values@^1.1.3, object.values@^1.1.4: oblivious-set@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^5.1.0: version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" opencollective-postinstall@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== optionator@^0.9.1: version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -2960,76 +3067,83 @@ optionator@^0.9.1: os-browserify@0.3.0, os-browserify@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -p-limit@3.1.0: +p-limit@3.1.0, p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-limit@^1.1.0: version "1.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-locate@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= dependencies: p-limit "^1.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-try@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= p-try@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: version "1.0.11" - resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" - resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: asn1.js "^5.2.0" @@ -3040,7 +3154,7 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= dependencies: error-ex "^1.3.1" @@ -3048,7 +3162,7 @@ parse-json@^4.0.0: parse-json@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -3058,54 +3172,54 @@ parse-json@^5.0.0: path-browserify@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== path-browserify@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: version "3.1.2" - resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" @@ -3116,67 +3230,74 @@ pbkdf2@^3.0.3: performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.2.3" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz" - integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== pify@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pkg-dir@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= dependencies: find-up "^2.1.0" -pkg-dir@^4.1.0, pkg-dir@^4.2.0: +pkg-dir@^4.1.0: version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + pkg-up@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= dependencies: find-up "^2.1.0" platform@1.3.6: version "1.3.6" - resolved "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== please-upgrade-node@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" pnp-webpack-plugin@1.6.4: version "1.6.4" - resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== dependencies: ts-pnp "^1.1.6" popper.js@^1.16.0: version "1.16.1" - resolved "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== postcss-value-parser@^3.3.0: version "3.3.1" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss@8.2.15: @@ -3190,45 +3311,45 @@ postcss@8.2.15: prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@~2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz" - integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== +prettier@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@0.11.10, process@^0.11.10: version "0.11.10" - resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= progress@^2.0.0: version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-polyfill@^8.2.0: version "8.2.0" - resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.0.tgz" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.0.tgz#367394726da7561457aba2133c9ceefbd6267da0" integrity sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g== prop-types-extra@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== dependencies: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: +prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" - resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== dependencies: loose-envify "^1.4.0" @@ -3237,7 +3358,7 @@ prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@~15.7.2: public-encrypt@^4.0.0: version "4.0.3" - resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" @@ -3249,7 +3370,7 @@ public-encrypt@^4.0.0: pump@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -3257,63 +3378,63 @@ pump@^3.0.0: punycode@1.3.2: version "1.3.2" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@^1.2.4: version "1.4.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0: version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== querystring-es3@0.2.1, querystring-es3@^0.2.0: version "0.2.1" - resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= querystring@0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= querystring@^0.2.0: version "0.2.1" - resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== queue@6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== dependencies: inherits "~2.0.3" raf@^3.4.0: version "3.4.1" - resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== dependencies: performance-now "^2.1.0" randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" @@ -3321,7 +3442,7 @@ randomfill@^1.0.3: raw-body@2.4.1: version "2.4.1" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== dependencies: bytes "3.1.0" @@ -3331,7 +3452,7 @@ raw-body@2.4.1: react-dom@^17.0.2: version "17.0.2" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: loose-envify "^1.1.0" @@ -3340,7 +3461,7 @@ react-dom@^17.0.2: react-dropzone@9.0.0: version "9.0.0" - resolved "https://registry.npmjs.org/react-dropzone/-/react-dropzone-9.0.0.tgz" + resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-9.0.0.tgz#4f5223cdcb4d3bd8a66e3298c4041eb0c75c4634" integrity sha512-wZ2o9B2qkdE3RumWhfyZT9swgJYJPeU5qHEcMU8weYpmLex1eeWX0CC32/Y0VutB+BBi2D+iePV/YZIiB4kZGw== dependencies: attr-accept "^1.1.3" @@ -3350,29 +3471,29 @@ react-dropzone@9.0.0: react-hotkeys@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/react-hotkeys/-/react-hotkeys-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0.tgz#a7719c7340cbba888b0e9184f806a9ec0ac2c53f" integrity sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q== dependencies: prop-types "^15.6.1" react-is@16.10.2: version "16.10.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.10.2.tgz" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab" integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA== react-is@17.0.2: version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-konva@~17.0.2-0: +react-konva@^17.0.2-5: version "17.0.2-5" - resolved "https://registry.npmjs.org/react-konva/-/react-konva-17.0.2-5.tgz" + resolved "https://registry.yarnpkg.com/react-konva/-/react-konva-17.0.2-5.tgz#e70b0acf323402de0a540f27b300fbe7ed151849" integrity sha512-IyzdfqRDK8r1ulp/jbLPX18AuO+n5yNtL0+4T0QEUsgArRqIl/VRCG1imA5mYJBk0cBNC5+fWDHN+HWEW62ZEQ== dependencies: react-reconciler "~0.26.2" @@ -3380,13 +3501,13 @@ react-konva@~17.0.2-0: react-lifecycles-compat@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== -react-query@^3.18.1: - version "3.18.1" - resolved "https://registry.npmjs.org/react-query/-/react-query-3.18.1.tgz" - integrity sha512-17lv3pQxU9n+cB5acUv0/cxNTjo9q8G+RsedC6Ax4V9D8xEM7Q5xf9xAbCPdEhDrrnzPjTls9fQEABKRSi7OJA== +react-query@^3.22.0: + version "3.22.0" + resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.22.0.tgz#f59bbc48737c6f34070aee85037caf5a990de565" + integrity sha512-S1vv7N7np3N9MCCIE8vNGG7LpPhHDn4yQmY1sUZ+ABBuSU/h4Rtz+0qLpKh+Vs0/icvdsdrzI2LA2p0yqnLzRg== dependencies: "@babel/runtime" "^7.5.5" broadcast-channel "^3.4.1" @@ -3394,17 +3515,17 @@ react-query@^3.18.1: react-reconciler@~0.26.2: version "0.26.2" - resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz" + resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.26.2.tgz#bbad0e2d1309423f76cf3c3309ac6c96e05e9d91" integrity sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" scheduler "^0.20.2" -react-redux@~7.2.0: - version "7.2.4" - resolved "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz" - integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== +react-redux@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.5.tgz#213c1b05aa1187d9c940ddfc0b29450957f6a3b8" + integrity sha512-Dt29bNyBsbQaysp6s/dN0gUodcq+dVKKER8Qv82UrpeygwYeX1raTtil7O/fftw/rFqzaf6gJhDZRkkZnn6bjg== dependencies: "@babel/runtime" "^7.12.1" "@types/react-redux" "^7.1.16" @@ -3415,22 +3536,22 @@ react-redux@~7.2.0: react-refresh@0.8.3: version "0.8.3" - resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== react-resize-detector@^6.6.3: - version "6.7.1" - resolved "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.1.tgz" - integrity sha512-54l8LWPBIRdtv0I/W/fMkmtgWX0mUIxKKAJKKimihNFueXtHuElDdXDyinQRmV7iku99AoyrSAhkCU/zjFG5+Q== + version "6.7.6" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-6.7.6.tgz#4416994e5ead7eba76606e3a248a1dfca49b67a3" + integrity sha512-/6RZlul1yePSoYJxWxmmgjO320moeLC/khrwpEVIL+D2EjLKhqOwzFv+H8laMbImVj7Zu4FlMa0oA7au3/ChjQ== dependencies: - "@types/resize-observer-browser" "^0.1.5" + "@types/resize-observer-browser" "^0.1.6" lodash.debounce "^4.0.8" lodash.throttle "^4.1.1" resize-observer-polyfill "^1.5.1" react-smooth@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91" integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw== dependencies: fast-equals "^2.0.0" @@ -3439,7 +3560,7 @@ react-smooth@^2.0.0: react-transition-group@2.9.0: version "2.9.0" - resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== dependencies: dom-helpers "^3.4.0" @@ -3449,7 +3570,7 @@ react-transition-group@2.9.0: react@^17.0.2: version "17.0.2" - resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" @@ -3457,7 +3578,7 @@ react@^17.0.2: read-pkg-up@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= dependencies: find-up "^2.0.0" @@ -3465,7 +3586,7 @@ read-pkg-up@^3.0.0: read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= dependencies: load-json-file "^4.0.0" @@ -3474,7 +3595,7 @@ read-pkg@^3.0.0: readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.7" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -3487,7 +3608,7 @@ readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6: readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.0" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" @@ -3496,22 +3617,29 @@ readable-stream@^3.5.0, readable-stream@^3.6.0: readdirp@~3.5.0: version "3.5.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + recharts-scale@^0.4.4: version "0.4.5" - resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== dependencies: decimal.js-light "^2.4.1" -recharts@~2.0.9: - version "2.0.9" - resolved "https://registry.npmjs.org/recharts/-/recharts-2.0.9.tgz" - integrity sha512-JNsXE80PuF3hugUCE7JqDOMSvu5xQLxtjOaqFKKZI2pCJ1PVJzhwDv4TWk0nO4AvADbeWzYEHbg8C5Hcrh42UA== +recharts@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.1.2.tgz#ceeb01e53fb46da0d946a1e0f82d783ddf5b9d06" + integrity sha512-rwFQT6T4imhLzD1kYtg9ql8YOesbFRdSwZi95KWgi5udbBdLGRCR4SgaPO8kf0URHcC23mdRbLLTMYCnXng7zQ== dependencies: "@types/d3-scale" "^3.0.0" "@types/d3-shape" "^2.0.0" @@ -3529,7 +3657,7 @@ recharts@~2.0.9: reduce-css-calc@^2.1.8: version "2.1.8" - resolved "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== dependencies: css-unit-converter "^1.1.1" @@ -3537,79 +3665,71 @@ reduce-css-calc@^2.1.8: redux-logger@~3.0.6: version "3.0.6" - resolved "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz" + resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" integrity sha1-91VZZvMJjzyIYExEnPC69XeCdL8= dependencies: deep-diff "^0.3.5" redux-saga@~1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/redux-saga/-/redux-saga-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.1.3.tgz#9f3e6aebd3c994bbc0f6901a625f9a42b51d1112" integrity sha512-RkSn/z0mwaSa5/xH/hQLo8gNf4tlvT18qXDNvedihLcfzh+jMchDgaariQoehCpgRltEm4zHKJyINEz6aqswTw== dependencies: "@redux-saga/core" "^1.1.3" redux-thunk@~2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== -redux@^4.0.0, redux@^4.0.4: - version "4.1.0" - resolved "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz" - integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== +redux@^4.0.0, redux@^4.0.4, redux@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.1.tgz#76f1c439bb42043f985fbd9bf21990e60bd67f47" + integrity sha512-hZQZdDEM25UY2P493kPYuKqviVwZ58lEmGQNeQ+gXa+U0gYPUBf7NKYazbe3m+bs/DzM/ahN12DbF+NG8i0CWw== dependencies: "@babel/runtime" "^7.9.2" -redux@~4.0.5: - version "4.0.5" - resolved "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz" - integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== - dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" - regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== regexp.prototype.flags@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== remove-accents@0.4.2: version "0.4.2" - resolved "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz" + resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== resize-observer-polyfill@^1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.13.1, resolve@^1.20.0: +resolve@^1.10.0, resolve@^1.17.0, resolve@^1.20.0: version "1.20.0" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: is-core-module "^2.2.0" @@ -3617,7 +3737,7 @@ resolve@^1.10.0, resolve@^1.13.1, resolve@^1.20.0: resolve@^2.0.0-next.3: version "2.0.0-next.3" - resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== dependencies: is-core-module "^2.2.0" @@ -3625,7 +3745,7 @@ resolve@^2.0.0-next.3: restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -3633,19 +3753,19 @@ restore-cursor@^3.1.0: reusify@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@3.0.2, rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" @@ -3653,43 +3773,43 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" -rxjs@^6.6.2: +rxjs@^6.6.7: version "6.6.7" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass@^1.32.12: - version "1.32.12" - resolved "https://registry.npmjs.org/sass/-/sass-1.32.12.tgz" - integrity sha512-zmXn03k3hN0KaiVTjohgkg98C3UowhL1/VSGdj4/VAAiMKGQOE80PFPxFP2Kyq0OUskPKcY5lImkhBKEHlypJA== +sass@^1.39.0: + version "1.39.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.39.0.tgz#6c64695d1c437767c8f1a4e471288e831f81d035" + integrity sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg== dependencies: chokidar ">=3.0.0 <4.0.0" scheduler@^0.20.2: version "0.20.2" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== dependencies: loose-envify "^1.1.0" @@ -3697,49 +3817,49 @@ scheduler@^0.20.2: seed-random@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ= semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz" - integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== +semver-regex@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" + integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== "semver@2 || 3 || 4 || 5": version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^6.0.0: version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.2.1, semver@^7.3.5: version "7.3.5" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" setimmediate@^1.0.4: version "1.0.5" - resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= setprototypeof@1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" - resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -3747,24 +3867,24 @@ sha.js@^2.4.0, sha.js@^2.4.8: shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@1.7.2: version "1.7.2" - resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -3773,17 +3893,17 @@ side-channel@^1.0.4: signal-exit@^3.0.2: version "3.0.3" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== slash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: ansi-styles "^4.0.0" @@ -3792,7 +3912,7 @@ slice-ansi@^3.0.0: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -3801,24 +3921,24 @@ slice-ansi@^4.0.0: source-map@0.7.3: version "0.7.3" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== source-map@0.8.0-beta.0: version "0.8.0-beta.0" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== dependencies: whatwg-url "^7.0.0" source-map@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== spdx-correct@^3.0.0: version "3.1.1" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" @@ -3826,42 +3946,42 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== + version "3.0.10" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" + integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= stacktrace-parser@0.1.10: version "0.1.10" - resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== dependencies: type-fest "^0.7.1" "statuses@>= 1.5.0 < 2": version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= stream-browserify@3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== dependencies: inherits "~2.0.4" @@ -3869,7 +3989,7 @@ stream-browserify@3.0.0: stream-browserify@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" @@ -3877,7 +3997,7 @@ stream-browserify@^2.0.1: stream-http@3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/stream-http/-/stream-http-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564" integrity sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg== dependencies: builtin-status-codes "^3.0.0" @@ -3887,7 +4007,7 @@ stream-http@3.1.1: stream-http@^2.7.2: version "2.8.3" - resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" @@ -3898,24 +4018,24 @@ stream-http@^2.7.2: stream-parser@^0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz" + resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M= dependencies: debug "2" string-argv@0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== string-hash@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" @@ -3924,7 +4044,7 @@ string-width@^4.1.0, string-width@^4.2.0: string.prototype.matchall@^4.0.5: version "4.0.5" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q== dependencies: call-bind "^1.0.2" @@ -3938,7 +4058,7 @@ string.prototype.matchall@^4.0.5: string.prototype.trimend@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: call-bind "^1.0.2" @@ -3946,7 +4066,7 @@ string.prototype.trimend@^1.0.4: string.prototype.trimstart@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: call-bind "^1.0.2" @@ -3954,21 +4074,21 @@ string.prototype.trimstart@^1.0.4: string_decoder@1.3.0, string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" @@ -3977,30 +4097,30 @@ stringify-object@^3.3.0: strip-ansi@6.0.0, strip-ansi@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== dependencies: ansi-regex "^5.0.0" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -styled-jsx@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.0.tgz#f7b90e7889d0a4f4635f8d1ae9ac32f3acaedc57" - integrity sha512-2USeoWMoJ/Lx5s2y1PxuvLy/cz2Yrr8cTySV3ILHU1Vmaw1bnV7suKdblLPjnyhMD+qzN7B1SWyh4UZTARn/WA== +styled-jsx@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.1.tgz#ae3f716eacc0792f7050389de88add6d5245b9e9" + integrity sha512-Gcb49/dRB1k8B4hdK8vhW27Rlb2zujCk1fISrizCcToIs+55B4vmUM0N9Gi4nnVfFZWe55jRdWpAqH1ldAKWvQ== dependencies: "@babel/plugin-syntax-jsx" "7.14.5" "@babel/types" "7.15.0" @@ -4013,56 +4133,51 @@ styled-jsx@4.0.0: stylis-rule-sheet@0.0.10: version "0.0.10" - resolved "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== stylis@3.5.4: version "3.5.4" - resolved "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" -svgsaver@~0.9.0: +svgsaver@^0.9.0: version "0.9.0" - resolved "https://registry.npmjs.org/svgsaver/-/svgsaver-0.9.0.tgz" + resolved "https://registry.yarnpkg.com/svgsaver/-/svgsaver-0.9.0.tgz#93d5dbb3f840953b8df0a14a942f4cc8d552335e" integrity sha1-k9Xbs/hAlTuN8KFKlC9MyNVSM14= dependencies: computed-styles "^1.1.2" file-saver "^1.3.3" -symbol-observable@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== - tabbable@^5.1.4: - version "5.2.0" - resolved "https://registry.npmjs.org/tabbable/-/tabbable-5.2.0.tgz" - integrity sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg== + version "5.2.1" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.1.tgz#e3fda7367ddbb172dcda9f871c0fdb36d1c4cd9c" + integrity sha512-40pEZ2mhjaZzK0BnI+QGNjJO8UYx9pP5v7BGe17SORTO0OEuuaAwQTkAp8whcZvqon44wKFOikD+Al11K3JICQ== table@^6.0.9: version "6.7.1" - resolved "https://registry.npmjs.org/table/-/table-6.7.1.tgz" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== dependencies: ajv "^8.0.1" @@ -4074,168 +4189,158 @@ table@^6.0.9: tapable@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== text-table@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= through@^2.3.8: version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timers-browserify@2.0.12, timers-browserify@^2.0.4: version "2.0.12" - resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" tiny-emitter@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== tippy.js@5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-5.1.2.tgz#5ac91233c59ab482ef5988cffe6e08bd26528e66" integrity sha512-Qtrv2wqbRbaKMUb6bWWBQWPayvcDKNrGlvihxtsyowhT7RLGEh1STWuy6EMXC6QLkfKPB2MLnf8W2mzql9VDAw== dependencies: popper.js "^1.16.0" to-arraybuffer@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= to-fast-properties@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toidentifier@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== tr46@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= dependencies: punycode "^2.1.0" ts-pnp@^1.1.6: version "1.2.0" - resolved "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== +tsconfig-paths@^3.11.0, tsconfig-paths@^3.9.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" + integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.1" minimist "^1.2.0" strip-bom "^3.0.0" -tslib@1.13.0: - version "1.13.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== - tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1: - version "2.2.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== +tslib@^2.0.0, tslib@^2.0.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" tty-browserify@0.0.0: version "0.0.0" - resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= tty-browserify@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.7.1: version "0.7.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - typed-function@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/typed-function/-/typed-function-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.0.0.tgz#15ab3825845138a8b1113bd89e60cd6a435739e8" integrity sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA== typescript-compare@^0.0.2: version "0.0.2" - resolved "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz" + resolved "https://registry.yarnpkg.com/typescript-compare/-/typescript-compare-0.0.2.tgz#7ee40a400a406c2ea0a7e551efd3309021d5f425" integrity sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA== dependencies: typescript-logic "^0.0.0" typescript-logic@^0.0.0: version "0.0.0" - resolved "https://registry.npmjs.org/typescript-logic/-/typescript-logic-0.0.0.tgz" + resolved "https://registry.yarnpkg.com/typescript-logic/-/typescript-logic-0.0.0.tgz#66ebd82a2548f2b444a43667bec120b496890196" integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== typescript-tuple@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/typescript-tuple/-/typescript-tuple-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/typescript-tuple/-/typescript-tuple-2.2.1.tgz#7d9813fb4b355f69ac55032e0363e8bb0f04dad2" integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q== dependencies: typescript-compare "^0.0.2" -unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: +unbox-primitive@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== dependencies: function-bind "^1.1.1" @@ -4245,12 +4350,12 @@ unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: unfetch@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== unload@2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== dependencies: "@babel/runtime" "^7.6.2" @@ -4258,46 +4363,46 @@ unload@2.2.0: unpipe@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" url@^0.11.0: version "0.11.0" - resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= dependencies: punycode "1.3.2" querystring "0.2.0" -use-resize-observer@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-7.0.0.tgz" - integrity sha512-+RjrQsk/mL8aKy4TGBDiPkUv6whyeoGDMIZYk0gOGHOlnrsjImC+jG6lfAFcBCKAG9epGRL419adhDNdkDCQkA== +use-resize-observer@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/use-resize-observer/-/use-resize-observer-8.0.0.tgz#69bd80c1ddd94f3758563fe107efb25fed85067a" + integrity sha512-n0iKSeiQpJCyaFh5JA0qsVLBIovsF4EIIR1G6XiBwKJN66ZrD4Oj62bjcuTAATPKiSp6an/2UZZxCf/67fk3sQ== dependencies: - resize-observer-polyfill "^1.5.1" + "@juggle/resize-observer" "^3.3.1" use-subscription@1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA== dependencies: object-assign "^4.1.1" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util@0.10.3: version "0.10.3" - resolved "https://registry.npmjs.org/util/-/util-0.10.3.tgz" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" @@ -4316,32 +4421,32 @@ util@0.12.4, util@^0.12.0: util@^0.11.0: version "0.11.1" - resolved "https://registry.npmjs.org/util/-/util-0.11.1.tgz" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== dependencies: inherits "2.0.3" -uuid@8.2.0: - version "8.2.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz" - integrity sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q== +uuid@8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuidv4@~6.1.1: - version "6.1.1" - resolved "https://registry.npmjs.org/uuidv4/-/uuidv4-6.1.1.tgz" - integrity sha512-ZplGb1SHFMVH3l7PUQl2Uwo+FpJQV6IPOoU+MjjbqrNYQolqbGwv+/sn9F+AGMsMOgGz3r9JN3ztGUi0VzMxmw== +uuidv4@^6.2.12: + version "6.2.12" + resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-6.2.12.tgz#e8c1d1d733c3fa4963d4610b8a3a09b4ec58ca96" + integrity sha512-UnN4ThIYWhv3ZUE8UwDnnCvh4JafCNu+sQkxmLyjCVwK3rjLfkg3DYiEv6oCMDIAIVEDP4INg4kX/C5hKaRzZA== dependencies: - "@types/uuid" "8.0.0" - uuid "8.2.0" + "@types/uuid" "8.3.1" + uuid "8.3.2" v8-compile-cache@^2.0.3: version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -4349,19 +4454,19 @@ validate-npm-package-license@^3.0.1: vm-browserify@1.1.2, vm-browserify@^1.0.1: version "1.1.2" - resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== warning@^4.0.0: version "4.0.3" - resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== dependencies: loose-envify "^1.0.0" watchpack@2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw== dependencies: glob-to-regexp "^0.4.1" @@ -4369,12 +4474,12 @@ watchpack@2.1.1: webidl-conversions@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== whatwg-url@^7.0.0: version "7.1.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== dependencies: lodash.sortby "^4.7.0" @@ -4383,7 +4488,7 @@ whatwg-url@^7.0.0: which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -4394,64 +4499,72 @@ which-boxed-primitive@^1.0.2: which-pm-runs@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= which-typed-array@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz" - integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + version "1.1.7" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" + integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw== dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.0" - es-abstract "^1.18.0-next.1" + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.7" which@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" word-wrap@^1.2.3: version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.7.2: +yaml@^1.10.0: version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -- cgit v1.2.3 From fe4cf5f4ecb99b6313b9c3c69557d228e2a34796 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 13:23:50 +0200 Subject: fix(docker): Mount local traces to correct container directory This change fixes an issue where local traces are not correctly detected due to Docker mounting the local traces in the incorrect directory. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b5d8cb98..c9459e5a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,7 +45,7 @@ services: volumes: - type: bind source: ./traces - target: /app/traces + target: /opt/opendc/traces environment: - OPENDC_API_URL=${OPENDC_API_BASE_URL} - AUTH0_DOMAIN=${OPENDC_AUTH0_DOMAIN} -- cgit v1.2.3 From 8f978b683ab51e37f6bdda65f4dc40d11a5e38b7 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 13:26:26 +0200 Subject: fix(docker): Do not warn when Sentry is not configured This change updates the Docker Compose configuration to not warn the user when they have not specified any Sentry configuration. Since Sentry is optional, the user should not be presented warnings. --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c9459e5a..57d2e021 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ services: NEXT_PUBLIC_AUTH0_DOMAIN: ${OPENDC_AUTH0_DOMAIN} NEXT_PUBLIC_AUTH0_CLIENT_ID: ${OPENDC_AUTH0_CLIENT_ID} NEXT_PUBLIC_AUTH0_AUDIENCE: ${OPENDC_AUTH0_AUDIENCE} - NEXT_PUBLIC_SENTRY_DSN: ${OPENDC_FRONTEND_SENTRY_DSN} + NEXT_PUBLIC_SENTRY_DSN: ${OPENDC_FRONTEND_SENTRY_DSN-} api: build: opendc-web/opendc-web-api @@ -31,7 +31,7 @@ services: - OPENDC_DB_HOST=mongo - OPENDC_FLASK_SECRET - OPENDC_OAUTH_CLIENT_ID - - SENTRY_DSN=${OPENDC_API_SENTRY_DSN} + - SENTRY_DSN=${OPENDC_API_SENTRY_DSN-} - SENTRY_ENVIRONMENT simulator: @@ -52,7 +52,7 @@ services: - AUTH0_AUDIENCE=${OPENDC_AUTH0_AUDIENCE} - AUTH0_CLIENT_ID=${OPENDC_AUTH0_CLIENT_ID_RUNNER} - AUTH0_CLIENT_SECRET=${OPENDC_AUTH0_CLIENT_SECRET_RUNNER} - - SENTRY_DSN=${OPENDC_SIMULATOR_SENTRY_DSN} + - SENTRY_DSN=${OPENDC_SIMULATOR_SENTRY_DSN-} - SENTRY_ENVIRONMENT mongo: -- cgit v1.2.3 From 61d74355a7b702917ae314c1c595b24fb8621a21 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 15:53:59 +0200 Subject: fix(docker): Default to public images for deployment This change updates the Docker Compose configuration to default to the available public images for OpenDC, in order to remove the requirement for building OpenDC locally. --- docker-compose.override.yml | 3 +++ docker-compose.yml | 13 ++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index b37068fc..6202e299 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -3,18 +3,21 @@ version: "3.8" # Docker Compose overrides for development environments services: frontend: + build: opendc-web/opendc-web-ui ports: - "8080:3000" environment: NEXT_PUBLIC_API_BASE_URL: http://localhost:8081 api: + build: opendc-web/opendc-web-api ports: - "8081:80" environment: SENTRY_ENVIRONMENT: "development" simulator: + build: . environment: SENTRY_ENVIRONMENT: "development" diff --git a/docker-compose.yml b/docker-compose.yml index 57d2e021..18847736 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,7 @@ version: "3.8" services: frontend: - build: - context: opendc-web/opendc-web-ui - image: frontend + image: atlargeresearch/opendc-web-ui:v2.1 restart: on-failure networks: - backend @@ -14,8 +12,7 @@ services: NEXT_PUBLIC_SENTRY_DSN: ${OPENDC_FRONTEND_SENTRY_DSN-} api: - build: opendc-web/opendc-web-api - image: api + image: atlargeresearch/opendc-web-api:v2.1 restart: on-failure networks: - backend @@ -35,8 +32,7 @@ services: - SENTRY_ENVIRONMENT simulator: - build: . - image: simulator + image: atlargeresearch/opendc:v2.1 restart: on-failure networks: - backend @@ -56,8 +52,7 @@ services: - SENTRY_ENVIRONMENT mongo: - build: - context: database + build: database restart: on-failure environment: - MONGO_INITDB_ROOT_USERNAME -- cgit v1.2.3 From f20d615e3f6e5b9d02526ac033778fb0419fed4e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 9 Sep 2021 16:21:41 +0200 Subject: feat(simulator): Support generic distribution in fault injector This change adds support for specifying the distribution of the failures, group size and duration for the fault injector. --- gradle/libs.versions.toml | 2 + .../experiments/capelin/ExperimentHelpers.kt | 11 +++-- .../opendc-simulator-failures/build.gradle.kts | 1 + .../simulator/failures/CorrelatedFaultInjector.kt | 49 ++++++++++------------ .../failures/UncorrelatedFaultInjector.kt | 31 +++++++++----- 5 files changed, 52 insertions(+), 42 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 76846104..4e2fc777 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,6 +2,7 @@ classgraph = "4.8.115" clikt = "3.2.0" config = "1.4.1" +commons-math3 = "3.6.1" hadoop = "3.3.1" jackson = "2.12.5" junit-jupiter = "5.7.2" @@ -71,3 +72,4 @@ kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchm classgraph = { module = "io.github.classgraph:classgraph", version.ref = "classgraph" } hadoop-common = { module = "org.apache.hadoop:hadoop-common", version.ref = "hadoop" } hadoop-mapreduce-client-core = { module = "org.apache.hadoop:hadoop-mapreduce-client-core", version.ref = "hadoop" } +commons-math3 = { module = "org.apache.commons:commons-math3", version.ref = "commons-math3" } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 0230409e..3d605300 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -26,6 +26,8 @@ import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.random.Well19937c import org.opendc.compute.api.* import org.opendc.compute.service.ComputeService import org.opendc.compute.service.scheduler.ComputeScheduler @@ -98,15 +100,16 @@ fun createFaultInjector( random: Random, failureInterval: Double ): FaultInjector { + val rng = Well19937c(random.nextLong()) + // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 // GRID'5000 return CorrelatedFaultInjector( coroutineScope, clock, - iatScale = ln(failureInterval), iatShape = 1.03, // Hours - sizeScale = ln(2.0), sizeShape = ln(1.0), // Expect 2 machines, with variation of 1 - dScale = ln(60.0), dShape = ln(60.0 * 8), // Minutes - random = random + iat = LogNormalDistribution(rng, ln(failureInterval), 1.03), + size = LogNormalDistribution(rng, 1.88, 1.25), + duration = LogNormalDistribution(rng, 8.89, 2.71) ) } diff --git a/opendc-simulator/opendc-simulator-failures/build.gradle.kts b/opendc-simulator/opendc-simulator-failures/build.gradle.kts index 57cd0a35..edd48b40 100644 --- a/opendc-simulator/opendc-simulator-failures/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-failures/build.gradle.kts @@ -29,4 +29,5 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) api(libs.kotlinx.coroutines) + api(libs.commons.math3) } diff --git a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt index 0e15f338..c3b85666 100644 --- a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt +++ b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt @@ -23,26 +23,29 @@ package org.opendc.simulator.failures import kotlinx.coroutines.* +import org.apache.commons.math3.distribution.RealDistribution import java.time.Clock -import kotlin.math.exp -import kotlin.math.max -import kotlin.random.Random -import kotlin.random.asJavaRandom +import java.util.* +import kotlin.math.roundToInt +import kotlin.math.roundToLong /** * A [FaultInjector] that injects fault in the system which are correlated to each other. Failures do not occur in * isolation, but will trigger other faults. + * + * @param scope The scope to run the fault injector in. + * @param clock The [Clock] to keep track of simulation time. + * @param iat The inter-arrival time distribution of the failures (in hours). + * @param size The failure group size distribution. + * @param duration The failure duration (in seconds). */ public class CorrelatedFaultInjector( - private val coroutineScope: CoroutineScope, + private val scope: CoroutineScope, private val clock: Clock, - private val iatScale: Double, - private val iatShape: Double, - private val sizeScale: Double, - private val sizeShape: Double, - private val dScale: Double, - private val dShape: Double, - random: Random = Random(0) + private val iat: RealDistribution, + private val size: RealDistribution, + private val duration: RealDistribution, + private val random: Random = Random(0) ) : FaultInjector { /** * The active failure domains that have been registered. @@ -54,11 +57,6 @@ public class CorrelatedFaultInjector( */ private var job: Job? = null - /** - * The [Random] instance to use. - */ - private val random: java.util.Random = random.asJavaRandom() - /** * Enqueue the specified [FailureDomain] to fail some time in the future. */ @@ -67,7 +65,7 @@ public class CorrelatedFaultInjector( // Clean up the domain if it finishes domain.scope.coroutineContext[Job]!!.invokeOnCompletion { - this@CorrelatedFaultInjector.coroutineScope.launch { + this@CorrelatedFaultInjector.scope.launch { active -= domain if (active.isEmpty()) { @@ -81,21 +79,21 @@ public class CorrelatedFaultInjector( return } - job = this.coroutineScope.launch { + job = this.scope.launch { while (active.isNotEmpty()) { ensureActive() // Make sure to convert delay from hours to milliseconds - val d = lognvariate(iatScale, iatShape) * 3.6e6 + val d = (iat.sample() * 3.6e6).roundToLong() // Handle long overflow if (clock.millis() + d <= 0) { return@launch } - delay(d.toLong()) + delay(d) - val n = lognvariate(sizeScale, sizeShape).toInt() + val n = size.sample().roundToInt() val targets = active.shuffled(random).take(n) for (failureDomain in targets) { @@ -103,14 +101,14 @@ public class CorrelatedFaultInjector( failureDomain.fail() } - val df = max(lognvariate(dScale, dShape) * 6e4, 15 * 6e4) + val df = (duration.sample() * 1000).roundToLong() // seconds to milliseconds // Handle long overflow if (clock.millis() + df <= 0) { return@launch } - delay(df.toLong()) + delay(df) for (failureDomain in targets) { failureDomain.recover() @@ -123,7 +121,4 @@ public class CorrelatedFaultInjector( job = null } } - - // XXX We should extract this in some common package later on. - private fun lognvariate(scale: Double, shape: Double) = exp(scale + shape * random.nextGaussian()) } diff --git a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt index b3bd737e..8f99f758 100644 --- a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt +++ b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt @@ -24,38 +24,47 @@ package org.opendc.simulator.failures import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import org.apache.commons.math3.distribution.RealDistribution import java.time.Clock -import kotlin.math.ln1p -import kotlin.math.pow -import kotlin.random.Random +import kotlin.math.roundToLong /** * A [FaultInjector] that injects uncorrelated faults into the system, meaning that failures of the subsystems are * independent. + * + * @param clock The [Clock] to keep track of simulation time. + * @param iat The failure inter-arrival time distribution (in hours) + * @param duration The failure duration distribution (in seconds). */ public class UncorrelatedFaultInjector( private val clock: Clock, - private val alpha: Double, - private val beta: Double, - private val random: Random = Random(0) + private val iat: RealDistribution, + private val duration: RealDistribution, ) : FaultInjector { /** * Enqueue the specified [FailureDomain] to fail some time in the future. */ override fun enqueue(domain: FailureDomain) { domain.scope.launch { - val d = random.weibull(alpha, beta) * 1e3 // Make sure to convert delay to milliseconds + val d = (iat.sample() * 3.6e6).roundToLong() // Make sure to convert delay to milliseconds // Handle long overflow if (clock.millis() + d <= 0) { return@launch } - delay(d.toLong()) + delay(d) domain.fail() + + val df = (duration.sample() * 1000).roundToLong() // seconds to milliseconds + + // Handle long overflow + if (clock.millis() + df <= 0) { + return@launch + } + + delay(df) + domain.recover() } } - - // XXX We should extract this in some common package later on. - private fun Random.weibull(alpha: Double, beta: Double) = (beta * (-ln1p(-nextDouble())).pow(1.0 / alpha)) } -- cgit v1.2.3 From 04945381d01d8c6e59befe6843f2c6f6da5e91bf Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 9 Sep 2021 16:46:33 +0200 Subject: refactor(capelin): Terminate servers after reaching deadline This change updates the Capelin experiment helpers to terminate a server when it has reached its end-date. --- .../experiments/capelin/ExperimentHelpers.kt | 33 +++++++++++++--------- .../experiments/capelin/CapelinIntegrationTest.kt | 24 ++++++++-------- .../src/test/resources/env/single.txt | 2 +- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 3d605300..512b754d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -54,7 +54,6 @@ import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.sdk.toOtelClock import java.time.Clock -import kotlin.coroutines.resume import kotlin.math.ln import kotlin.math.max import kotlin.random.Random @@ -169,10 +168,19 @@ suspend fun processTrace( monitor: ComputeMonitor? = null, ) { val client = scheduler.newClient() + val watcher = object : ServerWatcher { + override fun onStateChanged(server: Server, newState: ServerState) { + monitor?.onStateChange(clock.millis(), server, newState) + } + } + + // Create new image for the virtual machine val image = client.newImage("vm-image") - var offset = Long.MIN_VALUE + try { coroutineScope { + var offset = Long.MIN_VALUE + while (reader.hasNext()) { val entry = reader.next() @@ -183,9 +191,12 @@ suspend fun processTrace( // Make sure the trace entries are ordered by submission time assert(entry.start - offset >= 0) { "Invalid trace order" } delay(max(0, (entry.start - offset) - clock.millis())) + launch { chan.send(Unit) - val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, offset = -offset + 300001) + + val workloadOffset = -offset + 300001 + val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) val server = client.newServer( entry.name, image, @@ -196,18 +207,14 @@ suspend fun processTrace( ), meta = entry.meta + mapOf("workload" to workload) ) + server.watch(watcher) - suspendCancellableCoroutine { cont -> - server.watch(object : ServerWatcher { - override fun onStateChanged(server: Server, newState: ServerState) { - monitor?.onStateChange(clock.millis(), server, newState) + // Wait for the server reach its end time + val endTime = entry.meta["end-time"] as Long + delay(endTime + workloadOffset - clock.millis() + 1) - if (newState == ServerState.TERMINATED) { - cont.resume(Unit) - } - } - }) - } + // Delete the server after reaching the end-time of the virtual machine + server.delete() } } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index aed9a4bb..ab33bc25 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -52,7 +52,7 @@ import java.io.File import java.util.* /** - * An integration test suite for the SC20 experiments. + * An integration test suite for the Capelin experiments. */ class CapelinIntegrationTest { /** @@ -146,7 +146,7 @@ class CapelinIntegrationTest { filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) ) - val traceReader = createTestTraceReader(0.5, seed) + val traceReader = createTestTraceReader(0.25, seed) val environmentReader = createTestEnvironmentReader("single") val meterProvider = createMeterProvider(clock) @@ -174,9 +174,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(38051879552, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(34888186408, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(971668973, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(39183961335, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(35649903197, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(1043641877, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -226,10 +226,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(38051879552, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(34888186408, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(971668973, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, - { assertEquals(13910814, monitor.totalInterferedWork) { "Total interfered work incorrect" } } + { assertEquals(39183961335, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(35649903197, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(1043641877, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(2960970230, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -284,9 +284,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(25412073109, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(23695061858, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(368502468, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(38385852453, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(34886665781, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(979997253, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/env/single.txt b/opendc-experiments/opendc-experiments-capelin/src/test/resources/env/single.txt index 53b3c2d7..5642003d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/resources/env/single.txt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/resources/env/single.txt @@ -1,3 +1,3 @@ ClusterID;ClusterName;Cores;Speed;Memory;numberOfHosts;memoryCapacityPerHost;coreCountPerHost -A01;A01;8;3.2;64;1;64;8 +A01;A01;8;3.2;128;1;128;8 -- cgit v1.2.3 From d24cc0cc9c4fe2145f0337d65e9a75f631365973 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 10:59:44 +0200 Subject: refactor(compute): Integrate fault injection into compute simulator This change moves the fault injection logic directly into the opendc-compute-simulator module, so that it can operate at a higher abstraction. In the future, we might again split the module if we can re-use some of its logic. --- .../opendc-compute-simulator/build.gradle.kts | 2 +- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 37 +++--- .../opendc/compute/simulator/failure/HostFault.kt | 36 ++++++ .../compute/simulator/failure/HostFaultInjector.kt | 65 +++++++++++ .../simulator/failure/StartStopHostFault.kt | 55 +++++++++ .../simulator/failure/StochasticVictimSelector.kt | 44 ++++++++ .../compute/simulator/failure/VictimSelector.kt | 35 ++++++ .../simulator/internal/HostFaultInjectorImpl.kt | 103 +++++++++++++++++ .../opendc-experiments-capelin/build.gradle.kts | 1 - .../experiments/capelin/ExperimentHelpers.kt | 61 +++------- .../org/opendc/experiments/capelin/Portfolio.kt | 17 ++- .../experiments/capelin/CapelinIntegrationTest.kt | 41 ++----- .../opendc-experiments-energy21/build.gradle.kts | 1 - .../experiments/energy21/EnergyExperiment.kt | 3 - .../opendc-experiments-radice/build.gradle.kts | 1 - .../opendc-simulator-failures/build.gradle.kts | 33 ------ .../simulator/failures/CorrelatedFaultInjector.kt | 124 --------------------- .../org/opendc/simulator/failures/FailureDomain.kt | 47 -------- .../org/opendc/simulator/failures/FaultInjector.kt | 33 ------ .../failures/UncorrelatedFaultInjector.kt | 70 ------------ .../src/main/kotlin/org/opendc/web/runner/Main.kt | 20 ++-- settings.gradle.kts | 1 - 22 files changed, 395 insertions(+), 435 deletions(-) create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFault.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StartStopHostFault.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/VictimSelector.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt delete mode 100644 opendc-simulator/opendc-simulator-failures/build.gradle.kts delete mode 100644 opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt delete mode 100644 opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FailureDomain.kt delete mode 100644 opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FaultInjector.kt delete mode 100644 opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt diff --git a/opendc-compute/opendc-compute-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts index c5a9e668..cad051e6 100644 --- a/opendc-compute/opendc-compute-simulator/build.gradle.kts +++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeService) api(projects.opendcSimulator.opendcSimulatorCompute) - api(projects.opendcSimulator.opendcSimulatorFailures) + api(libs.commons.math3) implementation(projects.opendcUtils) implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 213d20ee..a1cc3390 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -43,7 +43,6 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.failures.FailureDomain import org.opendc.simulator.resources.SimResourceInterpreter import java.util.* import kotlin.coroutines.CoroutineContext @@ -66,11 +65,11 @@ public class SimHost( powerDriver: PowerDriver = SimplePowerDriver(ConstantPowerModel(0.0)), private val mapper: SimWorkloadMapper = SimMetaWorkloadMapper(), interferenceDomain: VmInterferenceDomain? = null -) : Host, FailureDomain, AutoCloseable { +) : Host, AutoCloseable { /** * The [CoroutineScope] of the host bounded by the lifecycle of the host. */ - override val scope: CoroutineScope = CoroutineScope(context + Job()) + private val scope: CoroutineScope = CoroutineScope(context + Job()) /** * The clock instance used by the host. @@ -347,6 +346,22 @@ public class SimHost( override fun toString(): String = "SimHost[uid=$uid,name=$name,model=$model]" + public suspend fun fail() { + reportTime() + _state = HostState.DOWN + for (guest in guests.values) { + guest.fail() + } + } + + public suspend fun recover() { + reportTime() + _state = HostState.UP + for (guest in guests.values) { + guest.start() + } + } + /** * Convert flavor to machine model. */ @@ -369,22 +384,6 @@ public class SimHost( listeners.forEach { it.onStateChanged(this, vm.server, vm.state) } } - override suspend fun fail() { - reportTime() - _state = HostState.DOWN - for (guest in guests.values) { - guest.fail() - } - } - - override suspend fun recover() { - reportTime() - _state = HostState.UP - for (guest in guests.values) { - guest.start() - } - } - /** * A virtual machine instance that the driver manages. */ diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFault.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFault.kt new file mode 100644 index 00000000..258ccc89 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFault.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.failure + +import org.opendc.compute.simulator.SimHost +import java.time.Clock + +/** + * Interface responsible for applying the fault to a host. + */ +public interface HostFault { + /** + * Apply the fault to the specified [victims]. + */ + public suspend fun apply(clock: Clock, victims: List) +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt new file mode 100644 index 00000000..5eff439f --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.failure + +import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.simulator.SimHost +import org.opendc.compute.simulator.internal.HostFaultInjectorImpl +import java.time.Clock +import kotlin.coroutines.CoroutineContext + +/** + * An interface for stochastically injecting faults into a set of hosts. + */ +public interface HostFaultInjector : AutoCloseable { + /** + * Start fault injection. + */ + public fun start() + + /** + * Stop fault injection into the system. + */ + public override fun close() + + public companion object { + /** + * Construct a new [HostFaultInjector]. + * + * @param context The scope to run the fault injector in. + * @param clock The [Clock] to keep track of simulation time. + * @param hosts The hosts to inject the faults into. + * @param iat The inter-arrival time distribution of the failures (in hours). + * @param selector The [VictimSelector] to select the host victims. + * @param fault The type of [HostFault] to inject. + */ + public operator fun invoke( + context: CoroutineContext, + clock: Clock, + hosts: Set, + iat: RealDistribution, + selector: VictimSelector, + fault: HostFault + ): HostFaultInjector = HostFaultInjectorImpl(context, clock, hosts, iat, selector, fault) + } +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StartStopHostFault.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StartStopHostFault.kt new file mode 100644 index 00000000..fc7cebfc --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StartStopHostFault.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.failure + +import kotlinx.coroutines.delay +import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.simulator.SimHost +import java.time.Clock +import kotlin.math.roundToLong + +/** + * A type of [HostFault] where the hosts are stopped and recover after some random amount of time. + */ +public class StartStopHostFault(private val duration: RealDistribution) : HostFault { + override suspend fun apply(clock: Clock, victims: List) { + for (host in victims) { + host.fail() + } + + val df = (duration.sample() * 1000).roundToLong() // seconds to milliseconds + + // Handle long overflow + if (clock.millis() + df <= 0) { + return + } + + delay(df) + + for (host in victims) { + host.recover() + } + } + + override fun toString(): String = "StartStopHostFault[$duration]" +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt new file mode 100644 index 00000000..87903623 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.failure + +import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.simulator.SimHost +import kotlin.math.roundToInt +import kotlin.random.Random + +/** + * A [VictimSelector] that stochastically selects a set of hosts to be failed. + */ +public class StochasticVictimSelector( + private val size: RealDistribution, + private val random: Random = Random(0) +) : VictimSelector { + + override fun select(hosts: Set): List { + val n = size.sample().roundToInt() + return hosts.shuffled(random).take(n) + } + + override fun toString(): String = "StochasticVictimSelector[$size]" +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/VictimSelector.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/VictimSelector.kt new file mode 100644 index 00000000..b5610284 --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/VictimSelector.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.failure + +import org.opendc.compute.simulator.SimHost + +/** + * Interface responsible for selecting the victim(s) for fault injection. + */ +public interface VictimSelector { + /** + * Select the hosts from [hosts] where a fault will be injected. + */ + public fun select(hosts: Set): List +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt new file mode 100644 index 00000000..6919b7fd --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.internal + +import kotlinx.coroutines.* +import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.simulator.SimHost +import org.opendc.compute.simulator.failure.HostFault +import org.opendc.compute.simulator.failure.HostFaultInjector +import org.opendc.compute.simulator.failure.VictimSelector +import java.time.Clock +import kotlin.coroutines.CoroutineContext +import kotlin.math.roundToLong + +/** + * Internal implementation of the [HostFaultInjector] interface. + * + * @param context The scope to run the fault injector in. + * @param clock The [Clock] to keep track of simulation time. + * @param hosts The set of hosts to inject faults into. + * @param iat The inter-arrival time distribution of the failures (in hours). + * @param selector The [VictimSelector] to select the host victims. + * @param fault The type of [HostFault] to inject. + */ +internal class HostFaultInjectorImpl( + private val context: CoroutineContext, + private val clock: Clock, + private val hosts: Set, + private val iat: RealDistribution, + private val selector: VictimSelector, + private val fault: HostFault +) : HostFaultInjector { + /** + * The scope in which the injector runs. + */ + private val scope = CoroutineScope(context + Job()) + + /** + * The [Job] that awaits the nearest fault in the system. + */ + private var job: Job? = null + + /** + * Start the fault injection into the system. + */ + override fun start() { + if (job != null) { + return + } + + job = scope.launch { + runInjector() + job = null + } + } + + /** + * Run the injection process. + */ + private suspend fun runInjector() { + while (true) { + // Make sure to convert delay from hours to milliseconds + val d = (iat.sample() * 3.6e6).roundToLong() + + // Handle long overflow + if (clock.millis() + d <= 0) { + return + } + + delay(d) + + val victims = selector.select(hosts) + fault.apply(clock, victims) + } + } + + /** + * Stop the fault injector. + */ + public override fun close() { + scope.cancel() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index b2330af0..036d0638 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -35,7 +35,6 @@ dependencies { implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) - implementation(projects.opendcSimulator.opendcSimulatorFailures) implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTelemetry.opendcTelemetrySdk) implementation(projects.opendcTelemetry.opendcTelemetryCompute) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 512b754d..8227bca9 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -25,7 +25,6 @@ package org.opendc.experiments.capelin import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel import org.apache.commons.math3.distribution.LogNormalDistribution import org.apache.commons.math3.random.Well19937c import org.opendc.compute.api.* @@ -41,6 +40,9 @@ import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher import org.opendc.compute.service.scheduler.weights.RamWeigher import org.opendc.compute.service.scheduler.weights.VCpuWeigher import org.opendc.compute.simulator.SimHost +import org.opendc.compute.simulator.failure.HostFaultInjector +import org.opendc.compute.simulator.failure.StartStopHostFault +import org.opendc.compute.simulator.failure.StochasticVictimSelector import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.trace.TraceReader import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider @@ -48,67 +50,36 @@ import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.failures.CorrelatedFaultInjector -import org.opendc.simulator.failures.FaultInjector import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.sdk.toOtelClock import java.time.Clock +import kotlin.coroutines.CoroutineContext import kotlin.math.ln import kotlin.math.max import kotlin.random.Random -/** - * Construct the failure domain for the experiments. - */ -fun createFailureDomain( - coroutineScope: CoroutineScope, - clock: Clock, - seed: Int, - failureInterval: Double, - service: ComputeService, - chan: Channel -): CoroutineScope { - val job = coroutineScope.launch { - chan.receive() - val random = Random(seed) - val injectors = mutableMapOf() - for (host in service.hosts) { - val cluster = host.meta["cluster"] as String - val injector = - injectors.getOrPut(cluster) { - createFaultInjector( - this, - clock, - random, - failureInterval - ) - } - injector.enqueue(host as SimHost) - } - } - return CoroutineScope(coroutineScope.coroutineContext + job) -} - /** * Obtain the [FaultInjector] to use for the experiments. */ fun createFaultInjector( - coroutineScope: CoroutineScope, + context: CoroutineContext, clock: Clock, - random: Random, + hosts: Set, + seed: Int, failureInterval: Double -): FaultInjector { - val rng = Well19937c(random.nextLong()) +): HostFaultInjector { + val rng = Well19937c(seed) // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 // GRID'5000 - return CorrelatedFaultInjector( - coroutineScope, + return HostFaultInjector( + context, clock, + hosts, iat = LogNormalDistribution(rng, ln(failureInterval), 1.03), - size = LogNormalDistribution(rng, 1.88, 1.25), - duration = LogNormalDistribution(rng, 8.89, 2.71) + selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), + fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) ) } @@ -164,7 +135,6 @@ suspend fun processTrace( clock: Clock, reader: TraceReader, scheduler: ComputeService, - chan: Channel, monitor: ComputeMonitor? = null, ) { val client = scheduler.newClient() @@ -193,10 +163,9 @@ suspend fun processTrace( delay(max(0, (entry.start - offset) - clock.millis())) launch { - chan.send(Unit) - val workloadOffset = -offset + 300001 val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) + val server = client.newServer( entry.name, image, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 4db04591..82794471 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -25,9 +25,8 @@ package org.opendc.experiments.capelin import com.typesafe.config.ConfigFactory import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.cancel -import kotlinx.coroutines.channels.Channel import mu.KotlinLogging +import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.export.parquet.ParquetExportMonitor import org.opendc.experiments.capelin.model.CompositeWorkload @@ -103,7 +102,6 @@ abstract class Portfolio(name: String) : Experiment(name) { val seeder = Random(repeat.toLong()) val environment = ClusterEnvironmentReader(File(config.getString("env-path"), "${topology.name}.txt")) - val chan = Channel(Channel.CONFLATED) val allocationPolicy = createComputeScheduler(allocationPolicy, seeder.asKotlinRandom(), vmPlacements) val meterProvider = createMeterProvider(clock) @@ -137,31 +135,30 @@ abstract class Portfolio(name: String) : Experiment(name) { ) withComputeService(clock, meterProvider, environment, allocationPolicy, performanceInterferenceModel) { scheduler -> - val failureDomain = if (operationalPhenomena.failureFrequency > 0) { + val faultInjector = if (operationalPhenomena.failureFrequency > 0) { logger.debug("ENABLING failures") - createFailureDomain( - this, + createFaultInjector( + coroutineContext, clock, + scheduler.hosts.map { it as SimHost }.toSet(), seeder.nextInt(), operationalPhenomena.failureFrequency, - scheduler, - chan ) } else { null } withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { + faultInjector?.start() processTrace( clock, trace, scheduler, - chan, monitor ) } - failureDomain?.cancel() + faultInjector?.close() monitor.close() } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index ab33bc25..44cf92a8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -23,8 +23,6 @@ package org.opendc.experiments.capelin import io.opentelemetry.sdk.metrics.export.MetricProducer -import kotlinx.coroutines.cancel -import kotlinx.coroutines.channels.Channel import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -34,6 +32,7 @@ import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.filters.RamFilter import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload @@ -73,9 +72,6 @@ class CapelinIntegrationTest { */ @Test fun testLarge() = runBlockingSimulation { - val failures = false - val seed = 0 - val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) @@ -85,31 +81,14 @@ class CapelinIntegrationTest { val meterProvider = createMeterProvider(clock) withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> - val failureDomain = if (failures) { - println("ENABLING failures") - createFailureDomain( - this, - clock, - seed, - 24.0 * 7, - scheduler, - chan - ) - } else { - null - } - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { processTrace( clock, traceReader, scheduler, - chan, monitor ) } - - failureDomain?.cancel() } val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) @@ -141,7 +120,6 @@ class CapelinIntegrationTest { @Test fun testSmall() = runBlockingSimulation { val seed = 1 - val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) @@ -157,7 +135,6 @@ class CapelinIntegrationTest { clock, traceReader, scheduler, - chan, monitor ) } @@ -187,7 +164,6 @@ class CapelinIntegrationTest { @Test fun testInterference() = runBlockingSimulation { val seed = 1 - val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) @@ -209,7 +185,6 @@ class CapelinIntegrationTest { clock, traceReader, scheduler, - chan, monitor ) } @@ -239,7 +214,6 @@ class CapelinIntegrationTest { @Test fun testFailures() = runBlockingSimulation { val seed = 1 - val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) @@ -250,27 +224,26 @@ class CapelinIntegrationTest { val meterProvider = createMeterProvider(clock) withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> - val failureDomain = - createFailureDomain( - this, + val faultInjector = + createFaultInjector( + coroutineContext, clock, + scheduler.hosts.map { it as SimHost }.toSet(), seed, 24.0 * 7, - scheduler, - chan ) withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { + faultInjector.start() processTrace( clock, traceReader, scheduler, - chan, monitor ) } - failureDomain.cancel() + faultInjector.close() } val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) diff --git a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts index 40ac2967..cc58e5f1 100644 --- a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts @@ -33,7 +33,6 @@ dependencies { api(projects.opendcHarness.opendcHarnessApi) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) - implementation(projects.opendcSimulator.opendcSimulatorFailures) implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcExperiments.opendcExperimentsCapelin) implementation(projects.opendcTelemetry.opendcTelemetrySdk) diff --git a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt index 02aaab3c..d9194969 100644 --- a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt +++ b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt @@ -26,7 +26,6 @@ import com.typesafe.config.ConfigFactory import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope import mu.KotlinLogging import org.opendc.compute.service.ComputeService @@ -81,7 +80,6 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { private val powerModel by anyOf(PowerModelType.LINEAR, PowerModelType.CUBIC, PowerModelType.INTERPOLATION) override fun doRun(repeat: Int): Unit = runBlockingSimulation { - val chan = Channel(Channel.CONFLATED) val allocationPolicy = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), weighers = listOf(), @@ -98,7 +96,6 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { clock, trace, scheduler, - chan, monitor ) } diff --git a/opendc-experiments/opendc-experiments-radice/build.gradle.kts b/opendc-experiments/opendc-experiments-radice/build.gradle.kts index c1515165..0c716183 100644 --- a/opendc-experiments/opendc-experiments-radice/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-radice/build.gradle.kts @@ -34,7 +34,6 @@ dependencies { implementation(projects.opendcFormat) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) - implementation(projects.opendcSimulator.opendcSimulatorFailures) implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTelemetry.opendcTelemetrySdk) diff --git a/opendc-simulator/opendc-simulator-failures/build.gradle.kts b/opendc-simulator/opendc-simulator-failures/build.gradle.kts deleted file mode 100644 index edd48b40..00000000 --- a/opendc-simulator/opendc-simulator-failures/build.gradle.kts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -description = "Failure models for OpenDC" - -plugins { - `kotlin-library-conventions` -} - -dependencies { - api(platform(projects.opendcPlatform)) - api(libs.kotlinx.coroutines) - api(libs.commons.math3) -} diff --git a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt deleted file mode 100644 index c3b85666..00000000 --- a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/CorrelatedFaultInjector.kt +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.failures - -import kotlinx.coroutines.* -import org.apache.commons.math3.distribution.RealDistribution -import java.time.Clock -import java.util.* -import kotlin.math.roundToInt -import kotlin.math.roundToLong - -/** - * A [FaultInjector] that injects fault in the system which are correlated to each other. Failures do not occur in - * isolation, but will trigger other faults. - * - * @param scope The scope to run the fault injector in. - * @param clock The [Clock] to keep track of simulation time. - * @param iat The inter-arrival time distribution of the failures (in hours). - * @param size The failure group size distribution. - * @param duration The failure duration (in seconds). - */ -public class CorrelatedFaultInjector( - private val scope: CoroutineScope, - private val clock: Clock, - private val iat: RealDistribution, - private val size: RealDistribution, - private val duration: RealDistribution, - private val random: Random = Random(0) -) : FaultInjector { - /** - * The active failure domains that have been registered. - */ - private val active = mutableSetOf() - - /** - * The [Job] that awaits the nearest fault in the system. - */ - private var job: Job? = null - - /** - * Enqueue the specified [FailureDomain] to fail some time in the future. - */ - override fun enqueue(domain: FailureDomain) { - active += domain - - // Clean up the domain if it finishes - domain.scope.coroutineContext[Job]!!.invokeOnCompletion { - this@CorrelatedFaultInjector.scope.launch { - active -= domain - - if (active.isEmpty()) { - job?.cancel() - job = null - } - } - } - - if (job != null) { - return - } - - job = this.scope.launch { - while (active.isNotEmpty()) { - ensureActive() - - // Make sure to convert delay from hours to milliseconds - val d = (iat.sample() * 3.6e6).roundToLong() - - // Handle long overflow - if (clock.millis() + d <= 0) { - return@launch - } - - delay(d) - - val n = size.sample().roundToInt() - val targets = active.shuffled(random).take(n) - - for (failureDomain in targets) { - active -= failureDomain - failureDomain.fail() - } - - val df = (duration.sample() * 1000).roundToLong() // seconds to milliseconds - - // Handle long overflow - if (clock.millis() + df <= 0) { - return@launch - } - - delay(df) - - for (failureDomain in targets) { - failureDomain.recover() - - // Re-enqueue machine to be failed - enqueue(failureDomain) - } - } - - job = null - } - } -} diff --git a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FailureDomain.kt b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FailureDomain.kt deleted file mode 100644 index dc3006e8..00000000 --- a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FailureDomain.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.failures - -import kotlinx.coroutines.CoroutineScope - -/** - * A logical or physical component in a computing environment which may fail. - */ -public interface FailureDomain { - /** - * The lifecycle of the failure domain to which a [FaultInjector] will attach. - */ - public val scope: CoroutineScope - - /** - * Fail the domain externally. - */ - public suspend fun fail() - - /** - * Resume the failure domain. - */ - public suspend fun recover() -} diff --git a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FaultInjector.kt b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FaultInjector.kt deleted file mode 100644 index a866260c..00000000 --- a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/FaultInjector.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.failures - -/** - * An interface for stochastically injecting faults into a running system. - */ -public interface FaultInjector { - /** - * Enqueue the specified [FailureDomain] into the queue as candidate for failure injection in the future. - */ - public fun enqueue(domain: FailureDomain) -} diff --git a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt b/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt deleted file mode 100644 index 8f99f758..00000000 --- a/opendc-simulator/opendc-simulator-failures/src/main/kotlin/org/opendc/simulator/failures/UncorrelatedFaultInjector.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.failures - -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.apache.commons.math3.distribution.RealDistribution -import java.time.Clock -import kotlin.math.roundToLong - -/** - * A [FaultInjector] that injects uncorrelated faults into the system, meaning that failures of the subsystems are - * independent. - * - * @param clock The [Clock] to keep track of simulation time. - * @param iat The failure inter-arrival time distribution (in hours) - * @param duration The failure duration distribution (in seconds). - */ -public class UncorrelatedFaultInjector( - private val clock: Clock, - private val iat: RealDistribution, - private val duration: RealDistribution, -) : FaultInjector { - /** - * Enqueue the specified [FailureDomain] to fail some time in the future. - */ - override fun enqueue(domain: FailureDomain) { - domain.scope.launch { - val d = (iat.sample() * 3.6e6).roundToLong() // Make sure to convert delay to milliseconds - - // Handle long overflow - if (clock.millis() + d <= 0) { - return@launch - } - - delay(d) - domain.fail() - - val df = (duration.sample() * 1000).roundToLong() // seconds to milliseconds - - // Handle long overflow - if (clock.millis() + df <= 0) { - return@launch - } - - delay(df) - domain.recover() - } - } -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 5d481270..b565e90d 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -30,8 +30,8 @@ import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel import mu.KotlinLogging +import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.* import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.env.MachineDef @@ -188,8 +188,6 @@ class RunnerCli : CliktCommand(name = "runner") { val seeder = Random(seed) - val chan = Channel(Channel.CONFLATED) - val meterProvider: MeterProvider = SdkMeterProvider .builder() .setClock(clock.toOtelClock()) @@ -207,31 +205,31 @@ class RunnerCli : CliktCommand(name = "runner") { val failureFrequency = if (operational.failuresEnabled) 24.0 * 7 else 0.0 withComputeService(clock, meterProvider, environment, allocationPolicy, interferenceModel) { scheduler -> - val failureDomain = if (failureFrequency > 0) { + val faultInjector = if (failureFrequency > 0) { logger.debug { "ENABLING failures" } - createFailureDomain( - this, + createFaultInjector( + coroutineContext, clock, + scheduler.hosts.map { it as SimHost }.toSet(), seeder.nextInt(), failureFrequency, - scheduler, - chan ) } else { null } withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { + faultInjector?.start() + processTrace( clock, trace, scheduler, - chan, monitor ) - } - failureDomain?.cancel() + faultInjector?.close() + } } val monitorResults = collectServiceMetrics(clock.millis(), metricProducer) diff --git a/settings.gradle.kts b/settings.gradle.kts index cee8887b..427cdb52 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -42,7 +42,6 @@ include(":opendc-simulator:opendc-simulator-resources") include(":opendc-simulator:opendc-simulator-power") include(":opendc-simulator:opendc-simulator-network") include(":opendc-simulator:opendc-simulator-compute") -include(":opendc-simulator:opendc-simulator-failures") include(":opendc-telemetry:opendc-telemetry-api") include(":opendc-telemetry:opendc-telemetry-sdk") include(":opendc-telemetry:opendc-telemetry-compute") -- cgit v1.2.3 From 36be169ae8a159a824a2b20cc0eb0e04b569fa09 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 16:05:23 +0200 Subject: docs(compute): Clarify terminology in compute service --- .../src/main/kotlin/org/opendc/compute/api/ComputeClient.kt | 2 +- .../src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt index baa1ba2f..577fbc73 100644 --- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt +++ b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt @@ -45,7 +45,7 @@ public interface ComputeClient : AutoCloseable { * * @param name The name of the flavor. * @param cpuCount The amount of CPU cores for this flavor. - * @param memorySize The size of the memory. + * @param memorySize The size of the memory in MB. * @param labels The identifying labels of the image. * @param meta The non-identifying meta-data of the image. */ diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt index 5632a55e..fc092a3f 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt @@ -25,7 +25,7 @@ package org.opendc.compute.service.driver /** * Describes the static machine properties of the host. * - * @property vcpuCount The number of logical processing cores available for this host. + * @property cpuCount The number of logical processing cores available for this host. * @property memorySize The amount of memory available for this host in MB. */ public data class HostModel(public val cpuCount: Int, public val memorySize: Long) -- cgit v1.2.3 From f142be8c2afd1f19bdec183f1169639b7cd1a472 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 16:54:46 +0200 Subject: test(compute): Add test suite for fault injector --- .../simulator/failure/HostFaultInjectorTest.kt | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt new file mode 100644 index 00000000..f240a25f --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.failure + +import io.mockk.coVerify +import io.mockk.mockk +import kotlinx.coroutines.delay +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.random.Well19937c +import org.junit.jupiter.api.Test +import org.opendc.compute.simulator.SimHost +import org.opendc.simulator.core.runBlockingSimulation +import java.time.Clock +import java.time.Duration +import kotlin.coroutines.CoroutineContext +import kotlin.math.ln + +/** + * Test suite for [HostFaultInjector] class. + */ +internal class HostFaultInjectorTest { + /** + * Simple test case to test that nothing happens when the injector is not started. + */ + @Test + fun testInjectorNotStarted() = runBlockingSimulation { + val host = mockk(relaxUnitFun = true) + + val injector = createSimpleInjector(coroutineContext, clock, setOf(host)) + + coVerify(exactly = 0) { host.fail() } + coVerify(exactly = 0) { host.recover() } + + injector.close() + } + + /** + * Simple test case to test a start stop fault where the machine is stopped and started after some time. + */ + @Test + fun testInjectorStopsMachine() = runBlockingSimulation { + val host = mockk(relaxUnitFun = true) + + val injector = createSimpleInjector(coroutineContext, clock, setOf(host)) + + injector.start() + + delay(Duration.ofDays(55).toMillis()) + + injector.close() + + coVerify(exactly = 1) { host.fail() } + coVerify(exactly = 1) { host.recover() } + } + + /** + * Simple test case to test a start stop fault where multiple machines are stopped. + */ + @Test + fun testInjectorStopsMultipleMachines() = runBlockingSimulation { + val hosts = listOf( + mockk(relaxUnitFun = true), + mockk(relaxUnitFun = true) + ) + + val injector = createSimpleInjector(coroutineContext, clock, hosts.toSet()) + + injector.start() + + delay(Duration.ofDays(55).toMillis()) + + injector.close() + + coVerify(exactly = 1) { hosts[0].fail() } + coVerify(exactly = 1) { hosts[1].fail() } + coVerify(exactly = 1) { hosts[0].recover() } + coVerify(exactly = 1) { hosts[1].recover() } + } + + /** + * Create a simple start stop fault injector. + */ + private fun createSimpleInjector(context: CoroutineContext, clock: Clock, hosts: Set): HostFaultInjector { + val rng = Well19937c(0) + val iat = LogNormalDistribution(rng, ln(24 * 7.0), 1.03) + val selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25)) + val fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) + + return HostFaultInjector(context, clock, hosts, iat, selector, fault) + } +} -- cgit v1.2.3 From 83497bd122983c7fc0d5cbbdc80b98d58c50cd75 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 16:06:53 +0200 Subject: feat(trace): Support Materna traces from GWA This change adds support for the Materna traces from the Grid Workload Trace Archive (GWA). These traces are very similar to the Bitbrains traces, so they share the same base implementation. --- .../trace/bitbrains/BitbrainsResourceStateTable.kt | 1 + .../bitbrains/BitbrainsResourceStateTableReader.kt | 192 ++++++++++++++------- 2 files changed, 129 insertions(+), 64 deletions(-) diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index 767ef919..846d5c8a 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -41,6 +41,7 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, priv Files.walk(path, 1) .filter { !Files.isDirectory(it) && it.extension == "csv" } .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() override val name: String = TABLE_RESOURCE_STATES diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt index 5687ac7f..dab784c2 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt @@ -22,20 +22,42 @@ package org.opendc.trace.bitbrains +import com.fasterxml.jackson.core.JsonParseException import com.fasterxml.jackson.core.JsonToken import com.fasterxml.jackson.dataformat.csv.CsvParser import com.fasterxml.jackson.dataformat.csv.CsvSchema import org.opendc.trace.* +import java.text.NumberFormat import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter +import java.time.format.DateTimeParseException +import java.util.* /** * A [TableReader] for the Bitbrains resource state table. */ internal class BitbrainsResourceStateTableReader(private val partition: String, private val parser: CsvParser) : TableReader { /** - * The current parser state. + * The [DateTimeFormatter] used to parse the timestamps in case of the Materna trace. */ - private val state = RowState() + private val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss") + + /** + * The type of timestamps in the trace. + */ + private var timestampType: TimestampType = TimestampType.UNDECIDED + + /** + * The [NumberFormat] used to parse doubles containing a comma. + */ + private val nf = NumberFormat.getInstance(Locale.GERMAN) + + /** + * A flag to indicate that the trace contains decimals with a comma separator. + */ + private var usesCommaDecimalSeparator = false init { parser.schema = schema @@ -43,7 +65,7 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun nextRow(): Boolean { // Reset the row state - state.reset() + reset() if (!nextStart()) { return false @@ -57,17 +79,32 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, } when (parser.currentName) { - "Timestamp [ms]" -> state.timestamp = Instant.ofEpochSecond(parser.longValue) - "CPU cores" -> state.cpuCores = parser.intValue - "CPU capacity provisioned [MHZ]" -> state.cpuCapacity = parser.doubleValue - "CPU usage [MHZ]" -> state.cpuUsage = parser.doubleValue - "CPU usage [%]" -> state.cpuUsagePct = parser.doubleValue - "Memory capacity provisioned [KB]" -> state.memCapacity = parser.doubleValue - "Memory usage [KB]" -> state.memUsage = parser.doubleValue - "Disk read throughput [KB/s]" -> state.diskRead = parser.doubleValue - "Disk write throughput [KB/s]" -> state.diskWrite = parser.doubleValue - "Network received throughput [KB/s]" -> state.netReceived = parser.doubleValue - "Network transmitted throughput [KB/s]" -> state.netTransmitted = parser.doubleValue + "Timestamp [ms]" -> { + timestamp = when (timestampType) { + TimestampType.UNDECIDED -> { + try { + val res = LocalDateTime.parse(parser.text, formatter).toInstant(ZoneOffset.UTC) + timestampType = TimestampType.DATE_TIME + res + } catch (e: DateTimeParseException) { + timestampType = TimestampType.EPOCH_MILLIS + Instant.ofEpochSecond(parser.longValue) + } + } + TimestampType.DATE_TIME -> LocalDateTime.parse(parser.text, formatter).toInstant(ZoneOffset.UTC) + TimestampType.EPOCH_MILLIS -> Instant.ofEpochSecond(parser.longValue) + } + } + "CPU cores" -> cpuCores = parser.intValue + "CPU capacity provisioned [MHZ]" -> cpuCapacity = parseSafeDouble() + "CPU usage [MHZ]" -> cpuUsage = parseSafeDouble() + "CPU usage [%]" -> cpuUsagePct = parseSafeDouble() / 100.0 // Convert to range [0, 1] + "Memory capacity provisioned [KB]" -> memCapacity = parseSafeDouble() + "Memory usage [KB]" -> memUsage = parseSafeDouble() + "Disk read throughput [KB/s]" -> diskRead = parseSafeDouble() + "Disk write throughput [KB/s]" -> diskWrite = parseSafeDouble() + "Network received throughput [KB/s]" -> netReceived = parseSafeDouble() + "Network transmitted throughput [KB/s]" -> netTransmitted = parseSafeDouble() } } @@ -95,17 +132,17 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun get(column: TableColumn): T { val res: Any? = when (column) { RESOURCE_STATE_ID -> partition - RESOURCE_STATE_TIMESTAMP -> state.timestamp - RESOURCE_STATE_NCPUS -> state.cpuCores - RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity - RESOURCE_STATE_CPU_USAGE -> state.cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsagePct - RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity - RESOURCE_STATE_MEM_USAGE -> state.memUsage - RESOURCE_STATE_DISK_READ -> state.diskRead - RESOURCE_STATE_DISK_WRITE -> state.diskWrite - RESOURCE_STATE_NET_RX -> state.netReceived - RESOURCE_STATE_NET_TX -> state.netTransmitted + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_NCPUS -> cpuCores + RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_STATE_CPU_USAGE -> cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_STATE_MEM_USAGE -> memUsage + RESOURCE_STATE_DISK_READ -> diskRead + RESOURCE_STATE_DISK_WRITE -> diskWrite + RESOURCE_STATE_NET_RX -> netReceived + RESOURCE_STATE_NET_TX -> netTransmitted else -> throw IllegalArgumentException("Invalid column") } @@ -119,7 +156,7 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_STATE_NCPUS -> state.cpuCores + RESOURCE_STATE_NCPUS -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } @@ -130,15 +167,15 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun getDouble(column: TableColumn): Double { return when (column) { - RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity - RESOURCE_STATE_CPU_USAGE -> state.cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsagePct - RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity - RESOURCE_STATE_MEM_USAGE -> state.memUsage - RESOURCE_STATE_DISK_READ -> state.diskRead - RESOURCE_STATE_DISK_WRITE -> state.diskWrite - RESOURCE_STATE_NET_RX -> state.netReceived - RESOURCE_STATE_NET_TX -> state.netTransmitted + RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_STATE_CPU_USAGE -> cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_STATE_MEM_USAGE -> memUsage + RESOURCE_STATE_DISK_READ -> diskRead + RESOURCE_STATE_DISK_WRITE -> diskWrite + RESOURCE_STATE_NET_RX -> netReceived + RESOURCE_STATE_NET_TX -> netTransmitted else -> throw IllegalArgumentException("Invalid column") } } @@ -161,37 +198,62 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, } /** - * The current row state. + * Try to parse the current value safely as double. */ - private class RowState { - var timestamp: Instant? = null - var cpuCores = -1 - var cpuCapacity = Double.NaN - var cpuUsage = Double.NaN - var cpuUsagePct = Double.NaN - var memCapacity = Double.NaN - var memUsage = Double.NaN - var diskRead = Double.NaN - var diskWrite = Double.NaN - var netReceived = Double.NaN - var netTransmitted = Double.NaN + private fun parseSafeDouble(): Double { + if (!usesCommaDecimalSeparator) { + try { + return parser.doubleValue + } catch (e: JsonParseException) { + usesCommaDecimalSeparator = true + } + } - /** - * Reset the state. - */ - fun reset() { - timestamp = null - cpuCores = -1 - cpuCapacity = Double.NaN - cpuUsage = Double.NaN - cpuUsagePct = Double.NaN - memCapacity = Double.NaN - memUsage = Double.NaN - diskRead = Double.NaN - diskWrite = Double.NaN - netReceived = Double.NaN - netTransmitted = Double.NaN + val text = parser.text + if (text.isBlank()) { + return 0.0 } + + return nf.parse(text).toDouble() + } + + /** + * State fields of the reader. + */ + private var timestamp: Instant? = null + private var cpuCores = -1 + private var cpuCapacity = Double.NaN + private var cpuUsage = Double.NaN + private var cpuUsagePct = Double.NaN + private var memCapacity = Double.NaN + private var memUsage = Double.NaN + private var diskRead = Double.NaN + private var diskWrite = Double.NaN + private var netReceived = Double.NaN + private var netTransmitted = Double.NaN + + /** + * Reset the state. + */ + private fun reset() { + timestamp = null + cpuCores = -1 + cpuCapacity = Double.NaN + cpuUsage = Double.NaN + cpuUsagePct = Double.NaN + memCapacity = Double.NaN + memUsage = Double.NaN + diskRead = Double.NaN + diskWrite = Double.NaN + netReceived = Double.NaN + netTransmitted = Double.NaN + } + + /** + * The type of the timestamp in the trace. + */ + private enum class TimestampType { + UNDECIDED, DATE_TIME, EPOCH_MILLIS } companion object { @@ -199,15 +261,17 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, * The [CsvSchema] that is used to parse the trace. */ private val schema = CsvSchema.builder() - .addColumn("Timestamp [ms]", CsvSchema.ColumnType.NUMBER) + .addColumn("Timestamp [ms]", CsvSchema.ColumnType.NUMBER_OR_STRING) .addColumn("CPU cores", CsvSchema.ColumnType.NUMBER) .addColumn("CPU capacity provisioned [MHZ]", CsvSchema.ColumnType.NUMBER) .addColumn("CPU usage [MHZ]", CsvSchema.ColumnType.NUMBER) .addColumn("CPU usage [%]", CsvSchema.ColumnType.NUMBER) .addColumn("Memory capacity provisioned [KB]", CsvSchema.ColumnType.NUMBER) .addColumn("Memory usage [KB]", CsvSchema.ColumnType.NUMBER) + .addColumn("Memory usage [%]", CsvSchema.ColumnType.NUMBER) .addColumn("Disk read throughput [KB/s]", CsvSchema.ColumnType.NUMBER) .addColumn("Disk write throughput [KB/s]", CsvSchema.ColumnType.NUMBER) + .addColumn("Disk size [GB]", CsvSchema.ColumnType.NUMBER) .addColumn("Network received throughput [KB/s]", CsvSchema.ColumnType.NUMBER) .addColumn("Network transmitted throughput [KB/s]", CsvSchema.ColumnType.NUMBER) .setAllowComments(true) -- cgit v1.2.3 From fa08b63bd749e9fbe1a1d04ef2ebd7a86453fa4b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sat, 11 Sep 2021 10:52:30 +0200 Subject: perf(trace): Keep reader state in own class This change removes the external class that holds the state of the reader and instead puts the state in the reader implementation. Maintaining a separate class for the state increases the complexity and has worse performance characteristics due to the bytecode produced by Kotlin for property accesses. --- .../capelin/trace/RawParquetTraceReader.kt | 4 +- .../capelin/trace/bp/BPResourceTable.kt | 2 +- .../capelin/trace/bp/BPResourceTableReader.kt | 10 +- .../capelin/trace/sv/SvResourceStateTable.kt | 5 +- .../capelin/trace/sv/SvResourceStateTableReader.kt | 142 +++++++++------------ .../kotlin/org/opendc/trace/ResourceColumns.kt | 4 +- .../org/opendc/trace/gwf/GwfTaskTableReader.kt | 85 ++++++------ .../main/kotlin/org/opendc/trace/wtf/WtfTrace.kt | 2 +- 8 files changed, 115 insertions(+), 139 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt index fa4e9ed8..ca937328 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt @@ -90,9 +90,9 @@ class RawParquetTraceReader(private val path: File) { } val submissionTime = reader.get(RESOURCE_START_TIME) - val endTime = reader.get(RESOURCE_END_TIME) + val endTime = reader.get(RESOURCE_STOP_TIME) val maxCores = reader.getInt(RESOURCE_NCPUS) - val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) + val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) val vmFragments = fragments.getValue(id).asSequence() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt index 74d1e574..bff8c55e 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt @@ -38,7 +38,7 @@ internal class BPResourceTable(private val path: Path) : Table { return when (column) { RESOURCE_ID -> true RESOURCE_START_TIME -> true - RESOURCE_END_TIME -> true + RESOURCE_STOP_TIME -> true RESOURCE_NCPUS -> true RESOURCE_MEM_CAPACITY -> true else -> false diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt index 0a105783..4416aae8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt @@ -45,7 +45,7 @@ internal class BPResourceTableReader(private val reader: LocalParquetReader true RESOURCE_START_TIME -> true - RESOURCE_END_TIME -> true + RESOURCE_STOP_TIME -> true RESOURCE_NCPUS -> true RESOURCE_MEM_CAPACITY -> true else -> false @@ -59,9 +59,9 @@ internal class BPResourceTableReader(private val reader: LocalParquetReader record["id"].toString() RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) - RESOURCE_END_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) - RESOURCE_NCPUS -> record["maxCores"] - RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() + RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) + RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) else -> throw IllegalArgumentException("Invalid column") } @@ -90,7 +90,7 @@ internal class BPResourceTableReader(private val reader: LocalParquetReader (record["requiredMemory"] as Number).toDouble() + RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() * 1000.0 // MB to KB else -> throw IllegalArgumentException("Invalid column") } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt index 24abb109..3a9bda69 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt @@ -31,7 +31,7 @@ import kotlin.io.path.extension import kotlin.io.path.nameWithoutExtension /** - * The resource state [Table] in the Bitbrains format. + * The resource state [Table] in the extended Bitbrains format. */ internal class SvResourceStateTable(path: Path) : Table { /** @@ -40,6 +40,7 @@ internal class SvResourceStateTable(path: Path) : Table { private val partitions = Files.walk(path, 1) .filter { !Files.isDirectory(it) && it.extension == "txt" } .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() override val name: String = TABLE_RESOURCE_STATES @@ -126,7 +127,7 @@ internal class SvResourceStateTable(path: Path) : Table { } } - override fun toString(): String = "BitbrainsCompositeTableReader" + override fun toString(): String = "SvCompositeTableReader" } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt index 1a556f8d..a7d2d70a 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt @@ -30,13 +30,8 @@ import java.time.Instant * A [TableReader] for the Bitbrains resource state table. */ internal class SvResourceStateTableReader(private val reader: BufferedReader) : TableReader { - /** - * The current parser state. - */ - private val state = RowState() - override fun nextRow(): Boolean { - state.reset() + reset() var line: String var num = 0 @@ -75,18 +70,18 @@ internal class SvResourceStateTableReader(private val reader: BufferedReader) : val field = line.subSequence(start, end) as String when (col++) { - COL_TIMESTAMP -> state.timestamp = Instant.ofEpochSecond(field.toLong(10)) - COL_CPU_USAGE -> state.cpuUsage = field.toDouble() - COL_CPU_DEMAND -> state.cpuDemand = field.toDouble() - COL_DISK_READ -> state.diskRead = field.toDouble() - COL_DISK_WRITE -> state.diskWrite = field.toDouble() - COL_CLUSTER_ID -> state.cluster = field.trim() - COL_NCPUS -> state.cpuCores = field.toInt(10) - COL_CPU_READY_PCT -> state.cpuReadyPct = field.toDouble() - COL_POWERED_ON -> state.poweredOn = field.toInt(10) == 1 - COL_CPU_CAPACITY -> state.cpuCapacity = field.toDouble() - COL_ID -> state.id = field.trim() - COL_MEM_CAPACITY -> state.memCapacity = field.toDouble() + COL_TIMESTAMP -> timestamp = Instant.ofEpochSecond(field.toLong(10)) + COL_CPU_USAGE -> cpuUsage = field.toDouble() + COL_CPU_DEMAND -> cpuDemand = field.toDouble() + COL_DISK_READ -> diskRead = field.toDouble() + COL_DISK_WRITE -> diskWrite = field.toDouble() + COL_CLUSTER_ID -> cluster = field.trim() + COL_NCPUS -> cpuCores = field.toInt(10) + COL_CPU_READY_PCT -> cpuReadyPct = field.toDouble() + COL_POWERED_ON -> poweredOn = field.toInt(10) == 1 + COL_CPU_CAPACITY -> cpuCapacity = field.toDouble() + COL_ID -> id = field.trim() + COL_MEM_CAPACITY -> memCapacity = field.toDouble() } } @@ -113,16 +108,16 @@ internal class SvResourceStateTableReader(private val reader: BufferedReader) : override fun get(column: TableColumn): T { val res: Any? = when (column) { - RESOURCE_STATE_ID -> state.id - RESOURCE_STATE_CLUSTER_ID -> state.cluster - RESOURCE_STATE_TIMESTAMP -> state.timestamp - RESOURCE_STATE_NCPUS -> state.cpuCores - RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity - RESOURCE_STATE_CPU_USAGE -> state.cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsage / state.cpuCapacity - RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity - RESOURCE_STATE_DISK_READ -> state.diskRead - RESOURCE_STATE_DISK_WRITE -> state.diskWrite + RESOURCE_STATE_ID -> id + RESOURCE_STATE_CLUSTER_ID -> cluster + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) + RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) + RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) + RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) + RESOURCE_STATE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) + RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) + RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) else -> throw IllegalArgumentException("Invalid column") } @@ -132,14 +127,14 @@ internal class SvResourceStateTableReader(private val reader: BufferedReader) : override fun getBoolean(column: TableColumn): Boolean { return when (column) { - RESOURCE_STATE_POWERED_ON -> state.poweredOn + RESOURCE_STATE_POWERED_ON -> poweredOn else -> throw IllegalArgumentException("Invalid column") } } override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_STATE_NCPUS -> state.cpuCores + RESOURCE_STATE_NCPUS -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } @@ -150,12 +145,13 @@ internal class SvResourceStateTableReader(private val reader: BufferedReader) : override fun getDouble(column: TableColumn): Double { return when (column) { - RESOURCE_STATE_CPU_CAPACITY -> state.cpuCapacity - RESOURCE_STATE_CPU_USAGE -> state.cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> state.cpuUsage / state.cpuCapacity - RESOURCE_STATE_MEM_CAPACITY -> state.memCapacity - RESOURCE_STATE_DISK_READ -> state.diskRead - RESOURCE_STATE_DISK_WRITE -> state.diskWrite + RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_STATE_CPU_USAGE -> cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity + RESOURCE_STATE_CPU_DEMAND -> cpuDemand + RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_STATE_DISK_READ -> diskRead + RESOURCE_STATE_DISK_WRITE -> diskWrite else -> throw IllegalArgumentException("Invalid column") } } @@ -165,51 +161,37 @@ internal class SvResourceStateTableReader(private val reader: BufferedReader) : } /** - * The current row state. + * State fields of the reader. */ - private class RowState { - @JvmField - var id: String? = null - @JvmField - var cluster: String? = null - @JvmField - var timestamp: Instant? = null - @JvmField - var cpuCores = -1 - @JvmField - var cpuCapacity = Double.NaN - @JvmField - var cpuUsage = Double.NaN - @JvmField - var cpuDemand = Double.NaN - @JvmField - var cpuReadyPct = Double.NaN - @JvmField - var memCapacity = Double.NaN - @JvmField - var diskRead = Double.NaN - @JvmField - var diskWrite = Double.NaN - @JvmField - var poweredOn: Boolean = false - - /** - * Reset the state. - */ - fun reset() { - id = null - timestamp = null - cluster = null - cpuCores = -1 - cpuCapacity = Double.NaN - cpuUsage = Double.NaN - cpuDemand = Double.NaN - cpuReadyPct = Double.NaN - memCapacity = Double.NaN - diskRead = Double.NaN - diskWrite = Double.NaN - poweredOn = false - } + private var id: String? = null + private var cluster: String? = null + private var timestamp: Instant? = null + private var cpuCores = -1 + private var cpuCapacity = Double.NaN + private var cpuUsage = Double.NaN + private var cpuDemand = Double.NaN + private var cpuReadyPct = Double.NaN + private var memCapacity = Double.NaN + private var diskRead = Double.NaN + private var diskWrite = Double.NaN + private var poweredOn: Boolean = false + + /** + * Reset the state of the reader. + */ + private fun reset() { + id = null + timestamp = null + cluster = null + cpuCores = -1 + cpuCapacity = Double.NaN + cpuUsage = Double.NaN + cpuDemand = Double.NaN + cpuReadyPct = Double.NaN + memCapacity = Double.NaN + diskRead = Double.NaN + diskWrite = Double.NaN + poweredOn = false } /** diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt index 44dec95b..e2e5ea6d 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt @@ -41,7 +41,7 @@ public val RESOURCE_START_TIME: TableColumn = TableColumn("resource:sta * End time for the resource. */ @JvmField -public val RESOURCE_END_TIME: TableColumn = TableColumn("resource:end_time", Instant::class.java) +public val RESOURCE_STOP_TIME: TableColumn = TableColumn("resource:stop_time", Instant::class.java) /** * Number of CPUs for the resource. @@ -50,7 +50,7 @@ public val RESOURCE_END_TIME: TableColumn = TableColumn("resource:end_t public val RESOURCE_NCPUS: TableColumn = intColumn("resource:num_cpus") /** - * Memory capacity for the resource. + * Memory capacity for the resource in KB. */ @JvmField public val RESOURCE_MEM_CAPACITY: TableColumn = doubleColumn("resource:mem_capacity") diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt index 64b7d465..fb9099bf 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt @@ -32,18 +32,13 @@ import java.util.regex.Pattern * A [TableReader] implementation for the GWF format. */ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { - /** - * The current parser state. - */ - private val state = RowState() - init { parser.schema = schema } override fun nextRow(): Boolean { // Reset the row state - state.reset() + reset() if (!nextStart()) { return false @@ -57,12 +52,12 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { } when (parser.currentName) { - "WorkflowID" -> state.workflowId = parser.longValue - "JobID" -> state.jobId = parser.longValue - "SubmitTime" -> state.submitTime = parser.longValue - "RunTime" -> state.runtime = parser.longValue - "NProcs" -> state.nProcs = parser.intValue - "ReqNProcs" -> state.reqNProcs = parser.intValue + "WorkflowID" -> workflowId = parser.longValue + "JobID" -> jobId = parser.longValue + "SubmitTime" -> submitTime = parser.longValue + "RunTime" -> runtime = parser.longValue + "NProcs" -> nProcs = parser.intValue + "ReqNProcs" -> reqNProcs = parser.intValue "Dependencies" -> parseParents(parser.valueAsString) } } @@ -85,13 +80,13 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { override fun get(column: TableColumn): T { val res: Any = when (column) { - TASK_WORKFLOW_ID -> state.workflowId - TASK_ID -> state.jobId - TASK_SUBMIT_TIME -> state.submitTime - TASK_RUNTIME -> state.runtime - TASK_REQ_NCPUS -> state.nProcs - TASK_ALLOC_NCPUS -> state.reqNProcs - TASK_PARENTS -> state.dependencies + TASK_WORKFLOW_ID -> workflowId + TASK_ID -> jobId + TASK_SUBMIT_TIME -> submitTime + TASK_RUNTIME -> runtime + TASK_REQ_NCPUS -> nProcs + TASK_ALLOC_NCPUS -> reqNProcs + TASK_PARENTS -> dependencies else -> throw IllegalArgumentException("Invalid column") } @@ -105,18 +100,18 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { override fun getInt(column: TableColumn): Int { return when (column) { - TASK_REQ_NCPUS -> state.nProcs - TASK_ALLOC_NCPUS -> state.reqNProcs + TASK_REQ_NCPUS -> nProcs + TASK_ALLOC_NCPUS -> reqNProcs else -> throw IllegalArgumentException("Invalid column") } } override fun getLong(column: TableColumn): Long { return when (column) { - TASK_WORKFLOW_ID -> state.workflowId - TASK_ID -> state.jobId - TASK_SUBMIT_TIME -> state.submitTime - TASK_RUNTIME -> state.runtime + TASK_WORKFLOW_ID -> workflowId + TASK_ID -> jobId + TASK_SUBMIT_TIME -> submitTime + TASK_RUNTIME -> runtime else -> throw IllegalArgumentException("Invalid column") } } @@ -166,29 +161,27 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { } /** - * The current row state. + * Reader state fields. */ - private class RowState { - var workflowId = -1L - var jobId = -1L - var submitTime = -1L - var runtime = -1L - var nProcs = -1 - var reqNProcs = -1 - var dependencies = emptySet() + private var workflowId = -1L + private var jobId = -1L + private var submitTime = -1L + private var runtime = -1L + private var nProcs = -1 + private var reqNProcs = -1 + private var dependencies = emptySet() - /** - * Reset the state. - */ - fun reset() { - workflowId = -1 - jobId = -1 - submitTime = -1 - runtime = -1 - nProcs = -1 - reqNProcs = -1 - dependencies = emptySet() - } + /** + * Reset the state. + */ + private fun reset() { + workflowId = -1 + jobId = -1 + submitTime = -1 + runtime = -1 + nProcs = -1 + reqNProcs = -1 + dependencies = emptySet() } companion object { diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt index 7eff0f5a..a755a107 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt @@ -43,5 +43,5 @@ public class WtfTrace internal constructor(private val path: Path) : Trace { return WtfTaskTable(path) } - override fun toString(): String = "SwfTrace[$path]" + override fun toString(): String = "WtfTrace[$path]" } -- cgit v1.2.3 From 6489ebe975e9ba842fd7cce1b1136944728bb21d Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sat, 11 Sep 2021 10:54:38 +0200 Subject: fix(capelin): Parse last column in Solvinity trace format This change fixes an issue where the last column in the Solvinity traces is not parsed correctly, due to the last column having no whitespace at the end to seek to. --- .../opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt index a7d2d70a..6ea403fe 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt @@ -65,7 +65,7 @@ internal class SvResourceStateTableReader(private val reader: BufferedReader) : end = line.indexOf(' ', start) if (end < 0) { - break + end = length } val field = line.subSequence(start, end) as String -- cgit v1.2.3 From 9e8ea96270701e643f95b18d2b91583d9fca08d2 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sat, 11 Sep 2021 11:10:38 +0200 Subject: feat(capelin): Implement trace API for Azure VM trace format This change adds a trace API implementation for the Azure VM traces. --- .../opendc-experiments-capelin/build.gradle.kts | 1 + .../experiments/capelin/trace/TraceConverter.kt | 488 +++++++-------------- .../capelin/trace/azure/AzureResourceStateTable.kt | 130 ++++++ .../trace/azure/AzureResourceStateTableReader.kt | 149 +++++++ .../capelin/trace/azure/AzureResourceTable.kt | 57 +++ .../trace/azure/AzureResourceTableReader.kt | 169 +++++++ .../experiments/capelin/trace/azure/AzureTrace.kt | 46 ++ .../capelin/trace/azure/AzureTraceFormat.kt | 56 +++ .../opendc/experiments/capelin/trace/bp/Schemas.kt | 55 +++ 9 files changed, 822 insertions(+), 329 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 036d0638..7dadd14d 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { implementation(libs.progressbar) implementation(libs.clikt) implementation(libs.jackson.module.kotlin) + implementation(libs.jackson.dataformat.csv) implementation(kotlin("reflect")) implementation(libs.parquet) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt index a021de8d..1f3878eb 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt @@ -25,80 +25,74 @@ package org.opendc.experiments.capelin.trace import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.groups.OptionGroup -import com.github.ajalt.clikt.parameters.groups.groupChoice +import com.github.ajalt.clikt.parameters.groups.cooccurring import com.github.ajalt.clikt.parameters.options.* -import com.github.ajalt.clikt.parameters.types.file -import com.github.ajalt.clikt.parameters.types.long -import me.tongfei.progressbar.ProgressBar -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder +import com.github.ajalt.clikt.parameters.types.* +import mu.KotlinLogging import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.experiments.capelin.trace.azure.AzureTraceFormat +import org.opendc.experiments.capelin.trace.bp.BP_RESOURCES_SCHEMA +import org.opendc.experiments.capelin.trace.bp.BP_RESOURCE_STATES_SCHEMA import org.opendc.experiments.capelin.trace.sv.SvTraceFormat import org.opendc.trace.* import org.opendc.trace.bitbrains.BitbrainsTraceFormat -import org.opendc.trace.spi.TraceFormat import org.opendc.trace.util.parquet.LocalOutputFile -import java.io.BufferedReader import java.io.File -import java.io.FileReader import java.util.* import kotlin.math.max import kotlin.math.min +import kotlin.math.roundToLong + +/** + * A script to convert a trace in text format into a Parquet trace. + */ +fun main(args: Array): Unit = TraceConverterCli().main(args) /** * Represents the command for converting traces */ class TraceConverterCli : CliktCommand(name = "trace-converter") { + /** + * The logger instance for the converter. + */ + private val logger = KotlinLogging.logger {} + /** * The directory where the trace should be stored. */ - private val outputPath by option("-O", "--output", help = "path to store the trace") + private val output by option("-O", "--output", help = "path to store the trace") .file(canBeFile = false, mustExist = false) .defaultLazy { File("output") } /** * The directory where the input trace is located. */ - private val inputPath by argument("input", help = "path to the input trace") + private val input by argument("input", help = "path to the input trace") .file(canBeFile = false) /** - * The input type of the trace. + * The input format of the trace. */ - private val type by option("-t", "--type", help = "input type of trace").groupChoice( - "solvinity" to SolvinityConversion(), - "bitbrains" to BitbrainsConversion(), - "azure" to AzureConversion() - ) + private val format by option("-f", "--format", help = "input format of trace") + .choice( + "solvinity" to SvTraceFormat(), + "bitbrains" to BitbrainsTraceFormat(), + "azure" to AzureTraceFormat() + ) + .required() + + /** + * The sampling options. + */ + private val samplingOptions by SamplingOptions().cooccurring() override fun run() { - val metaSchema = SchemaBuilder - .record("meta") - .namespace("org.opendc.format.sc20") - .fields() - .name("id").type().stringType().noDefault() - .name("submissionTime").type().longType().noDefault() - .name("endTime").type().longType().noDefault() - .name("maxCores").type().intType().noDefault() - .name("requiredMemory").type().longType().noDefault() - .endRecord() - val schema = SchemaBuilder - .record("trace") - .namespace("org.opendc.format.sc20") - .fields() - .name("id").type().stringType().noDefault() - .name("time").type().longType().noDefault() - .name("duration").type().longType().noDefault() - .name("cores").type().intType().noDefault() - .name("cpuUsage").type().doubleType().noDefault() - .name("flops").type().longType().noDefault() - .endRecord() - - val metaParquet = File(outputPath, "meta.parquet") - val traceParquet = File(outputPath, "trace.parquet") + val metaParquet = File(output, "meta.parquet") + val traceParquet = File(output, "trace.parquet") if (metaParquet.exists()) { metaParquet.delete() @@ -107,324 +101,160 @@ class TraceConverterCli : CliktCommand(name = "trace-converter") { traceParquet.delete() } + val trace = format.open(input.toURI().toURL()) + + logger.info { "Building resources table" } + val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) - .withSchema(metaSchema) - .withCompressionCodec(CompressionCodecName.SNAPPY) - .withPageSize(4 * 1024 * 1024) // For compression - .withRowGroupSize(16 * 1024 * 1024) // For write buffering (Page size) + .withSchema(BP_RESOURCES_SCHEMA) + .withCompressionCodec(CompressionCodecName.ZSTD) + .enablePageWriteChecksum() .build() + val selectedVms = metaWriter.use { convertResources(trace, it) } + + logger.info { "Wrote ${selectedVms.size} rows" } + logger.info { "Building resource states table" } + val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) - .withSchema(schema) - .withCompressionCodec(CompressionCodecName.SNAPPY) - .withPageSize(4 * 1024 * 1024) // For compression - .withRowGroupSize(16 * 1024 * 1024) // For write buffering (Page size) + .withSchema(BP_RESOURCE_STATES_SCHEMA) + .withCompressionCodec(CompressionCodecName.ZSTD) + .enableDictionaryEncoding() + .enablePageWriteChecksum() + .withBloomFilterEnabled("id", true) + .withBloomFilterNDV("id", selectedVms.size.toLong()) .build() - try { - val type = type ?: throw IllegalArgumentException("Invalid trace conversion") - val allFragments = type.read(inputPath, metaSchema, metaWriter) - allFragments.sortWith(compareBy { it.tick }.thenBy { it.id }) - - for (fragment in allFragments) { - val record = GenericData.Record(schema) - record.put("id", fragment.id) - record.put("time", fragment.tick) - record.put("duration", fragment.duration) - record.put("cores", fragment.cores) - record.put("cpuUsage", fragment.usage) - record.put("flops", fragment.flops) - - writer.write(record) - } - } finally { - writer.close() - metaWriter.close() - } + val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } + logger.info { "Wrote $statesCount rows" } } -} -/** - * The supported trace conversions. - */ -sealed class TraceConversion(name: String) : OptionGroup(name) { /** - * Read the fragments of the trace. + * Convert the resources table for the trace. */ - abstract fun read( - traceDirectory: File, - metaSchema: Schema, - metaWriter: ParquetWriter - ): MutableList -} - -/** - * A [TraceConversion] that uses the Trace API to perform the conversion. - */ -abstract class AbstractConversion(name: String) : TraceConversion(name) { - abstract val format: TraceFormat - - override fun read( - traceDirectory: File, - metaSchema: Schema, - metaWriter: ParquetWriter - ): MutableList { - val fragments = mutableListOf() - val trace = format.open(traceDirectory.toURI().toURL()) + private fun convertResources(trace: Trace, writer: ParquetWriter): Set { + val random = samplingOptions?.let { Random(it.seed) } + val samplingFraction = samplingOptions?.fraction ?: 1.0 val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - var lastId: String? = null - var maxCores = Int.MIN_VALUE - var requiredMemory = Long.MIN_VALUE - var minTime = Long.MAX_VALUE - var maxTime = Long.MIN_VALUE - var lastTimestamp = Long.MIN_VALUE - - while (reader.nextRow()) { - val id = reader.get(RESOURCE_STATE_ID) - - if (lastId != null && lastId != id) { - val metaRecord = GenericData.Record(metaSchema) - metaRecord.put("id", lastId) - metaRecord.put("submissionTime", minTime) - metaRecord.put("endTime", maxTime) - metaRecord.put("maxCores", maxCores) - metaRecord.put("requiredMemory", requiredMemory) - metaWriter.write(metaRecord) - } - lastId = id + var hasNextRow = reader.nextRow() + val selectedVms = mutableSetOf() - val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP) - val timestampMs = timestamp.toEpochMilli() - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - val cores = reader.getInt(RESOURCE_STATE_NCPUS) - val memCapacity = reader.getDouble(RESOURCE_STATE_MEM_CAPACITY) + while (hasNextRow) { + var id: String + var numCpus = Int.MIN_VALUE + var memCapacity = Double.MIN_VALUE + var memUsage = Double.MIN_VALUE + var startTime = Long.MAX_VALUE + var stopTime = Long.MIN_VALUE - maxCores = max(maxCores, cores) - requiredMemory = max(requiredMemory, (memCapacity / 1000).toLong()) + do { + id = reader.get(RESOURCE_STATE_ID) - if (lastTimestamp < 0) { - lastTimestamp = timestampMs - 5 * 60 * 1000L - minTime = min(minTime, lastTimestamp) - } + val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + startTime = min(startTime, timestamp) + stopTime = max(stopTime, timestamp) + + numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_NCPUS)) - if (fragments.isEmpty()) { - val duration = 5 * 60 * 1000L - val flops: Long = (cpuUsage * duration / 1000).toLong() - fragments.add(Fragment(id, lastTimestamp, flops, duration, cpuUsage, cores)) - } else { - val last = fragments.last() - val duration = timestampMs - lastTimestamp - val flops: Long = (cpuUsage * duration / 1000).toLong() - - // Perform run-length encoding - if (last.id == id && (duration == 0L || last.usage == cpuUsage)) { - fragments[fragments.size - 1] = last.copy(duration = last.duration + duration) - } else { - fragments.add( - Fragment( - id, - lastTimestamp, - flops, - duration, - cpuUsage, - cores - ) - ) + memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) + if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { + memUsage = max(memUsage, reader.getDouble(RESOURCE_STATE_MEM_USAGE)) } + + hasNextRow = reader.nextRow() + } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) + + // Sample only a fraction of the VMs + if (random != null && random.nextDouble() > samplingFraction) { + continue } - val last = fragments.last() - maxTime = max(maxTime, last.tick + last.duration) - lastTimestamp = timestampMs + val builder = GenericRecordBuilder(BP_RESOURCES_SCHEMA) + + builder["id"] = id + builder["submissionTime"] = startTime + builder["endTime"] = stopTime + builder["maxCores"] = numCpus + builder["requiredMemory"] = max(memCapacity, memUsage).roundToLong() + + logger.info { "Selecting VM $id" } + + writer.write(builder.build()) + selectedVms.add(id) } - return fragments + + return selectedVms } -} -class SolvinityConversion : AbstractConversion("Solvinity") { - override val format: TraceFormat = SvTraceFormat() -} + /** + * Convert the resource states table for the trace. + */ + private fun convertResourceStates(trace: Trace, writer: ParquetWriter, selectedVms: Set): Int { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() -/** - * Conversion of the Bitbrains public trace. - */ -class BitbrainsConversion : AbstractConversion("Bitbrains") { - override val format: TraceFormat = BitbrainsTraceFormat() -} + var hasNextRow = reader.nextRow() + var count = 0 -/** - * Conversion of the Azure public VM trace. - */ -class AzureConversion : TraceConversion("Azure") { - private val seed by option(help = "seed for trace sampling") - .long() - .default(0) - - override fun read( - traceDirectory: File, - metaSchema: Schema, - metaWriter: ParquetWriter - ): MutableList { - val random = Random(seed) - val fraction = 0.01 - - // Read VM table - val vmIdTableCol = 0 - val coreTableCol = 9 - val provisionedMemoryTableCol = 10 - - var vmId: String - var cores: Int - var requiredMemory: Long - - val vmIds = mutableSetOf() - val vmIdToMetadata = mutableMapOf() - - BufferedReader(FileReader(File(traceDirectory, "vmtable.csv"))).use { reader -> - reader.lineSequence() - .chunked(1024) - .forEach { lines -> - for (line in lines) { - // Ignore comments in the trace - if (line.startsWith("#") || line.isBlank()) { - continue - } - // Sample only a fraction of the VMs - if (random.nextDouble() > fraction) { - continue - } - - val values = line.split(",") - - // Exclude VMs with a large number of cores (not specified exactly) - if (values[coreTableCol].contains(">")) { - continue - } - - vmId = values[vmIdTableCol].trim() - cores = values[coreTableCol].trim().toInt() - requiredMemory = values[provisionedMemoryTableCol].trim().toInt() * 1_000L // GB -> MB - - vmIds.add(vmId) - vmIdToMetadata[vmId] = VmInfo(cores, requiredMemory, Long.MAX_VALUE, -1L) - } + while (hasNextRow) { + var lastTimestamp = Long.MIN_VALUE + + do { + val id = reader.get(RESOURCE_STATE_ID) + + if (id !in selectedVms) { + hasNextRow = reader.nextRow() + continue } - } - // Read VM metric reading files - val timestampCol = 0 - val vmIdCol = 1 - val cpuUsageCol = 4 - val traceInterval = 5 * 60 * 1000L - - val vmIdToFragments = mutableMapOf>() - val vmIdToLastFragment = mutableMapOf() - val allFragments = mutableListOf() - - for (i in ProgressBar.wrap((1..195).toList(), "Reading Trace")) { - val readingsFile = File(File(traceDirectory, "readings"), "readings-$i.csv") - var timestamp: Long - var cpuUsage: Double - - BufferedReader(FileReader(readingsFile)).use { reader -> - reader.lineSequence() - .chunked(128) - .forEach { lines -> - for (line in lines) { - // Ignore comments in the trace - if (line.startsWith("#") || line.isBlank()) { - continue - } - - val values = line.split(",") - vmId = values[vmIdCol].trim() - - // Ignore readings for VMs not in the sample - if (!vmIds.contains(vmId)) { - continue - } - - timestamp = values[timestampCol].trim().toLong() * 1000L - vmIdToMetadata[vmId]!!.minTime = min(vmIdToMetadata[vmId]!!.minTime, timestamp) - cpuUsage = values[cpuUsageCol].trim().toDouble() * 3_000 // MHz - vmIdToMetadata[vmId]!!.maxTime = max(vmIdToMetadata[vmId]!!.maxTime, timestamp) - - val flops: Long = (cpuUsage * 5 * 60).toLong() - val lastFragment = vmIdToLastFragment[vmId] - - vmIdToLastFragment[vmId] = - if (lastFragment != null && lastFragment.flops == 0L && flops == 0L) { - Fragment( - vmId, - lastFragment.tick, - lastFragment.flops + flops, - lastFragment.duration + traceInterval, - cpuUsage, - vmIdToMetadata[vmId]!!.cores - ) - } else { - val fragment = - Fragment( - vmId, - timestamp, - flops, - traceInterval, - cpuUsage, - vmIdToMetadata[vmId]!!.cores - ) - if (lastFragment != null) { - if (vmIdToFragments[vmId] == null) { - vmIdToFragments[vmId] = mutableListOf() - } - vmIdToFragments[vmId]!!.add(lastFragment) - allFragments.add(lastFragment) - } - fragment - } - } - } - } - } + val builder = GenericRecordBuilder(BP_RESOURCE_STATES_SCHEMA) + builder["id"] = id - for (entry in vmIdToLastFragment) { - if (entry.value != null) { - if (vmIdToFragments[entry.key] == null) { - vmIdToFragments[entry.key] = mutableListOf() + val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + if (lastTimestamp < 0) { + lastTimestamp = timestamp - 5 * 60 * 1000L } - vmIdToFragments[entry.key]!!.add(entry.value!!) - } - } - println("Read ${vmIdToLastFragment.size} VMs") - - for (entry in vmIdToMetadata) { - val metaRecord = GenericData.Record(metaSchema) - metaRecord.put("id", entry.key) - metaRecord.put("submissionTime", entry.value.minTime) - metaRecord.put("endTime", entry.value.maxTime) - println("${entry.value.minTime} - ${entry.value.maxTime}") - metaRecord.put("maxCores", entry.value.cores) - metaRecord.put("requiredMemory", entry.value.requiredMemory) - metaWriter.write(metaRecord) - } + val duration = timestamp - lastTimestamp + val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) + val flops = (cpuUsage * duration / 1000.0).roundToLong() - return allFragments - } -} + builder["time"] = timestamp + builder["duration"] = duration + builder["cores"] = cores + builder["cpuUsage"] = cpuUsage + builder["flops"] = flops -data class Fragment( - val id: String, - val tick: Long, - val flops: Long, - val duration: Long, - val usage: Double, - val cores: Int -) + writer.write(builder.build()) -class VmInfo(val cores: Int, val requiredMemory: Long, var minTime: Long, var maxTime: Long) + lastTimestamp = timestamp + hasNextRow = reader.nextRow() + } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) -/** - * A script to convert a trace in text format into a Parquet trace. - */ -fun main(args: Array): Unit = TraceConverterCli().main(args) + count++ + } + + return count + } + + /** + * Options for sampling the workload trace. + */ + private class SamplingOptions : OptionGroup() { + /** + * The fraction of VMs to sample + */ + val fraction by option("--sampling-fraction", help = "fraction of the workload to sample") + .double() + .restrictTo(0.0001, 1.0) + .required() + + /** + * The seed for sampling the trace. + */ + val seed by option("--sampling-seed", help = "seed for sampling the workload") + .long() + .default(0) + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt new file mode 100644 index 00000000..f8e57d1d --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] for the Azure v1 VM traces. + */ +internal class AzureResourceStateTable(private val factory: CsvFactory, path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + else -> false + } + } + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (_, path) = it.next() + return AzureResourceStateTableReader(factory.createParser(path.toFile())) + } else { + null + } + } + + override fun toString(): String = "AzureCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + return AzureResourceStateTableReader(factory.createParser(path.toFile())) + } + + override fun toString(): String = "AzureResourceStateTable" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt new file mode 100644 index 00000000..f80c0e82 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.azure + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Azure v1 VM resource state table. + */ +internal class AzureResourceStateTableReader(private val parser: CsvParser) : TableReader { + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "timestamp" -> timestamp = Instant.ofEpochSecond(parser.longValue) + "vm id" -> id = parser.text + "avg cpu" -> cpuUsagePct = parser.doubleValue + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> id + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + throw IllegalArgumentException("Invalid column") + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var timestamp: Instant? = null + private var cpuUsagePct = Double.NaN + + /** + * Reset the state. + */ + private fun reset() { + id = null + timestamp = null + cpuUsagePct = Double.NaN + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("timestamp", CsvSchema.ColumnType.NUMBER) + .addColumn("vm id", CsvSchema.ColumnType.STRING) + .addColumn("CPU min cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU max cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU avg cpu", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .build() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt new file mode 100644 index 00000000..bbfd25ff --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * The resource [Table] for the Azure v1 VM traces. + */ +internal class AzureResourceTable(private val factory: CsvFactory, private val path: Path) : Table { + override val name: String = TABLE_RESOURCES + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_STOP_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun newReader(): TableReader { + return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("No partition $partition") + } + + override fun toString(): String = "AzureResourceTable" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt new file mode 100644 index 00000000..b712b854 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.azure + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.apache.parquet.example.Paper.schema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Azure v1 VM resources table. + */ +internal class AzureResourceTableReader(private val parser: CsvParser) : TableReader { + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "vm id" -> id = parser.text + "vm created" -> startTime = Instant.ofEpochSecond(parser.longValue) + "vm deleted" -> stopTime = Instant.ofEpochSecond(parser.longValue) + "vm virtual core count" -> cpuCores = parser.intValue + "vm memory" -> memCapacity = parser.doubleValue * 1e6 // GB to KB + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_STOP_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_ID -> id + RESOURCE_START_TIME -> startTime + RESOURCE_STOP_TIME -> stopTime + RESOURCE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_NCPUS -> cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_MEM_CAPACITY -> memCapacity + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var startTime: Instant? = null + private var stopTime: Instant? = null + private var cpuCores = -1 + private var memCapacity = Double.NaN + + /** + * Reset the state. + */ + fun reset() { + id = null + startTime = null + stopTime = null + cpuCores = -1 + memCapacity = Double.NaN + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("vm id", CsvSchema.ColumnType.NUMBER) + .addColumn("subscription id", CsvSchema.ColumnType.STRING) + .addColumn("deployment id", CsvSchema.ColumnType.NUMBER) + .addColumn("timestamp vm created", CsvSchema.ColumnType.NUMBER) + .addColumn("timestamp vm deleted", CsvSchema.ColumnType.NUMBER) + .addColumn("max cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("avg cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("p95 cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("vm category", CsvSchema.ColumnType.NUMBER) + .addColumn("vm virtual core count", CsvSchema.ColumnType.NUMBER) + .addColumn("vm memory", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .build() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt new file mode 100644 index 00000000..24c60bab --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the Azure v1 VM traces. + */ +class AzureTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = name in tables + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_RESOURCES -> AzureResourceTable(factory, path) + TABLE_RESOURCE_STATES -> AzureResourceStateTable(factory, path) + else -> null + } + } + + override fun toString(): String = "AzureTrace[$path]" +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt new file mode 100644 index 00000000..744e43a0 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the Azure v1 format. + */ +class AzureTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "azure-v1" + + /** + * The [CsvFactory] used to create the parser. + */ + private val factory = CsvFactory() + .enable(CsvParser.Feature.ALLOW_COMMENTS) + .enable(CsvParser.Feature.TRIM_SPACES) + + /** + * Open the trace file. + */ + override fun open(url: URL): AzureTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return AzureTrace(factory, path) + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt new file mode 100644 index 00000000..7dd8161d --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.trace.bp + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder + +/** + * Schema for the resources table in the trace. + */ +val BP_RESOURCES_SCHEMA: Schema = SchemaBuilder + .record("meta") + .namespace("org.opendc.trace.capelin") + .fields() + .requiredString("id") + .requiredLong("submissionTime") + .requiredLong("endTime") + .requiredInt("maxCores") + .requiredLong("requiredMemory") + .endRecord() + +/** + * Schema for the resource states table in the trace. + */ +val BP_RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder + .record("meta") + .namespace("org.opendc.trace.capelin") + .fields() + .requiredString("id") + .requiredLong("time") + .requiredLong("duration") + .requiredInt("cores") + .requiredDouble("cpuUsage") + .requiredLong("flops") + .endRecord() -- cgit v1.2.3 From b7be3400bb4b21d0cd7021e2baf1f6ce43aba189 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Sep 2021 22:10:22 +0200 Subject: feat(trace): Add support for WfCommons (WorkflowHub) traces This change adds support for reading WfCommons workflow traces in OpenDC. This functionality is available in the new `opendc-trace-wfformat` module. --- gradle/libs.versions.toml | 1 + .../main/kotlin/org/opendc/trace/TaskColumns.kt | 17 +- .../org/opendc/trace/gwf/GwfTaskTableReader.kt | 36 +- .../org/opendc/trace/gwf/GwfTraceFormatTest.kt | 12 +- .../org/opendc/trace/swf/SwfTaskTableReader.kt | 18 +- .../org/opendc/trace/swf/SwfTraceFormatTest.kt | 4 +- .../opendc-trace-wfformat/build.gradle.kts | 37 + .../org/opendc/trace/wfformat/WfFormatTaskTable.kt | 59 + .../trace/wfformat/WfFormatTaskTableReader.kt | 234 ++++ .../org/opendc/trace/wfformat/WfFormatTrace.kt | 47 + .../opendc/trace/wfformat/WfFormatTraceFormat.kt | 47 + .../services/org.opendc.trace.spi.TraceFormat | 1 + .../trace/wfformat/WfFormatTaskTableReaderTest.kt | 345 +++++ .../trace/wfformat/WfFormatTraceFormatTest.kt | 133 ++ .../src/test/resources/trace.json | 1342 ++++++++++++++++++++ .../org/opendc/trace/wtf/WtfTaskTableReader.kt | 27 +- .../org/opendc/trace/wtf/WtfTraceFormatTest.kt | 22 +- .../org/opendc/workflow/service/TraceReplayer.kt | 16 +- settings.gradle.kts | 1 + 19 files changed, 2319 insertions(+), 80 deletions(-) create mode 100644 opendc-trace/opendc-trace-wfformat/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt create mode 100644 opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt create mode 100644 opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt create mode 100644 opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-wfformat/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReaderTest.kt create mode 100644 opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-wfformat/src/test/resources/trace.json diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4e2fc777..ddede2e8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,6 +52,7 @@ clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" } progressbar = { module = "me.tongfei:progressbar", version.ref = "progressbar" } # Format +jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } jackson-dataformat-csv = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-csv", version.ref = "jackson" } diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt index 88bbc623..46920dce 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt @@ -23,49 +23,52 @@ @file:JvmName("TaskColumns") package org.opendc.trace +import java.time.Duration +import java.time.Instant + /** * A column containing the task identifier. */ @JvmField -public val TASK_ID: TableColumn = longColumn("task:id") +public val TASK_ID: TableColumn = stringColumn("task:id") /** * A column containing the identifier of the workflow. */ @JvmField -public val TASK_WORKFLOW_ID: TableColumn = longColumn("task:workflow_id") +public val TASK_WORKFLOW_ID: TableColumn = stringColumn("task:workflow_id") /** * A column containing the submit time of the task. */ @JvmField -public val TASK_SUBMIT_TIME: TableColumn = longColumn("task:submit_time") +public val TASK_SUBMIT_TIME: TableColumn = TableColumn("task:submit_time", type = Instant::class.java) /** * A column containing the wait time of the task. */ @JvmField -public val TASK_WAIT_TIME: TableColumn = longColumn("task:wait_time") +public val TASK_WAIT_TIME: TableColumn = TableColumn("task:wait_time", type = Instant::class.java) /** * A column containing the runtime time of the task. */ @JvmField -public val TASK_RUNTIME: TableColumn = longColumn("task:runtime") +public val TASK_RUNTIME: TableColumn = TableColumn("task:runtime", type = Duration::class.java) /** * A column containing the parents of a task. */ @Suppress("UNCHECKED_CAST") @JvmField -public val TASK_PARENTS: TableColumn> = TableColumn("task:parents", type = Set::class.java as Class>) +public val TASK_PARENTS: TableColumn> = TableColumn("task:parents", type = Set::class.java as Class>) /** * A column containing the children of a task. */ @Suppress("UNCHECKED_CAST") @JvmField -public val TASK_CHILDREN: TableColumn> = TableColumn("task:children", type = Set::class.java as Class>) +public val TASK_CHILDREN: TableColumn> = TableColumn("task:children", type = Set::class.java as Class>) /** * A column containing the requested CPUs of a task. diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt index fb9099bf..39eb5520 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt @@ -26,6 +26,8 @@ import com.fasterxml.jackson.core.JsonToken import com.fasterxml.jackson.dataformat.csv.CsvParser import com.fasterxml.jackson.dataformat.csv.CsvSchema import org.opendc.trace.* +import java.time.Duration +import java.time.Instant import java.util.regex.Pattern /** @@ -52,10 +54,10 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { } when (parser.currentName) { - "WorkflowID" -> workflowId = parser.longValue - "JobID" -> jobId = parser.longValue - "SubmitTime" -> submitTime = parser.longValue - "RunTime" -> runtime = parser.longValue + "WorkflowID" -> workflowId = parser.text + "JobID" -> jobId = parser.text + "SubmitTime" -> submitTime = Instant.ofEpochSecond(parser.longValue) + "RunTime" -> runtime = Duration.ofSeconds(parser.longValue) "NProcs" -> nProcs = parser.intValue "ReqNProcs" -> reqNProcs = parser.intValue "Dependencies" -> parseParents(parser.valueAsString) @@ -79,7 +81,7 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { } override fun get(column: TableColumn): T { - val res: Any = when (column) { + val res: Any? = when (column) { TASK_WORKFLOW_ID -> workflowId TASK_ID -> jobId TASK_SUBMIT_TIME -> submitTime @@ -107,13 +109,7 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { } override fun getLong(column: TableColumn): Long { - return when (column) { - TASK_WORKFLOW_ID -> workflowId - TASK_ID -> jobId - TASK_SUBMIT_TIME -> submitTime - TASK_RUNTIME -> runtime - else -> throw IllegalArgumentException("Invalid column") - } + throw IllegalArgumentException("Invalid column") } override fun getDouble(column: TableColumn): Double { @@ -163,10 +159,10 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { /** * Reader state fields. */ - private var workflowId = -1L - private var jobId = -1L - private var submitTime = -1L - private var runtime = -1L + private var workflowId: String? = null + private var jobId: String? = null + private var submitTime: Instant? = null + private var runtime: Duration? = null private var nProcs = -1 private var reqNProcs = -1 private var dependencies = emptySet() @@ -175,10 +171,10 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { * Reset the state. */ private fun reset() { - workflowId = -1 - jobId = -1 - submitTime = -1 - runtime = -1 + workflowId = null + jobId = null + submitTime = null + runtime = null nProcs = -1 reqNProcs = -1 dependencies = emptySet() diff --git a/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt b/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt index 6b0568fe..b209b979 100644 --- a/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt @@ -29,6 +29,8 @@ import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opendc.trace.* import java.net.URL +import java.time.Duration +import java.time.Instant /** * Test suite for the [GwfTraceFormat] class. @@ -90,11 +92,11 @@ internal class GwfTraceFormatTest { assertAll( { assertTrue(reader.nextRow()) }, - { assertEquals(0L, reader.getLong(TASK_WORKFLOW_ID)) }, - { assertEquals(1L, reader.getLong(TASK_ID)) }, - { assertEquals(16, reader.getLong(TASK_SUBMIT_TIME)) }, - { assertEquals(11, reader.getLong(TASK_RUNTIME)) }, - { assertEquals(setOf(), reader.get(TASK_PARENTS)) }, + { assertEquals("0", reader.get(TASK_WORKFLOW_ID)) }, + { assertEquals("1", reader.get(TASK_ID)) }, + { assertEquals(Instant.ofEpochSecond(16), reader.get(TASK_SUBMIT_TIME)) }, + { assertEquals(Duration.ofSeconds(11), reader.get(TASK_RUNTIME)) }, + { assertEquals(emptySet(), reader.get(TASK_PARENTS)) }, ) } diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt index 5f879a54..3f49c770 100644 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTableReader.kt @@ -24,6 +24,8 @@ package org.opendc.trace.swf import org.opendc.trace.* import java.io.BufferedReader +import java.time.Duration +import java.time.Instant /** * A [TableReader] implementation for the SWF format. @@ -85,10 +87,10 @@ internal class SwfTaskTableReader(private val reader: BufferedReader) : TableRea override fun get(column: TableColumn): T { val res: Any = when (column) { - TASK_ID -> getLong(TASK_ID) - TASK_SUBMIT_TIME -> getLong(TASK_SUBMIT_TIME) - TASK_WAIT_TIME -> getLong(TASK_WAIT_TIME) - TASK_RUNTIME -> getLong(TASK_RUNTIME) + TASK_ID -> fields[COL_JOB_ID] + TASK_SUBMIT_TIME -> Instant.ofEpochSecond(fields[COL_SUBMIT_TIME].toLong(10)) + TASK_WAIT_TIME -> Duration.ofSeconds(fields[COL_WAIT_TIME].toLong(10)) + TASK_RUNTIME -> Duration.ofSeconds(fields[COL_RUN_TIME].toLong(10)) TASK_REQ_NCPUS -> getInt(TASK_REQ_NCPUS) TASK_ALLOC_NCPUS -> getInt(TASK_ALLOC_NCPUS) TASK_PARENTS -> { @@ -121,13 +123,7 @@ internal class SwfTaskTableReader(private val reader: BufferedReader) : TableRea } override fun getLong(column: TableColumn): Long { - return when (column) { - TASK_ID -> fields[COL_JOB_ID].toLong(10) - TASK_SUBMIT_TIME -> fields[COL_SUBMIT_TIME].toLong(10) - TASK_WAIT_TIME -> fields[COL_WAIT_TIME].toLong(10) - TASK_RUNTIME -> fields[COL_RUN_TIME].toLong(10) - else -> throw IllegalArgumentException("Invalid column") - } + throw IllegalArgumentException("Invalid column") } override fun getDouble(column: TableColumn): Double { diff --git a/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt index 9686891b..828c2bfa 100644 --- a/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt @@ -85,10 +85,10 @@ internal class SwfTraceFormatTest { assertAll( { assertTrue(reader.nextRow()) }, - { assertEquals(1, reader.getLong(TASK_ID)) }, + { assertEquals("1", reader.get(TASK_ID)) }, { assertEquals(306, reader.getInt(TASK_ALLOC_NCPUS)) }, { assertTrue(reader.nextRow()) }, - { assertEquals(2, reader.getLong(TASK_ID)) }, + { assertEquals("2", reader.get(TASK_ID)) }, { assertEquals(17, reader.getInt(TASK_ALLOC_NCPUS)) }, ) diff --git a/opendc-trace/opendc-trace-wfformat/build.gradle.kts b/opendc-trace/opendc-trace-wfformat/build.gradle.kts new file mode 100644 index 00000000..2d336d03 --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/build.gradle.kts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for WfCommons workload traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) + + implementation(libs.jackson.core) +} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt new file mode 100644 index 00000000..907bf7ff --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wfformat + +import com.fasterxml.jackson.core.JsonFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * A [Table] containing the tasks in a WfCommons workload trace. + */ +internal class WfFormatTaskTable(private val factory: JsonFactory, private val path: Path) : Table { + override val name: String = TABLE_TASKS + + override val isSynthetic: Boolean = false + + override fun isSupported(column: TableColumn<*>): Boolean { + return when (column) { + TASK_ID -> true + TASK_WORKFLOW_ID -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_PARENTS -> true + TASK_CHILDREN -> true + else -> false + } + } + + override fun newReader(): TableReader { + val parser = factory.createParser(path.toFile()) + return WfFormatTaskTableReader(parser) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Invalid partition $partition") + } + + override fun toString(): String = "WfFormatTaskTable" +} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt new file mode 100644 index 00000000..4408ba5c --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wfformat + +import com.fasterxml.jackson.core.JsonParseException +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.core.JsonToken +import org.opendc.trace.* +import java.time.Duration +import kotlin.math.roundToInt + +/** + * A [TableReader] implementation for the WfCommons workload trace format. + */ +internal class WfFormatTaskTableReader(private val parser: JsonParser) : TableReader { + /** + * The current nesting of the parser. + */ + private var level: ParserLevel = ParserLevel.TOP + + override fun nextRow(): Boolean { + reset() + + var hasJob = false + + while (!hasJob) { + when (level) { + ParserLevel.TOP -> { + val token = parser.nextToken() + + // Check whether the document is not empty and starts with an object + if (token == null) { + break + } else if (token != JsonToken.START_OBJECT) { + throw JsonParseException(parser, "Expected object", parser.currentLocation) + } else { + level = ParserLevel.TRACE + } + } + ParserLevel.TRACE -> { + // Seek for the workflow object in the file + if (!seekWorkflow()) { + break + } else if (!parser.isExpectedStartObjectToken) { + throw JsonParseException(parser, "Expected object", parser.currentLocation) + } else { + level = ParserLevel.WORKFLOW + } + } + ParserLevel.WORKFLOW -> { + // Seek for the jobs object in the file + level = if (!seekJobs()) { + ParserLevel.TRACE + } else if (!parser.isExpectedStartArrayToken) { + throw JsonParseException(parser, "Expected array", parser.currentLocation) + } else { + ParserLevel.JOB + } + } + ParserLevel.JOB -> { + when (parser.nextToken()) { + JsonToken.END_ARRAY -> level = ParserLevel.WORKFLOW + JsonToken.START_OBJECT -> { + parseJob() + hasJob = true + break + } + else -> throw JsonParseException(parser, "Unexpected token", parser.currentLocation) + } + } + } + } + + return hasJob + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + TASK_ID -> true + TASK_WORKFLOW_ID -> true + TASK_RUNTIME -> true + TASK_REQ_NCPUS -> true + TASK_PARENTS -> true + TASK_CHILDREN -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + TASK_ID -> id + TASK_WORKFLOW_ID -> workflowId + TASK_RUNTIME -> runtime + TASK_PARENTS -> parents + TASK_CHILDREN -> children + TASK_REQ_NCPUS -> getInt(TASK_REQ_NCPUS) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + TASK_REQ_NCPUS -> cores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + throw IllegalArgumentException("Invalid column") + } + + override fun close() { + parser.close() + } + + /** + * Parse the trace and seek until the workflow description. + */ + private fun seekWorkflow(): Boolean { + while (parser.nextValue() != JsonToken.END_OBJECT) { + when (parser.currentName) { + "name" -> workflowId = parser.text + "workflow" -> return true + else -> parser.skipChildren() + } + } + + return false + } + + /** + * Parse the workflow description in the file and seek until the first job. + */ + private fun seekJobs(): Boolean { + while (parser.nextValue() != JsonToken.END_OBJECT) { + when (parser.currentName) { + "jobs" -> return true + else -> parser.skipChildren() + } + } + + return false + } + + /** + * Parse a single job in the file. + */ + private fun parseJob() { + while (parser.nextValue() != JsonToken.END_OBJECT) { + when (parser.currentName) { + "name" -> id = parser.text + "parents" -> parents = parseIds() + "children" -> children = parseIds() + "runtime" -> runtime = Duration.ofSeconds(parser.numberValue.toLong()) + "cores" -> cores = parser.floatValue.roundToInt() + else -> parser.skipChildren() + } + } + } + + /** + * Parse the parents/children of a job. + */ + private fun parseIds(): Set { + if (!parser.isExpectedStartArrayToken) { + throw JsonParseException(parser, "Expected array", parser.currentLocation) + } + + val ids = mutableSetOf() + + while (parser.nextToken() != JsonToken.END_ARRAY) { + if (parser.currentToken != JsonToken.VALUE_STRING) { + throw JsonParseException(parser, "Expected token", parser.currentLocation) + } + + ids.add(parser.valueAsString) + } + + return ids + } + + private enum class ParserLevel { + TOP, TRACE, WORKFLOW, JOB + } + + /** + * State fields for the parser. + */ + private var id: String? = null + private var workflowId: String? = null + private var runtime: Duration? = null + private var parents: Set? = null + private var children: Set? = null + private var cores = -1 + + private fun reset() { + id = null + runtime = null + parents = null + children = null + cores = -1 + } +} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt new file mode 100644 index 00000000..2d9c79fb --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wfformat + +import com.fasterxml.jackson.core.JsonFactory +import org.opendc.trace.TABLE_TASKS +import org.opendc.trace.Table +import org.opendc.trace.Trace +import java.nio.file.Path + +/** + * [Trace] implementation for the WfCommons workload trace format. + */ +public class WfFormatTrace internal constructor(private val factory: JsonFactory, private val path: Path) : Trace { + override val tables: List = listOf(TABLE_TASKS) + + override fun containsTable(name: String): Boolean = TABLE_TASKS == name + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_TASKS -> WfFormatTaskTable(factory, path) + else -> null + } + } + + override fun toString(): String = "WfFormatTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt new file mode 100644 index 00000000..ff8d054c --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wfformat + +import com.fasterxml.jackson.core.JsonFactory +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A [TraceFormat] implementation for the WfCommons workload trace format. + */ +public class WfFormatTraceFormat : TraceFormat { + /** + * The [JsonFactory] that is used to created JSON parsers. + */ + private val factory = JsonFactory() + + override val name: String = "wfformat" + + override fun open(url: URL): WfFormatTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return WfFormatTrace(factory, path) + } +} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-wfformat/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..ee3aa2f6 --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.wfformat.WfFormatTraceFormat diff --git a/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReaderTest.kt b/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReaderTest.kt new file mode 100644 index 00000000..b07f27ed --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReaderTest.kt @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wfformat + +import com.fasterxml.jackson.core.JsonFactory +import com.fasterxml.jackson.core.JsonParseException +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.TASK_ID +import org.opendc.trace.TASK_PARENTS + +/** + * Test suite for the [WfFormatTaskTableReader] class. + */ +internal class WfFormatTaskTableReaderTest { + /** + * The [JsonFactory] used to construct the parser. + */ + private val factory = JsonFactory() + + @Test + fun testEmptyInput() { + val content = "" + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertFalse(reader.nextRow()) + reader.close() + } + + @Test + fun testTopLevelArrayInput() { + val content = "[]" + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { + while (reader.nextRow()) { + continue + } + } + + reader.close() + } + + @Test + fun testNoWorkflow() { + val content = """ + { + "name": "eager-nextflow-chameleon" + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertDoesNotThrow { + while (reader.nextRow()) { + continue + } + } + + reader.close() + } + + @Test + fun testWorkflowArrayType() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": [] + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { + while (reader.nextRow()) { + continue + } + } + + reader.close() + } + + @Test + fun testWorkflowNullType() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": null + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { + while (reader.nextRow()) { + continue + } + } + + reader.close() + } + + @Test + fun testNoJobs() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertDoesNotThrow { reader.nextRow() } + + reader.close() + } + + @Test + fun testJobsObjectType() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { "jobs": {} } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { reader.nextRow() } + + reader.close() + } + + @Test + fun testJobsNullType() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { "jobs": null } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { reader.nextRow() } + + reader.close() + } + + @Test + fun testJobsInvalidChildType() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + "jobs": [1] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { reader.nextRow() } + + reader.close() + } + + @Test + fun testJobsValidChildType() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + "jobs": [ + { + "name": "test" + } + ] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertTrue(reader.nextRow()) + assertEquals("test", reader.get(TASK_ID)) + assertFalse(reader.nextRow()) + + reader.close() + } + + @Test + fun testJobsInvalidParents() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + "jobs": [ + { + "name": "test", + "parents": 1, + } + ] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { reader.nextRow() } + + reader.close() + } + + @Test + fun testJobsInvalidParentsItem() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + "jobs": [ + { + "name": "test", + "parents": [1], + } + ] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertThrows { reader.nextRow() } + + reader.close() + } + + @Test + fun testJobsValidParents() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + "jobs": [ + { + "name": "test", + "parents": ["1"] + } + ] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertTrue(reader.nextRow()) + assertEquals(setOf("1"), reader.get(TASK_PARENTS)) + assertFalse(reader.nextRow()) + + reader.close() + } + + @Test + fun testJobsInvalidSecondEntry() { + val content = """ + { + "workflow": { + "jobs": [ + { + "name": "test", + "parents": ["1"] + }, + "test" + ] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertDoesNotThrow { reader.nextRow() } + assertThrows { reader.nextRow() } + + reader.close() + } + + @Test + fun testDuplicateJobsArray() { + val content = """ + { + "name": "eager-nextflow-chameleon", + "workflow": { + "jobs": [ + { + "name": "test", + "parents": ["1"] + } + ], + "jobs": [ + { + "name": "test2", + "parents": ["test"] + } + ] + } + } + """.trimIndent() + val parser = factory.createParser(content) + val reader = WfFormatTaskTableReader(parser) + + assertTrue(reader.nextRow()) + assertTrue(reader.nextRow()) + assertEquals("test2", reader.get(TASK_ID)) + assertFalse(reader.nextRow()) + + reader.close() + } +} diff --git a/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt b/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt new file mode 100644 index 00000000..0bfc8840 --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.wfformat + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.* +import java.io.File +import java.net.URL + +/** + * Test suite for the [WfFormatTraceFormat] class. + */ +class WfFormatTraceFormatTest { + @Test + fun testTraceExists() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val format = WfFormatTraceFormat() + assertDoesNotThrow { format.open(input) } + } + + @Test + fun testTraceDoesNotExists() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val format = WfFormatTraceFormat() + assertThrows { format.open(URL(input.toString() + "help")) } + } + + @Test + fun testTables() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val format = WfFormatTraceFormat() + val trace = format.open(input) + + assertEquals(listOf(TABLE_TASKS), trace.tables) + } + + @Test + fun testTableExists() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val format = WfFormatTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val format = WfFormatTraceFormat() + val trace = format.open(input) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + /** + * Smoke test for parsing WfCommons traces. + */ + @Test + fun testTableReader() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val trace = WfFormatTraceFormat().open(input) + val reader = trace.getTable(TABLE_TASKS)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("makebwaindex_mammoth_mt_krause.fasta", reader.get(TASK_ID)) }, + { assertEquals("eager-nextflow-chameleon", reader.get(TASK_WORKFLOW_ID)) }, + { assertEquals(172000, reader.get(TASK_RUNTIME).toMillis()) }, + { assertEquals(emptySet(), reader.get(TASK_PARENTS)) }, + ) + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("makeseqdict_mammoth_mt_krause.fasta", reader.get(TASK_ID)) }, + { assertEquals("eager-nextflow-chameleon", reader.get(TASK_WORKFLOW_ID)) }, + { assertEquals(175000, reader.get(TASK_RUNTIME).toMillis()) }, + { assertEquals(setOf("makebwaindex_mammoth_mt_krause.fasta"), reader.get(TASK_PARENTS)) }, + ) + + reader.close() + } + + /** + * Test full iteration of the table. + */ + @Test + fun testTableReaderFull() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val trace = WfFormatTraceFormat().open(input) + val reader = trace.getTable(TABLE_TASKS)!!.newReader() + + assertDoesNotThrow { + while (reader.nextRow()) { + // reader.get(TASK_ID) + } + reader.close() + } + } + + @Test + fun testTableReaderPartition() { + val input = File("src/test/resources/trace.json").toURI().toURL() + val format = WfFormatTraceFormat() + val table = format.open(input).getTable(TABLE_TASKS)!! + + assertThrows { table.newReader("test") } + } +} diff --git a/opendc-trace/opendc-trace-wfformat/src/test/resources/trace.json b/opendc-trace/opendc-trace-wfformat/src/test/resources/trace.json new file mode 100644 index 00000000..d21f024d --- /dev/null +++ b/opendc-trace/opendc-trace-wfformat/src/test/resources/trace.json @@ -0,0 +1,1342 @@ +{ + "name": "eager-nextflow-chameleon", + "description": "Instance generated with WfCommons - https://wfcommons.org", + "createdAt": "2021-09-06T03:43:31.762479", + "schemaVersion": "1.2", + "author": { + "name": "cc", + "email": "support@wfcommons.org" + }, + "wms": { + "name": "Nextflow", + "version": "21.04.3", + "url": "https://www.nextflow.io" + }, + "workflow": { + "executedAt": "20210906T034331+0000", + "makespan": 275, + "jobs": [ + { + "name": "makebwaindex_mammoth_mt_krause.fasta", + "type": "compute", + "runtime": 172.182, + "command": { + "program": "makebwaindex", + "arguments": [ + "bwa", + "index", + "Mammoth_MT_Krause.fasta", + "mkdir", + "BWAIndex", + "&&", + "mv", + "Mammoth_MT_Krause.fasta*", + "BWAIndex" + ] + }, + "parents": [], + "children": [ + "makeseqdict_mammoth_mt_krause.fasta" + ], + "files": [], + "cores": 1.0, + "id": "ID000001", + "category": "makebwaindex", + "avgCPU": 5.8, + "bytesRead": 124, + "bytesWritten": 126, + "memory": 4248 + }, + { + "name": "makeseqdict_mammoth_mt_krause.fasta", + "type": "compute", + "runtime": 175.427, + "command": { + "program": "makeseqdict", + "arguments": [ + "picard", + "-Xmx6144M", + "CreateSequenceDictionary", + "R=Mammoth_MT_Krause.fasta", + "O=\"Mammoth_MT_Krause.dict\"" + ] + }, + "parents": [ + "makebwaindex_mammoth_mt_krause.fasta" + ], + "children": [ + "makefastaindex_mammoth_mt_krause.fasta" + ], + "files": [], + "cores": 1.0, + "id": "ID000003", + "category": "makeseqdict", + "avgCPU": 83.5, + "bytesRead": 22728, + "bytesWritten": 1300, + "memory": 104416 + }, + { + "name": "makefastaindex_mammoth_mt_krause.fasta", + "type": "compute", + "runtime": 170.797, + "command": { + "program": "makefastaindex", + "arguments": [ + "samtools", + "faidx", + "Mammoth_MT_Krause.fasta" + ] + }, + "parents": [ + "makeseqdict_mammoth_mt_krause.fasta" + ], + "children": [ + "output_documentation" + ], + "files": [], + "cores": 1.0, + "id": "ID000002", + "category": "makefastaindex", + "avgCPU": 23.8, + "bytesRead": 66, + "bytesWritten": 4, + "memory": 6096 + }, + { + "name": "output_documentation", + "type": "compute", + "runtime": 173.479, + "command": { + "program": "output_documentation", + "arguments": [ + "markdown_to_html.py", + "output.md", + "-o", + "results_description.html" + ] + }, + "parents": [ + "makefastaindex_mammoth_mt_krause.fasta" + ], + "children": [ + "get_software_versions" + ], + "files": [], + "cores": 1.0, + "id": "ID000005", + "category": "output_documentation", + "avgCPU": 84.0, + "bytesRead": 8222, + "bytesWritten": 15165, + "memory": 11488 + }, + { + "name": "get_software_versions", + "type": "compute", + "runtime": 183.445, + "command": { + "program": "get_software_versions", + "arguments": [ + "echo", + "2.3.5", + "&>", + "v_pipeline.txt", + "echo", + "21.04.3", + "&>", + "v_nextflow.txt", + "fastqc", + "--version", + "&>", + "v_fastqc.txt", + "2>&1", + "||", + "true", + "AdapterRemoval", + "--version", + "&>", + "v_adapterremoval.txt", + "2>&1", + "||", + "true", + "fastp", + "--version", + "&>", + "v_fastp.txt", + "2>&1", + "||", + "true", + "bwa", + "&>", + "v_bwa.txt", + "2>&1", + "||", + "true", + "circulargenerator", + "--help", + "|", + "head", + "-n", + "1", + "&>", + "v_circulargenerator.txt", + "2>&1", + "||", + "true", + "samtools", + "--version", + "&>", + "v_samtools.txt", + "2>&1", + "||", + "true", + "dedup", + "-v", + "&>", + "v_dedup.txt", + "2>&1", + "||", + "true", + "##", + "bioconda", + "recipe", + "of", + "picard", + "is", + "incorrectly", + "set", + "up", + "and", + "extra", + "warning", + "made", + "with", + "stderr,", + "this", + "ugly", + "command", + "ensures", + "only", + "version", + "exported", + "(", + "exec", + "7>&1", + "picard", + "MarkDuplicates", + "--version", + "2>&1", + ">&7", + "|", + "grep", + "-v", + "/", + ">&2", + ")", + "2>", + "v_markduplicates.txt", + "||", + "true", + "qualimap", + "--version", + "&>", + "v_qualimap.txt", + "2>&1", + "||", + "true", + "preseq", + "&>", + "v_preseq.txt", + "2>&1", + "||", + "true", + "gatk", + "--version", + "2>&1", + "|", + "head", + "-n", + "1", + ">", + "v_gatk.txt", + "2>&1", + "||", + "true", + "gatk3", + "--version", + "2>&1", + ">", + "v_gatk3.txt", + "2>&1", + "||", + "true", + "freebayes", + "--version", + "&>", + "v_freebayes.txt", + "2>&1", + "||", + "true", + "bedtools", + "--version", + "&>", + "v_bedtools.txt", + "2>&1", + "||", + "true", + "damageprofiler", + "--version", + "&>", + "v_damageprofiler.txt", + "2>&1", + "||", + "true", + "bam", + "--version", + "&>", + "v_bamutil.txt", + "2>&1", + "||", + "true", + "pmdtools", + "--version", + "&>", + "v_pmdtools.txt", + "2>&1", + "||", + "true", + "angsd", + "-h", + "|&", + "head", + "-n", + "1", + "|", + "cut", + "-d", + "-f3-4", + "&>", + "v_angsd.txt", + "2>&1", + "||", + "true", + "multivcfanalyzer", + "--help", + "|", + "head", + "-n", + "1", + "&>", + "v_multivcfanalyzer.txt", + "2>&1", + "||", + "true", + "malt-run", + "--help", + "|&", + "tail", + "-n", + "3", + "|", + "head", + "-n", + "1", + "|", + "cut", + "-f", + "2", + "-d(", + "|", + "cut", + "-f", + "1", + "-d", + ",", + "&>", + "v_malt.txt", + "2>&1", + "||", + "true", + "MaltExtract", + "--help", + "|", + "head", + "-n", + "2", + "|", + "tail", + "-n", + "1", + "&>", + "v_maltextract.txt", + "2>&1", + "||", + "true", + "multiqc", + "--version", + "&>", + "v_multiqc.txt", + "2>&1", + "||", + "true", + "vcf2genome", + "-h", + "|&", + "head", + "-n", + "1", + "&>", + "v_vcf2genome.txt", + "||", + "true", + "mtnucratio", + "--help", + "&>", + "v_mtnucratiocalculator.txt", + "||", + "true", + "sexdeterrmine", + "--version", + "&>", + "v_sexdeterrmine.txt", + "||", + "true", + "kraken2", + "--version", + "|", + "head", + "-n", + "1", + "&>", + "v_kraken.txt", + "||", + "true", + "endorS.py", + "--version", + "&>", + "v_endorSpy.txt", + "||", + "true", + "pileupCaller", + "--version", + "&>", + "v_sequencetools.txt", + "2>&1", + "||", + "true", + "bowtie2", + "--version", + "|", + "grep", + "-a", + "bowtie2-.*", + "-fdebug", + ">", + "v_bowtie2.txt", + "||", + "true", + "eigenstrat_snp_coverage", + "--version", + "|", + "cut", + "-d", + "-f2", + ">v_eigenstrat_snp_coverage.txt", + "||", + "true", + "mapDamage", + "--version", + ">", + "v_mapdamage.txt", + "||", + "true", + "bbduk.sh", + "|", + "grep", + "Last", + "modified", + "|", + "cut", + "-d", + "-f", + "3-99", + ">", + "v_bbduk.txt", + "||", + "true", + "scrape_software_versions.py", + "&>", + "software_versions_mqc.yaml" + ] + }, + "parents": [ + "output_documentation" + ], + "children": [ + "fastqc_jk2782_l1", + "fastqc_jk2802_l2" + ], + "files": [], + "cores": 2.0, + "id": "ID000006", + "category": "get_software_versions", + "avgCPU": 147.8, + "bytesRead": 172760, + "bytesWritten": 1048, + "memory": 387324 + }, + { + "name": "fastqc_jk2782_l1", + "type": "compute", + "runtime": 175.205, + "command": { + "program": "fastqc", + "arguments": [ + "fastqc", + "-t", + "2", + "-q", + "JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq.gz", + "JK2782_TGGCCGATCAACGA_L008_R2_001.fastq.gz.tengrand.fq.gz", + "rename", + "s/_fastqc.zip$/_raw_fastqc.zip/", + "*_fastqc.zip", + "rename", + "s/_fastqc.html$/_raw_fastqc.html/", + "*_fastqc.html" + ] + }, + "parents": [ + "get_software_versions" + ], + "children": [ + "adapter_removal_jk2782_l1", + "adapter_removal_jk2802_l2" + ], + "files": [], + "cores": 2.0, + "id": "ID000007", + "category": "fastqc", + "avgCPU": 161.8, + "bytesRead": 35981, + "bytesWritten": 3967, + "memory": 270124 + }, + { + "name": "adapter_removal_jk2782_l1", + "type": "compute", + "runtime": 172.643, + "command": { + "program": "adapter_removal", + "arguments": [ + "mkdir", + "-p", + "output", + "AdapterRemoval", + "--file1", + "JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq.gz", + "--file2", + "JK2782_TGGCCGATCAACGA_L008_R2_001.fastq.gz.tengrand.fq.gz", + "--basename", + "JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe", + "--gzip", + "--threads", + "2", + "--qualitymax", + "41", + "--collapse", + "--trimns", + "--trimqualities", + "--adapter1", + "AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC", + "--adapter2", + "AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGTA", + "--minlength", + "30", + "--minquality", + "20", + "--minadapteroverlap", + "1", + "cat", + "*.collapsed.gz", + "*.collapsed.truncated.gz", + "*.singleton.truncated.gz", + "*.pair1.truncated.gz", + "*.pair2.truncated.gz", + ">", + "output/JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe.combined.tmp.fq.gz", + "mv", + "*.settings", + "output/", + "##", + "Add", + "R_", + "and", + "L_", + "for", + "unmerged", + "reads", + "for", + "DeDup", + "compatibility", + "AdapterRemovalFixPrefix", + "-Xmx4g", + "output/JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe.combined.tmp.fq.gz", + "|", + "pigz", + "-p", + "1", + ">", + "output/JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe.combined.fq.gz" + ] + }, + "parents": [ + "fastqc_jk2782_l1", + "fastqc_jk2802_l2" + ], + "children": [ + "fastqc_after_clipping_jk2782_l1", + "fastqc_after_clipping_jk2802_l2" + ], + "files": [], + "cores": 2.0, + "id": "ID000008", + "category": "adapter_removal", + "avgCPU": 160.9, + "bytesRead": 17357, + "bytesWritten": 4405, + "memory": 79308 + }, + { + "name": "fastqc_jk2802_l2", + "type": "compute", + "runtime": 177.338, + "command": { + "program": "fastqc", + "arguments": [ + "fastqc", + "-q", + "JK2802_AGAATAACCTACCA_L008_R1_001.fastq.gz.tengrand.fq.gz", + "rename", + "s/_fastqc.zip$/_raw_fastqc.zip/", + "*_fastqc.zip", + "rename", + "s/_fastqc.html$/_raw_fastqc.html/", + "*_fastqc.html" + ] + }, + "parents": [ + "get_software_versions" + ], + "children": [ + "adapter_removal_jk2782_l1", + "adapter_removal_jk2802_l2" + ], + "files": [], + "cores": 2.0, + "id": "ID000009", + "category": "fastqc", + "avgCPU": 120.1, + "bytesRead": 24457, + "bytesWritten": 2181, + "memory": 181060 + }, + { + "name": "adapter_removal_jk2802_l2", + "type": "compute", + "runtime": 174.313, + "command": { + "program": "adapter_removal", + "arguments": [ + "mkdir", + "-p", + "output", + "AdapterRemoval", + "--file1", + "JK2802_AGAATAACCTACCA_L008_R1_001.fastq.gz.tengrand.fq.gz", + "--basename", + "JK2802_AGAATAACCTACCA_L008_R1_001.fastq.gz.tengrand.fq_L2.se", + "--gzip", + "--threads", + "2", + "--qualitymax", + "41", + "--trimns", + "--trimqualities", + "--adapter1", + "AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC", + "--adapter2", + "AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGTA", + "--minlength", + "30", + "--minquality", + "20", + "--minadapteroverlap", + "1", + "mv", + "*.settings", + "*.se.truncated.gz", + "output/" + ] + }, + "parents": [ + "fastqc_jk2782_l1", + "fastqc_jk2802_l2" + ], + "children": [ + "fastqc_after_clipping_jk2782_l1", + "fastqc_after_clipping_jk2802_l2" + ], + "files": [], + "cores": 2.0, + "id": "ID000010", + "category": "adapter_removal", + "avgCPU": 106.5, + "bytesRead": 683, + "bytesWritten": 897, + "memory": 12136 + }, + { + "name": "fastqc_after_clipping_jk2782_l1", + "type": "compute", + "runtime": 15.371, + "command": { + "program": "fastqc_after_clipping", + "arguments": [ + "fastqc", + "-t", + "2", + "-q", + "JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe.combined.fq.gz" + ] + }, + "parents": [ + "adapter_removal_jk2782_l1", + "adapter_removal_jk2802_l2" + ], + "children": [ + "bwa_jk2802", + "bwa_jk2782" + ], + "files": [], + "cores": 2.0, + "id": "ID000013", + "category": "fastqc_after_clipping", + "avgCPU": 133.3, + "bytesRead": 23788, + "bytesWritten": 1998, + "memory": 215020 + }, + { + "name": "fastqc_after_clipping_jk2802_l2", + "type": "compute", + "runtime": 15.272, + "command": { + "program": "fastqc_after_clipping", + "arguments": [ + "fastqc", + "-t", + "2", + "-q", + "JK2802_AGAATAACCTACCA_L008_R1_001.fastq.gz.tengrand.fq_L2.se.truncated.gz" + ] + }, + "parents": [ + "adapter_removal_jk2782_l1", + "adapter_removal_jk2802_l2" + ], + "children": [ + "bwa_jk2802", + "bwa_jk2782" + ], + "files": [], + "cores": 2.0, + "id": "ID000014", + "category": "fastqc_after_clipping", + "avgCPU": 124.1, + "bytesRead": 23882, + "bytesWritten": 2143, + "memory": 213064 + }, + { + "name": "bwa_jk2802", + "type": "compute", + "runtime": 9.566, + "command": { + "program": "bwa", + "arguments": [ + "bwa", + "aln", + "-t", + "2", + "BWAIndex/Mammoth_MT_Krause.fasta", + "JK2802_AGAATAACCTACCA_L008_R1_001.fastq.gz.tengrand.fq_L2.se.truncated.gz", + "-n", + "0.04", + "-l", + "1024", + "-k", + "2", + "-o", + "1", + "-f", + "JK2802.sai", + "bwa", + "samse", + "-r", + "\"@RGtID:ILLUMINA-JK2802tSM:JK2802tPL:illuminatPU:ILLUMINA-JK2802-SE\"", + "BWAIndex/Mammoth_MT_Krause.fasta", + "JK2802.sai", + "JK2802_AGAATAACCTACCA_L008_R1_001.fastq.gz.tengrand.fq_L2.se.truncated.gz", + "|", + "samtools", + "sort", + "-@", + "1", + "-O", + "bam", + "-", + ">", + "\"JK2802\"_\"SE\".mapped.bam", + "samtools", + "index", + "\"JK2802\"_\"SE\".mapped.bam" + ] + }, + "parents": [ + "fastqc_after_clipping_jk2782_l1", + "fastqc_after_clipping_jk2802_l2" + ], + "children": [ + "samtools_flagstat_jk2782", + "samtools_flagstat_jk2802" + ], + "files": [], + "cores": 2.0, + "id": "ID000016", + "category": "bwa", + "avgCPU": 15.7, + "bytesRead": 3774, + "bytesWritten": 3367, + "memory": 10628 + }, + { + "name": "bwa_jk2782", + "type": "compute", + "runtime": 9.652, + "command": { + "program": "bwa", + "arguments": [ + "bwa", + "aln", + "-t", + "2", + "BWAIndex/Mammoth_MT_Krause.fasta", + "JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe.combined.fq.gz", + "-n", + "0.04", + "-l", + "1024", + "-k", + "2", + "-o", + "1", + "-f", + "JK2782.sai", + "bwa", + "samse", + "-r", + "\"@RGtID:ILLUMINA-JK2782tSM:JK2782tPL:illuminatPU:ILLUMINA-JK2782-PE\"", + "BWAIndex/Mammoth_MT_Krause.fasta", + "JK2782.sai", + "JK2782_TGGCCGATCAACGA_L008_R1_001.fastq.gz.tengrand.fq_L1.pe.combined.fq.gz", + "|", + "samtools", + "sort", + "-@", + "1", + "-O", + "bam", + "-", + ">", + "\"JK2782\"_\"PE\".mapped.bam", + "samtools", + "index", + "\"JK2782\"_\"PE\".mapped.bam" + ] + }, + "parents": [ + "fastqc_after_clipping_jk2782_l1", + "fastqc_after_clipping_jk2802_l2" + ], + "children": [ + "samtools_flagstat_jk2782", + "samtools_flagstat_jk2802" + ], + "files": [], + "cores": 2.0, + "id": "ID000015", + "category": "bwa", + "avgCPU": 69.8, + "bytesRead": 3705, + "bytesWritten": 3355, + "memory": 12876 + }, + { + "name": "samtools_flagstat_jk2782", + "type": "compute", + "runtime": 13.011, + "command": { + "program": "samtools_flagstat", + "arguments": [ + "samtools", + "flagstat", + "JK2782_PE.mapped.bam", + ">", + "JK2782_flagstat.stats" + ] + }, + "parents": [ + "bwa_jk2802", + "bwa_jk2782" + ], + "children": [ + "markduplicates_jk2782", + "markduplicates_jk2802" + ], + "files": [], + "cores": 1.0, + "id": "ID000026", + "category": "samtools_flagstat", + "avgCPU": 30.1, + "bytesRead": 478, + "bytesWritten": 5, + "memory": 6468 + }, + { + "name": "samtools_flagstat_jk2802", + "type": "compute", + "runtime": 13.129, + "command": { + "program": "samtools_flagstat", + "arguments": [ + "samtools", + "flagstat", + "JK2802_SE.mapped.bam", + ">", + "JK2802_flagstat.stats" + ] + }, + "parents": [ + "bwa_jk2802", + "bwa_jk2782" + ], + "children": [ + "markduplicates_jk2782", + "markduplicates_jk2802" + ], + "files": [], + "cores": 1.0, + "id": "ID000024", + "category": "samtools_flagstat", + "avgCPU": 118.5, + "bytesRead": 551, + "bytesWritten": 5 + }, + { + "name": "markduplicates_jk2782", + "type": "compute", + "runtime": 22.655, + "command": { + "program": "markduplicates", + "arguments": [ + "mv", + "JK2782_PE.mapped.bam", + "JK2782.bam", + "picard", + "-Xmx4096M", + "MarkDuplicates", + "INPUT=JK2782.bam", + "OUTPUT=JK2782_rmdup.bam", + "REMOVE_DUPLICATES=TRUE", + "AS=TRUE", + "METRICS_FILE=\"JK2782_rmdup.metrics\"", + "VALIDATION_STRINGENCY=SILENT", + "samtools", + "index", + "JK2782_rmdup.bam" + ] + }, + "parents": [ + "samtools_flagstat_jk2782", + "samtools_flagstat_jk2802" + ], + "children": [ + "preseq_jk2782", + "preseq_jk2802" + ], + "files": [], + "cores": 2.0, + "id": "ID000021", + "category": "markduplicates", + "avgCPU": 173.6, + "bytesRead": 24055, + "bytesWritten": 2319, + "memory": 1400048 + }, + { + "name": "markduplicates_jk2802", + "type": "compute", + "runtime": 21.545, + "command": { + "program": "markduplicates", + "arguments": [ + "mv", + "JK2802_SE.mapped.bam", + "JK2802.bam", + "picard", + "-Xmx4096M", + "MarkDuplicates", + "INPUT=JK2802.bam", + "OUTPUT=JK2802_rmdup.bam", + "REMOVE_DUPLICATES=TRUE", + "AS=TRUE", + "METRICS_FILE=\"JK2802_rmdup.metrics\"", + "VALIDATION_STRINGENCY=SILENT", + "samtools", + "index", + "JK2802_rmdup.bam" + ] + }, + "parents": [ + "samtools_flagstat_jk2782", + "samtools_flagstat_jk2802" + ], + "children": [ + "preseq_jk2782", + "preseq_jk2802" + ], + "files": [], + "cores": 2.0, + "id": "ID000020", + "category": "markduplicates", + "avgCPU": 182.6, + "bytesRead": 24242, + "bytesWritten": 2466, + "memory": 1404624 + }, + { + "name": "preseq_jk2782", + "type": "compute", + "runtime": 12.299, + "command": { + "program": "preseq", + "arguments": [ + "preseq", + "c_curve", + "-s", + "1000", + "-o", + "JK2782_PE.mapped.ccurve", + "-B", + "JK2782_PE.mapped.bam" + ] + }, + "parents": [ + "markduplicates_jk2782", + "markduplicates_jk2802" + ], + "children": [ + "endorspy_jk2782", + "endorspy_jk2802" + ], + "files": [], + "cores": 1.0, + "id": "ID000030", + "category": "preseq", + "avgCPU": 81.9, + "bytesRead": 473, + "bytesWritten": 4, + "memory": 12032 + }, + { + "name": "preseq_jk2802", + "type": "compute", + "runtime": 10.188, + "command": { + "program": "preseq", + "arguments": [ + "preseq", + "c_curve", + "-s", + "1000", + "-o", + "JK2802_SE.mapped.ccurve", + "-B", + "JK2802_SE.mapped.bam" + ] + }, + "parents": [ + "markduplicates_jk2782", + "markduplicates_jk2802" + ], + "children": [ + "endorspy_jk2782", + "endorspy_jk2802" + ], + "files": [], + "cores": 1.0, + "id": "ID000027", + "category": "preseq", + "avgCPU": 77.6, + "bytesRead": 548, + "bytesWritten": 4, + "memory": 11972 + }, + { + "name": "endorspy_jk2782", + "type": "compute", + "runtime": 7.537, + "command": { + "program": "endorspy", + "arguments": [ + "endorS.py", + "-o", + "json", + "-n", + "JK2782", + "JK2782_flagstat.stats" + ] + }, + "parents": [ + "preseq_jk2782", + "preseq_jk2802" + ], + "children": [ + "damageprofiler_jk2802", + "damageprofiler_jk2782" + ], + "files": [], + "cores": 1.0, + "id": "ID000031", + "category": "endorspy", + "avgCPU": 44.7, + "bytesRead": 623, + "bytesWritten": 4, + "memory": 12264 + }, + { + "name": "endorspy_jk2802", + "type": "compute", + "runtime": 8.0, + "command": { + "program": "endorspy", + "arguments": [ + "endorS.py", + "-o", + "json", + "-n", + "JK2802", + "JK2802_flagstat.stats" + ] + }, + "parents": [ + "preseq_jk2782", + "preseq_jk2802" + ], + "children": [ + "damageprofiler_jk2802", + "damageprofiler_jk2782" + ], + "files": [], + "cores": 1.0, + "id": "ID000032", + "category": "endorspy", + "avgCPU": 54.0, + "bytesRead": 623, + "bytesWritten": 4, + "memory": 12224 + }, + { + "name": "damageprofiler_jk2802", + "type": "compute", + "runtime": 18.596, + "command": { + "program": "damageprofiler", + "arguments": [ + "damageprofiler", + "-Xmx4g", + "-i", + "JK2802_rmdup.bam", + "-r", + "Mammoth_MT_Krause.fasta", + "-l", + "100", + "-t", + "15", + "-o", + ".", + "-yaxis_damageplot", + "0.30" + ] + }, + "parents": [ + "endorspy_jk2782", + "endorspy_jk2802" + ], + "children": [ + "qualimap_jk2802", + "qualimap_jk2782" + ], + "files": [], + "cores": 1.0, + "id": "ID000033", + "category": "damageprofiler", + "avgCPU": 88.6, + "bytesRead": 25744, + "bytesWritten": 391, + "memory": 242940 + }, + { + "name": "damageprofiler_jk2782", + "type": "compute", + "runtime": 16.736, + "command": { + "program": "damageprofiler", + "arguments": [ + "damageprofiler", + "-Xmx4g", + "-i", + "JK2782_rmdup.bam", + "-r", + "Mammoth_MT_Krause.fasta", + "-l", + "100", + "-t", + "15", + "-o", + ".", + "-yaxis_damageplot", + "0.30" + ] + }, + "parents": [ + "endorspy_jk2782", + "endorspy_jk2802" + ], + "children": [ + "qualimap_jk2802", + "qualimap_jk2782" + ], + "files": [], + "cores": 1.0, + "id": "ID000036", + "category": "damageprofiler", + "avgCPU": 88.3, + "bytesRead": 25661, + "bytesWritten": 327, + "memory": 198276 + }, + { + "name": "qualimap_jk2802", + "type": "compute", + "runtime": 15.368, + "command": { + "program": "qualimap", + "arguments": [ + "qualimap", + "bamqc", + "-bam", + "JK2802_rmdup.bam", + "-nt", + "2", + "-outdir", + ".", + "-outformat", + "\"HTML\"", + "--java-mem-size=4G" + ] + }, + "parents": [ + "damageprofiler_jk2802", + "damageprofiler_jk2782" + ], + "children": [ + "multiqc_1" + ], + "files": [], + "cores": 2.0, + "id": "ID000053", + "category": "qualimap", + "avgCPU": 177.7, + "bytesRead": 35038, + "bytesWritten": 1712, + "memory": 209440 + }, + { + "name": "qualimap_jk2782", + "type": "compute", + "runtime": 14.223, + "command": { + "program": "qualimap", + "arguments": [ + "qualimap", + "bamqc", + "-bam", + "JK2782_rmdup.bam", + "-nt", + "2", + "-outdir", + ".", + "-outformat", + "\"HTML\"", + "--java-mem-size=4G" + ] + }, + "parents": [ + "damageprofiler_jk2802", + "damageprofiler_jk2782" + ], + "children": [ + "multiqc_1" + ], + "files": [], + "cores": 2.0, + "id": "ID000054", + "category": "qualimap", + "avgCPU": 181.9, + "bytesRead": 34954, + "bytesWritten": 1937, + "memory": 232196 + }, + { + "name": "multiqc_1", + "type": "compute", + "runtime": 46.376, + "command": { + "program": "multiqc", + "arguments": [ + "multiqc", + "-f", + "multiqc_config.yaml", + "." + ] + }, + "parents": [ + "qualimap_jk2802", + "qualimap_jk2782" + ], + "children": [], + "files": [], + "cores": 1.0, + "id": "ID000056", + "category": "multiqc", + "avgCPU": 93.0, + "bytesRead": 1215169, + "bytesWritten": 22599, + "memory": 139496 + } + ] + } +} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt index b6789542..5e2463f8 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt @@ -25,6 +25,8 @@ package org.opendc.trace.wtf import org.apache.avro.generic.GenericRecord import org.opendc.trace.* import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Duration +import java.time.Instant /** * A [TableReader] implementation for the WTF format. @@ -61,14 +63,14 @@ internal class WtfTaskTableReader(private val reader: LocalParquetReader record["id"] - TASK_WORKFLOW_ID -> record["workflow_id"] - TASK_SUBMIT_TIME -> record["ts_submit"] - TASK_WAIT_TIME -> record["wait_time"] - TASK_RUNTIME -> record["runtime"] + TASK_ID -> (record["id"] as Long).toString() + TASK_WORKFLOW_ID -> (record["workflow_id"] as Long).toString() + TASK_SUBMIT_TIME -> Instant.ofEpochMilli(record["ts_submit"] as Long) + TASK_WAIT_TIME -> Duration.ofMillis(record["wait_time"] as Long) + TASK_RUNTIME -> Duration.ofMillis(record["runtime"] as Long) TASK_REQ_NCPUS -> (record["resource_amount_requested"] as Double).toInt() - TASK_PARENTS -> (record["parents"] as ArrayList).map { it["item"] as Long }.toSet() - TASK_CHILDREN -> (record["children"] as ArrayList).map { it["item"] as Long }.toSet() + TASK_PARENTS -> (record["parents"] as ArrayList).map { it["item"].toString() }.toSet() + TASK_CHILDREN -> (record["children"] as ArrayList).map { it["item"].toString() }.toSet() TASK_GROUP_ID -> record["group_id"] TASK_USER_ID -> record["user_id"] else -> throw IllegalArgumentException("Invalid column") @@ -94,16 +96,7 @@ internal class WtfTaskTableReader(private val reader: LocalParquetReader): Long { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - TASK_ID -> record["id"] as Long - TASK_WORKFLOW_ID -> record["workflow_id"] as Long - TASK_SUBMIT_TIME -> record["ts_submit"] as Long - TASK_WAIT_TIME -> record["wait_time"] as Long - TASK_RUNTIME -> record["runtime"] as Long - else -> throw IllegalArgumentException("Invalid column") - } + throw IllegalArgumentException("Invalid column") } override fun getDouble(column: TableColumn): Double { diff --git a/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt b/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt index a05a523e..b155f265 100644 --- a/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt @@ -28,6 +28,8 @@ import org.junit.jupiter.api.assertThrows import org.opendc.trace.* import java.io.File import java.net.URL +import java.time.Duration +import java.time.Instant /** * Test suite for the [WtfTraceFormat] class. @@ -91,20 +93,20 @@ class WtfTraceFormatTest { assertAll( { assertTrue(reader.nextRow()) }, - { assertEquals(362334516345962206, reader.getLong(TASK_ID)) }, - { assertEquals(1078341553348591493, reader.getLong(TASK_WORKFLOW_ID)) }, - { assertEquals(245604, reader.getLong(TASK_SUBMIT_TIME)) }, - { assertEquals(8163, reader.getLong(TASK_RUNTIME)) }, - { assertEquals(setOf(584055316413447529, 133113685133695608, 1008582348422865408), reader.get(TASK_PARENTS)) }, + { assertEquals("362334516345962206", reader.get(TASK_ID)) }, + { assertEquals("1078341553348591493", reader.get(TASK_WORKFLOW_ID)) }, + { assertEquals(Instant.ofEpochMilli(245604), reader.get(TASK_SUBMIT_TIME)) }, + { assertEquals(Duration.ofMillis(8163), reader.get(TASK_RUNTIME)) }, + { assertEquals(setOf("584055316413447529", "133113685133695608", "1008582348422865408"), reader.get(TASK_PARENTS)) }, ) assertAll( { assertTrue(reader.nextRow()) }, - { assertEquals(502010169100446658, reader.getLong(TASK_ID)) }, - { assertEquals(1078341553348591493, reader.getLong(TASK_WORKFLOW_ID)) }, - { assertEquals(251325, reader.getLong(TASK_SUBMIT_TIME)) }, - { assertEquals(8216, reader.getLong(TASK_RUNTIME)) }, - { assertEquals(setOf(584055316413447529, 133113685133695608, 1008582348422865408), reader.get(TASK_PARENTS)) }, + { assertEquals("502010169100446658", reader.get(TASK_ID)) }, + { assertEquals("1078341553348591493", reader.get(TASK_WORKFLOW_ID)) }, + { assertEquals(Instant.ofEpochMilli(251325), reader.get(TASK_SUBMIT_TIME)) }, + { assertEquals(Duration.ofMillis(8216), reader.get(TASK_RUNTIME)) }, + { assertEquals(setOf("584055316413447529", "133113685133695608", "1008582348422865408"), reader.get(TASK_PARENTS)) }, ) reader.close() diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt index a390fe08..9ee3736e 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/TraceReplayer.kt @@ -81,17 +81,17 @@ internal class TraceReplayer(private val trace: Trace) { try { while (reader.nextRow()) { // Bag of tasks without workflow ID all share the same workflow - val workflowId = if (reader.hasColumn(TASK_WORKFLOW_ID)) reader.getLong(TASK_WORKFLOW_ID) else 0L + val workflowId = if (reader.hasColumn(TASK_WORKFLOW_ID)) reader.get(TASK_WORKFLOW_ID).toLong() else 0L val workflow = jobs.computeIfAbsent(workflowId) { id -> Job(UUID(0L, id), "", HashSet(), HashMap()) } - val id = reader.getLong(TASK_ID) + val id = reader.get(TASK_ID).toLong() val grantedCpus = if (reader.hasColumn(TASK_ALLOC_NCPUS)) reader.getInt(TASK_ALLOC_NCPUS) else reader.getInt(TASK_REQ_NCPUS) - val submitTime = reader.getLong(TASK_SUBMIT_TIME) - val runtime = reader.getLong(TASK_RUNTIME) - val flops: Long = 4000 * runtime * grantedCpus + val submitTime = reader.get(TASK_SUBMIT_TIME) + val runtime = reader.get(TASK_RUNTIME) + val flops: Long = 4000 * runtime.seconds * grantedCpus val workload = SimFlopsWorkload(flops) val task = Task( UUID(0L, id), @@ -100,14 +100,14 @@ internal class TraceReplayer(private val trace: Trace) { mapOf( "workload" to workload, WORKFLOW_TASK_CORES to grantedCpus, - WORKFLOW_TASK_DEADLINE to (runtime * 1000) + WORKFLOW_TASK_DEADLINE to runtime.toMillis() ), ) tasks[id] = task - taskDependencies[task] = reader.get(TASK_PARENTS) + taskDependencies[task] = reader.get(TASK_PARENTS).map { it.toLong() }.toSet() - (workflow.metadata as MutableMap).merge("WORKFLOW_SUBMIT_TIME", submitTime) { a, b -> min(a as Long, b as Long) } + (workflow.metadata as MutableMap).merge("WORKFLOW_SUBMIT_TIME", submitTime.toEpochMilli()) { a, b -> min(a as Long, b as Long) } (workflow.tasks as MutableSet).add(task) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 427cdb52..60e67e2b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -49,6 +49,7 @@ include(":opendc-trace:opendc-trace-api") include(":opendc-trace:opendc-trace-gwf") include(":opendc-trace:opendc-trace-swf") include(":opendc-trace:opendc-trace-wtf") +include(":opendc-trace:opendc-trace-wfformat") include(":opendc-trace:opendc-trace-bitbrains") include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") -- cgit v1.2.3 From 49dd8377c8bfde1e64e411c6a6f921c768b9b53b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 12 Sep 2021 11:22:07 +0200 Subject: refactor(trace): Add API for accessing available table columns This change adds a new API to the Table interface for accessing the table columns that the table supports. This does not necessarily mean that the column will have a value for every row, but that the table format has defined this particular column. --- .../capelin/trace/azure/AzureResourceStateTable.kt | 13 ++++----- .../capelin/trace/azure/AzureResourceTable.kt | 17 +++++------- .../capelin/trace/bp/BPResourceStateTable.kt | 17 +++++------- .../capelin/trace/bp/BPResourceTable.kt | 17 +++++------- .../capelin/trace/sv/SvResourceStateTable.kt | 31 ++++++++++------------ .../src/main/kotlin/org/opendc/trace/Table.kt | 4 +-- .../trace/bitbrains/BitbrainsResourceStateTable.kt | 31 ++++++++++------------ .../kotlin/org/opendc/trace/gwf/GwfTaskTable.kt | 21 +++++++-------- .../kotlin/org/opendc/trace/swf/SwfTaskTable.kt | 27 +++++++++---------- .../org/opendc/trace/wfformat/WfFormatTaskTable.kt | 19 ++++++------- .../kotlin/org/opendc/trace/wtf/WtfTaskTable.kt | 27 +++++++++---------- 11 files changed, 97 insertions(+), 127 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt index f8e57d1d..f98f4b2c 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt @@ -46,14 +46,11 @@ internal class AzureResourceStateTable(private val factory: CsvFactory, path: Pa override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - else -> false - } - } + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_CPU_USAGE_PCT + ) override fun newReader(): TableReader { val it = partitions.iterator() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt index bbfd25ff..c9d4f7eb 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt @@ -34,16 +34,13 @@ internal class AzureResourceTable(private val factory: CsvFactory, private val p override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } - } + override val columns: List> = listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_NCPUS, + RESOURCE_MEM_CAPACITY + ) override fun newReader(): TableReader { return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt index 35bfd5ef..f051bf88 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt @@ -34,16 +34,13 @@ internal class BPResourceStateTable(private val path: Path) : Table { override val name: String = TABLE_RESOURCE_STATES override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_DURATION -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_USAGE -> true - else -> false - } - } + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_DURATION, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_USAGE, + ) override fun newReader(): TableReader { val reader = LocalParquetReader(path.resolve("trace.parquet")) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt index bff8c55e..5b0f013f 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt @@ -34,16 +34,13 @@ internal class BPResourceTable(private val path: Path) : Table { override val name: String = TABLE_RESOURCES override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } - } + override val columns: List> = listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_NCPUS, + RESOURCE_MEM_CAPACITY + ) override fun newReader(): TableReader { val reader = LocalParquetReader(path.resolve("meta.parquet")) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt index 3a9bda69..67140fe9 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt @@ -46,23 +46,20 @@ internal class SvResourceStateTable(path: Path) : Table { override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_CLUSTER_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_CAPACITY -> true - RESOURCE_STATE_CPU_USAGE -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_STATE_CPU_DEMAND -> true - RESOURCE_STATE_CPU_READY_PCT -> true - RESOURCE_STATE_MEM_CAPACITY -> true - RESOURCE_STATE_DISK_READ -> true - RESOURCE_STATE_DISK_WRITE -> true - else -> false - } - } + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_CLUSTER_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT, + RESOURCE_STATE_CPU_DEMAND, + RESOURCE_STATE_CPU_READY_PCT, + RESOURCE_STATE_MEM_CAPACITY, + RESOURCE_STATE_DISK_READ, + RESOURCE_STATE_DISK_WRITE, + ) override fun newReader(): TableReader { val it = partitions.iterator() diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt index 11e5d6b7..6aca2051 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt @@ -37,9 +37,9 @@ public interface Table { public val isSynthetic: Boolean /** - * Determine whether the specified [column] is supported by this table. + * The list of columns supported in this table. */ - public fun isSupported(column: TableColumn<*>): Boolean + public val columns: List> /** * Open a [TableReader] for this table. diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index 846d5c8a..883bf8f4 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -47,23 +47,20 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, priv override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_CAPACITY -> true - RESOURCE_STATE_CPU_USAGE -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_STATE_MEM_CAPACITY -> true - RESOURCE_STATE_MEM_USAGE -> true - RESOURCE_STATE_DISK_READ -> true - RESOURCE_STATE_DISK_WRITE -> true - RESOURCE_STATE_NET_RX -> true - RESOURCE_STATE_NET_TX -> true - else -> false - } - } + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT, + RESOURCE_STATE_MEM_CAPACITY, + RESOURCE_STATE_MEM_USAGE, + RESOURCE_STATE_DISK_READ, + RESOURCE_STATE_DISK_WRITE, + RESOURCE_STATE_NET_RX, + RESOURCE_STATE_NET_TX, + ) override fun newReader(): TableReader { val it = partitions.iterator() diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt index 80a99d10..fd7bd068 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt @@ -34,18 +34,15 @@ internal class GwfTaskTable(private val factory: CsvFactory, private val url: UR override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - TASK_WORKFLOW_ID -> true - TASK_ID -> true - TASK_SUBMIT_TIME -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_ALLOC_NCPUS -> true - TASK_PARENTS -> true - else -> false - } - } + override val columns: List> = listOf( + TASK_WORKFLOW_ID, + TASK_ID, + TASK_SUBMIT_TIME, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_ALLOC_NCPUS, + TASK_PARENTS + ) override fun newReader(): TableReader { return GwfTaskTableReader(factory.createParser(url)) diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt index 12a51a2f..7ec0d607 100644 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt @@ -34,21 +34,18 @@ internal class SwfTaskTable(private val path: Path) : Table { override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - TASK_ID -> true - TASK_SUBMIT_TIME -> true - TASK_WAIT_TIME -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_ALLOC_NCPUS -> true - TASK_PARENTS -> true - TASK_STATUS -> true - TASK_GROUP_ID -> true - TASK_USER_ID -> true - else -> false - } - } + override val columns: List> = listOf( + TASK_ID, + TASK_SUBMIT_TIME, + TASK_WAIT_TIME, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_ALLOC_NCPUS, + TASK_PARENTS, + TASK_STATUS, + TASK_GROUP_ID, + TASK_USER_ID + ) override fun newReader(): TableReader { val reader = path.bufferedReader() diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt index 907bf7ff..7b7f979f 100644 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt @@ -34,17 +34,14 @@ internal class WfFormatTaskTable(private val factory: JsonFactory, private val p override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - TASK_ID -> true - TASK_WORKFLOW_ID -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_PARENTS -> true - TASK_CHILDREN -> true - else -> false - } - } + override val columns: List> = listOf( + TASK_ID, + TASK_WORKFLOW_ID, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_PARENTS, + TASK_CHILDREN + ) override fun newReader(): TableReader { val parser = factory.createParser(path.toFile()) diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt index be26f540..74202718 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt @@ -35,21 +35,18 @@ internal class WtfTaskTable(private val path: Path) : Table { override val isSynthetic: Boolean = false - override fun isSupported(column: TableColumn<*>): Boolean { - return when (column) { - TASK_ID -> true - TASK_WORKFLOW_ID -> true - TASK_SUBMIT_TIME -> true - TASK_WAIT_TIME -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_PARENTS -> true - TASK_CHILDREN -> true - TASK_GROUP_ID -> true - TASK_USER_ID -> true - else -> false - } - } + override val columns: List> = listOf( + TASK_ID, + TASK_WORKFLOW_ID, + TASK_SUBMIT_TIME, + TASK_WAIT_TIME, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_PARENTS, + TASK_CHILDREN, + TASK_GROUP_ID, + TASK_USER_ID + ) override fun newReader(): TableReader { val reader = LocalParquetReader(path.resolve("tasks/schema-1.0")) -- cgit v1.2.3 From 3fb1eac8290181638a6571e4d7a49e53b7f3d7d1 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 12 Sep 2021 11:40:15 +0200 Subject: feat(trace): Add synthetic resource table for Bitbrains format This change adds a synthetic resource table for the Bitbrains format, which can be used to list the available partitions in the trace. --- .../trace/bitbrains/BitbrainsResourceStateTable.kt | 2 +- .../trace/bitbrains/BitbrainsResourceTable.kt | 61 ++++++++++++ .../bitbrains/BitbrainsResourceTableReader.kt | 108 +++++++++++++++++++++ .../org/opendc/trace/bitbrains/BitbrainsTrace.kt | 12 +-- .../trace/bitbrains/BitbrainsTraceFormatTest.kt | 23 ++++- 5 files changed, 195 insertions(+), 11 deletions(-) create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index 883bf8f4..c9e5954d 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -33,7 +33,7 @@ import kotlin.io.path.nameWithoutExtension /** * The resource state [Table] in the Bitbrains format. */ -internal class BitbrainsResourceStateTable(private val factory: CsvFactory, private val path: Path) : Table { +internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path: Path) : Table { /** * The partitions that belong to the table. */ diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt new file mode 100644 index 00000000..bc4f0b7d --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resources [Table] in the Bitbrains format. + */ +internal class BitbrainsResourceTable(private val factory: CsvFactory, path: Path) : Table { + /** + * The VMs that belong to the table. + */ + private val vms = + Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + + override val name: String = TABLE_RESOURCES + + override val isSynthetic: Boolean = true + + override val columns: List> = listOf(RESOURCE_ID) + + override fun newReader(): TableReader { + return BitbrainsResourceTableReader(factory, vms) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } + + override fun toString(): String = "BitbrainsResourceTable" +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt new file mode 100644 index 00000000..c02dc5ae --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * A [TableReader] for the Bitbrains resource table. + */ +internal class BitbrainsResourceTableReader(private val factory: CsvFactory, vms: Map) : TableReader { + /** + * An iterator to iterate over the resource entries. + */ + private val it = vms.iterator() + + override fun nextRow(): Boolean { + reset() + + while (it.hasNext()) { + val (name, path) = it.next() + + val parser = factory.createParser(path.toFile()) + val reader = BitbrainsResourceStateTableReader(name, parser) + + try { + if (!reader.nextRow()) { + continue + } + + id = reader.get(RESOURCE_STATE_ID) + return true + } finally { + reader.close() + } + } + + return false + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_ID -> id + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + throw IllegalArgumentException("Invalid column") + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + throw IllegalArgumentException("Invalid column") + } + + override fun close() {} + + /** + * State fields of the reader. + */ + private var id: String? = null + + /** + * Reset the state of the reader. + */ + private fun reset() { + id = null + } +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt index 5a2d4243..bcd8dd52 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt @@ -30,16 +30,16 @@ import java.nio.file.Path * [Trace] implementation for the Bitbrains format. */ public class BitbrainsTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCE_STATES) + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name + override fun containsTable(name: String): Boolean = tables.contains(name) override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null + return when (name) { + TABLE_RESOURCES -> BitbrainsResourceTable(factory, path) + TABLE_RESOURCE_STATES -> BitbrainsResourceStateTable(factory, path) + else -> null } - - return BitbrainsResourceStateTable(factory, path) } override fun toString(): String = "BitbrainsTrace[$path]" diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt index 550805d3..ff4a33f8 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt @@ -25,9 +25,7 @@ package org.opendc.trace.bitbrains import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows -import org.opendc.trace.RESOURCE_STATE_CPU_USAGE -import org.opendc.trace.RESOURCE_STATE_TIMESTAMP -import org.opendc.trace.TABLE_RESOURCE_STATES +import org.opendc.trace.* import java.net.URL /** @@ -58,7 +56,7 @@ class BitbrainsTraceFormatTest { val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) val trace = format.open(url) - assertEquals(listOf(TABLE_RESOURCE_STATES), trace.tables) + assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) } @Test @@ -81,6 +79,23 @@ class BitbrainsTraceFormatTest { assertNull(trace.getTable("test")) } + @Test + fun testResources() { + val format = BitbrainsTraceFormat() + val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("bitbrains", reader.get(RESOURCE_ID)) }, + { assertFalse(reader.nextRow()) } + ) + + reader.close() + } + @Test fun testSmoke() { val format = BitbrainsTraceFormat() -- cgit v1.2.3 From 992b65396f55c0e12b36823d191dea8e03dd45ba Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 12 Sep 2021 11:46:03 +0200 Subject: feat(trace): Support dynamic resolving of trace formats This change enables users to open traces of various trace formats by dynamically specifying the format name. The trace API will use the service loader to resolve the available trace formats on the classpath. --- .../src/main/kotlin/org/opendc/trace/Trace.kt | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt index 36e93b52..0ae45e86 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt @@ -22,6 +22,11 @@ package org.opendc.trace +import org.opendc.trace.spi.TraceFormat +import java.io.File +import java.net.URL +import java.nio.file.Path + /** * A trace is a collection of related tables that characterize a workload. */ @@ -40,4 +45,34 @@ public interface Trace { * Obtain a [Table] with the specified [name]. */ public fun getTable(name: String): Table? + + public companion object { + /** + * Open a [Trace] at the specified [url] in the given [format]. + * + * @throws IllegalArgumentException if [format] is not supported. + */ + public fun open(url: URL, format: String): Trace { + val provider = requireNotNull(TraceFormat.byName(format)) { "Unknown format $format" } + return provider.open(url) + } + + /** + * Open a [Trace] at the specified [path] in the given [format]. + * + * @throws IllegalArgumentException if [format] is not supported. + */ + public fun open(path: File, format: String): Trace { + return open(path.toURI().toURL(), format) + } + + /** + * Open a [Trace] at the specified [path] in the given [format]. + * + * @throws IllegalArgumentException if [format] is not supported. + */ + public fun open(path: Path, format: String): Trace { + return open(path.toUri().toURL(), format) + } + } } -- cgit v1.2.3 From 144d9d0c118097900c086b7fb8b1cf22a788592b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 13 Sep 2021 12:22:32 +0200 Subject: build(telemetry): Update to OpenTelemetry 1.6.0 This change updates the opentelemetry-java library to version 1.6.0. --- gradle/libs.versions.toml | 6 +++--- .../org/opendc/experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../org/opendc/telemetry/compute/ComputeMetricExporter.kt | 11 ++++++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ddede2e8..3f0e180b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,9 +13,9 @@ kotlinx-coroutines = "1.5.1" ktor = "1.6.3" log4j = "2.14.1" mockk = "1.12.0" -opentelemetry-main = "1.5.0" -opentelemetry-metrics = "1.5.0-alpha" -opentelemetry-semconv = "1.5.0-alpha" +opentelemetry-main = "1.6.0" +opentelemetry-metrics = "1.6.0-alpha" +opentelemetry-semconv = "1.6.0-alpha" parquet = "1.12.0" progressbar = "0.9.0" sentry = "5.1.2" diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 44cf92a8..cf88535d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -110,7 +110,7 @@ class CapelinIntegrationTest { { assertEquals(206667809529, monitor.totalGrantedWork) { "Incorrect granted burst" } }, { assertEquals(1151611104, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedWork) { "Incorrect interfered burst" } }, - { assertEquals(1.7671768767192196E7, monitor.totalPowerDraw, 0.01) { "Incorrect power draw" } }, + { assertEquals(1.8175860403178412E7, monitor.totalPowerDraw, 0.01) { "Incorrect power draw" } }, ) } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt index 95e7ff9e..57d43c60 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt @@ -59,7 +59,7 @@ public class ComputeMetricExporter( when (metric.name) { "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v } "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v } - "power.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.powerDraw = v } + "power.usage" -> mapDoubleHistogram(metric, hostMetrics) { m, v -> m.powerDraw = v } "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v } "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v } "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } @@ -105,6 +105,15 @@ public class ComputeMetricExporter( } } + private fun mapDoubleHistogram(data: MetricData, hostMetrics: MutableMap, block: (HBuffer, Double) -> Unit) { + val points = data.doubleHistogramData?.points ?: emptyList() + for (point in points) { + val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } + block(hostMetric, point.sum / point.count) + } + } + private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HBuffer, Long) -> Unit) { val points = data?.longSumData?.points ?: emptyList() for (point in points) { -- cgit v1.2.3 From 7960791430b0536df4704493c01d32e38f37f022 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 14 Sep 2021 12:52:17 +0200 Subject: refactor(experiments): Remove energy experiments shell This change removes the energy experiments. The experiments only provided a setup for the original experiments and is not able to reproduce the results without further worker. --- .../opendc-experiments-energy21/.gitignore | 3 - .../opendc-experiments-energy21/build.gradle.kts | 47 ----- .../experiments/energy21/EnergyExperiment.kt | 208 --------------------- .../src/main/resources/application.conf | 14 -- settings.gradle.kts | 1 - 5 files changed, 273 deletions(-) delete mode 100644 opendc-experiments/opendc-experiments-energy21/.gitignore delete mode 100644 opendc-experiments/opendc-experiments-energy21/build.gradle.kts delete mode 100644 opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt delete mode 100644 opendc-experiments/opendc-experiments-energy21/src/main/resources/application.conf diff --git a/opendc-experiments/opendc-experiments-energy21/.gitignore b/opendc-experiments/opendc-experiments-energy21/.gitignore deleted file mode 100644 index 55da79f8..00000000 --- a/opendc-experiments/opendc-experiments-energy21/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -input/ -output/ -.ipynb_checkpoints diff --git a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts deleted file mode 100644 index cc58e5f1..00000000 --- a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -description = "Experiments for the OpenDC Energy work" - -/* Build configuration */ -plugins { - `experiment-conventions` - `testing-conventions` -} - -dependencies { - api(platform(projects.opendcPlatform)) - api(projects.opendcHarness.opendcHarnessApi) - implementation(projects.opendcSimulator.opendcSimulatorCore) - implementation(projects.opendcSimulator.opendcSimulatorCompute) - implementation(projects.opendcCompute.opendcComputeSimulator) - implementation(projects.opendcExperiments.opendcExperimentsCapelin) - implementation(projects.opendcTelemetry.opendcTelemetrySdk) - implementation(projects.opendcTelemetry.opendcTelemetryCompute) - implementation(libs.kotlin.logging) - implementation(libs.config) - - implementation(libs.parquet) { - exclude(group = "org.slf4j", module = "slf4j-log4j12") - exclude(group = "log4j") - } -} diff --git a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt deleted file mode 100644 index d9194969..00000000 --- a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.energy21 - -import com.typesafe.config.ConfigFactory -import io.opentelemetry.api.metrics.MeterProvider -import io.opentelemetry.sdk.metrics.export.MetricProducer -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.coroutineScope -import mu.KotlinLogging -import org.opendc.compute.service.ComputeService -import org.opendc.compute.service.scheduler.ComputeScheduler -import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.filters.RamFilter -import org.opendc.compute.service.scheduler.filters.VCpuFilter -import org.opendc.compute.simulator.SimHost -import org.opendc.experiments.capelin.* -import org.opendc.experiments.capelin.export.parquet.ParquetExportMonitor -import org.opendc.experiments.capelin.trace.StreamingParquetTraceReader -import org.opendc.harness.dsl.Experiment -import org.opendc.harness.dsl.anyOf -import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider -import org.opendc.simulator.compute.kernel.cpufreq.PerformanceScalingGovernor -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.compute.power.* -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.telemetry.compute.collectServiceMetrics -import org.opendc.telemetry.compute.withMonitor -import java.io.File -import java.time.Clock -import java.util.* - -/** - * Experiments for the OpenDC project on Energy modeling. - */ -public class EnergyExperiment : Experiment("Energy Modeling 2021") { - /** - * The logger for this portfolio instance. - */ - private val logger = KotlinLogging.logger {} - - /** - * The configuration to use. - */ - private val config = ConfigFactory.load().getConfig("opendc.experiments.energy21") - - /** - * The traces to test. - */ - private val trace by anyOf("solvinity") - - /** - * The power models to test. - */ - private val powerModel by anyOf(PowerModelType.LINEAR, PowerModelType.CUBIC, PowerModelType.INTERPOLATION) - - override fun doRun(repeat: Int): Unit = runBlockingSimulation { - val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), - weighers = listOf(), - subsetSize = Int.MAX_VALUE - ) - - val meterProvider: MeterProvider = createMeterProvider(clock) - val monitor = ParquetExportMonitor(File(config.getString("output-path")), "power_model=$powerModel/run_id=$repeat", 4096) - val trace = StreamingParquetTraceReader(File(config.getString("trace-path"), trace)) - - withComputeService(clock, meterProvider, allocationPolicy) { scheduler -> - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - processTrace( - clock, - trace, - scheduler, - monitor - ) - } - } - - val monitorResults = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) - logger.debug { - "Finish SUBMIT=${monitorResults.instanceCount} " + - "FAIL=${monitorResults.failedInstanceCount} " + - "QUEUE=${monitorResults.queuedInstanceCount} " + - "RUNNING=${monitorResults.runningInstanceCount}" - } - } - - /** - * Construct the environment for a simulated compute service.. - */ - public suspend fun withComputeService( - clock: Clock, - meterProvider: MeterProvider, - scheduler: ComputeScheduler, - block: suspend CoroutineScope.(ComputeService) -> Unit - ): Unit = coroutineScope { - val model = createMachineModel() - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val hosts = List(64) { id -> - SimHost( - UUID(0, id.toLong()), - "node-$id", - model, - emptyMap(), - coroutineContext, - interpreter, - meterProvider.get("opendc-compute-simulator"), - SimFairShareHypervisorProvider(), - PerformanceScalingGovernor(), - powerModel.driver - ) - } - - val serviceMeter = meterProvider.get("opendc-compute") - val service = - ComputeService(coroutineContext, clock, serviceMeter, scheduler) - - for (host in hosts) { - service.addHost(host) - } - - try { - block(this, service) - } finally { - service.close() - hosts.forEach(SimHost::close) - } - } - - /** - * The machine model based on: https://www.spec.org/power_ssj2008/results/res2020q1/power_ssj2008-20191125-01012.html - */ - private fun createMachineModel(): MachineModel { - val node = ProcessingNode("AMD", "am64", "EPYC 7742", 64) - val cpus = List(node.coreCount) { id -> ProcessingUnit(node, id, 3400.0) } - val memory = List(8) { MemoryUnit("Samsung", "Unknown", 2933.0, 16_000) } - - return MachineModel(cpus, memory) - } - - /** - * The power models to test. - */ - public enum class PowerModelType { - CUBIC { - override val driver: PowerDriver = SimplePowerDriver(CubicPowerModel(206.0, 56.4)) - }, - - LINEAR { - override val driver: PowerDriver = SimplePowerDriver(LinearPowerModel(206.0, 56.4)) - }, - - SQRT { - override val driver: PowerDriver = SimplePowerDriver(SqrtPowerModel(206.0, 56.4)) - }, - - SQUARE { - override val driver: PowerDriver = SimplePowerDriver(SquarePowerModel(206.0, 56.4)) - }, - - INTERPOLATION { - override val driver: PowerDriver = SimplePowerDriver( - InterpolationPowerModel( - listOf(56.4, 100.0, 107.0, 117.0, 127.0, 138.0, 149.0, 162.0, 177.0, 191.0, 206.0) - ) - ) - }, - - MSE { - override val driver: PowerDriver = SimplePowerDriver(MsePowerModel(206.0, 56.4, 1.4)) - }, - - ASYMPTOTIC { - override val driver: PowerDriver = SimplePowerDriver(AsymptoticPowerModel(206.0, 56.4, 0.3, false)) - }, - - ASYMPTOTIC_DVFS { - override val driver: PowerDriver = SimplePowerDriver(AsymptoticPowerModel(206.0, 56.4, 0.3, true)) - }; - - public abstract val driver: PowerDriver - } -} diff --git a/opendc-experiments/opendc-experiments-energy21/src/main/resources/application.conf b/opendc-experiments/opendc-experiments-energy21/src/main/resources/application.conf deleted file mode 100644 index 263da0fe..00000000 --- a/opendc-experiments/opendc-experiments-energy21/src/main/resources/application.conf +++ /dev/null @@ -1,14 +0,0 @@ -# Default configuration for the energy experiments -opendc.experiments.energy21 { - # Path to the directory containing the input traces - trace-path = input/traces - - # Path to the output directory to write the results to - output-path = output -} - -opendc.experiments.capelin { - env-path = input/environments/ - trace-path = input/traces/ - output-path = output -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 60e67e2b..933febe0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,7 +31,6 @@ include(":opendc-faas:opendc-faas-api") include(":opendc-faas:opendc-faas-service") include(":opendc-faas:opendc-faas-simulator") include(":opendc-experiments:opendc-experiments-capelin") -include(":opendc-experiments:opendc-experiments-energy21") include(":opendc-experiments:opendc-experiments-serverless20") include(":opendc-experiments:opendc-experiments-tf20") include(":opendc-web:opendc-web-api") -- cgit v1.2.3 From eef8ea3ab40a4e4a12ba96f839c35c5804884bc1 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 13 Sep 2021 12:25:51 +0200 Subject: refactor(capelin): Improve ParquetDataWriter implementation This change improves the ParquetDataWriter class to support more complex use-cases. It now allows subclasses to modify the writer options. In addition to this, a subclass for writing server data is added. --- .../capelin/export/parquet/ParquetDataWriter.kt | 125 ++++++++++++--------- .../capelin/export/parquet/ParquetExportMonitor.kt | 14 ++- .../export/parquet/ParquetHostDataWriter.kt | 74 +++++++----- .../export/parquet/ParquetServerDataWriter.kt | 73 ++++++++++++ .../export/parquet/ParquetServiceDataWriter.kt | 46 ++++---- 5 files changed, 225 insertions(+), 107 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt index c5cb80e2..5684bde9 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt @@ -25,11 +25,13 @@ package org.opendc.experiments.capelin.export.parquet import mu.KotlinLogging import org.apache.avro.Schema import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.example.Paper.schema import org.apache.parquet.hadoop.ParquetFileWriter +import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.trace.util.parquet.LocalOutputFile -import java.io.Closeable import java.io.File import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.BlockingQueue @@ -38,50 +40,94 @@ import kotlin.concurrent.thread /** * A writer that writes data in Parquet format. */ -public open class ParquetDataWriter( - private val path: File, +abstract class ParquetDataWriter( + path: File, private val schema: Schema, - private val converter: (T, GenericData.Record) -> Unit, - private val bufferSize: Int = 4096 -) : Runnable, Closeable { + bufferSize: Int = 4096 +) : AutoCloseable { /** * The logging instance to use. */ private val logger = KotlinLogging.logger {} /** - * The writer to write the Parquet file. + * The queue of commands to process. */ - private val writer = AvroParquetWriter.builder(LocalOutputFile(path)) - .withSchema(schema) - .withCompressionCodec(CompressionCodecName.SNAPPY) - .withPageSize(4 * 1024 * 1024) // For compression - .withRowGroupSize(16 * 1024 * 1024) // For write buffering (Page size) - .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) - .build() + private val queue: BlockingQueue = ArrayBlockingQueue(bufferSize) /** - * The queue of commands to process. + * An exception to be propagated to the actual writer. */ - private val queue: BlockingQueue = ArrayBlockingQueue(bufferSize) + private var exception: Throwable? = null /** * The thread that is responsible for writing the Parquet records. */ - private val writerThread = thread(start = false, name = this.toString()) { run() } + private val writerThread = thread(start = false, name = this.toString()) { + val writer = let { + val builder = AvroParquetWriter.builder(LocalOutputFile(path)) + .withSchema(schema) + .withCompressionCodec(CompressionCodecName.ZSTD) + .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) + buildWriter(builder) + } + + val queue = queue + val buf = mutableListOf() + var shouldStop = false + + try { + while (!shouldStop) { + try { + process(writer, queue.take()) + } catch (e: InterruptedException) { + shouldStop = true + } + + if (queue.drainTo(buf) > 0) { + for (data in buf) { + process(writer, data) + } + buf.clear() + } + } + } catch (e: Throwable) { + logger.error(e) { "Failure in Parquet data writer" } + exception = e + } finally { + writer.close() + } + } + + /** + * Build the [ParquetWriter] used to write the Parquet files. + */ + protected open fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { + return builder.build() + } + + /** + * Convert the specified [data] into a Parquet record. + */ + protected abstract fun convert(builder: GenericRecordBuilder, data: T) /** * Write the specified metrics to the database. */ - public fun write(event: T) { - queue.put(Action.Write(event)) + fun write(data: T) { + val exception = exception + if (exception != null) { + throw IllegalStateException("Writer thread failed", exception) + } + + queue.put(data) } /** * Signal the writer to stop. */ - public override fun close() { - queue.put(Action.Stop) + override fun close() { + writerThread.interrupt() writerThread.join() } @@ -90,38 +136,11 @@ public open class ParquetDataWriter( } /** - * Start the writer thread. + * Process the specified [data] to be written to the Parquet file. */ - override fun run() { - try { - loop@ while (true) { - val action = queue.take() - when (action) { - is Action.Stop -> break@loop - is Action.Write<*> -> { - val record = GenericData.Record(schema) - @Suppress("UNCHECKED_CAST") - converter(action.data as T, record) - writer.write(record) - } - } - } - } catch (e: Throwable) { - logger.error("Writer failed", e) - } finally { - writer.close() - } - } - - public sealed class Action { - /** - * A poison pill that will stop the writer thread. - */ - public object Stop : Action() - - /** - * Write the specified metrics to the database. - */ - public data class Write(val data: T) : Action() + private fun process(writer: ParquetWriter, data: T) { + val builder = GenericRecordBuilder(schema) + convert(builder, data) + writer.write(builder.build()) } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt index 79b84e9d..b057e932 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt @@ -24,22 +24,33 @@ package org.opendc.experiments.capelin.export.parquet import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServerData import org.opendc.telemetry.compute.table.ServiceData import java.io.File /** * A [ComputeMonitor] that logs the events to a Parquet file. */ -public class ParquetExportMonitor(base: File, partition: String, bufferSize: Int) : ComputeMonitor, AutoCloseable { +class ParquetExportMonitor(base: File, partition: String, bufferSize: Int) : ComputeMonitor, AutoCloseable { + private val serverWriter = ParquetServerDataWriter( + File(base, "server/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + private val hostWriter = ParquetHostDataWriter( File(base, "host/$partition/data.parquet").also { it.parentFile.mkdirs() }, bufferSize ) + private val serviceWriter = ParquetServiceDataWriter( File(base, "service/$partition/data.parquet").also { it.parentFile.mkdirs() }, bufferSize ) + override fun record(data: ServerData) { + serverWriter.write(data) + } + override fun record(data: HostData) { hostWriter.write(data) } @@ -51,5 +62,6 @@ public class ParquetExportMonitor(base: File, partition: String, bufferSize: Int override fun close() { hostWriter.close() serviceWriter.close() + serverWriter.close() } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt index 8912c12e..7062a275 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt @@ -25,6 +25,10 @@ package org.opendc.experiments.capelin.export.parquet import org.apache.avro.Schema import org.apache.avro.SchemaBuilder import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.opendc.compute.service.driver.HostState import org.opendc.telemetry.compute.table.HostData import java.io.File @@ -32,42 +36,52 @@ import java.io.File * A Parquet event writer for [HostData]s. */ public class ParquetHostDataWriter(path: File, bufferSize: Int) : - ParquetDataWriter(path, schema, convert, bufferSize) { + ParquetDataWriter(path, SCHEMA, bufferSize) { - override fun toString(): String = "host-writer" + override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { + return builder + .withDictionaryEncoding("host_id", true) + .build() + } - public companion object { - private val convert: (HostData, GenericData.Record) -> Unit = { data, record -> - record.put("host_id", data.host.name) - record.put("state", data.host.state.name) - record.put("timestamp", data.timestamp) - record.put("total_work", data.totalWork) - record.put("granted_work", data.grantedWork) - record.put("overcommitted_work", data.overcommittedWork) - record.put("interfered_work", data.interferedWork) - record.put("cpu_usage", data.cpuUsage) - record.put("cpu_demand", data.cpuDemand) - record.put("power_draw", data.powerDraw) - record.put("instance_count", data.instanceCount) - record.put("cores", data.host.model.cpuCount) - } + override fun convert(builder: GenericRecordBuilder, data: HostData) { + builder["timestamp"] = data.timestamp + builder["host_id"] = data.host.name + builder["powered_on"] = data.host.state == HostState.UP + builder["uptime"] = data.uptime + builder["downtime"] = data.downtime + builder["total_work"] = data.totalWork + builder["granted_work"] = data.grantedWork + builder["overcommitted_work"] = data.overcommittedWork + builder["interfered_work"] = data.interferedWork + builder["cpu_usage"] = data.cpuUsage + builder["cpu_demand"] = data.cpuDemand + builder["power_draw"] = data.powerDraw + builder["num_instances"] = data.instanceCount + builder["num_cpus"] = data.host.model.cpuCount + } + + override fun toString(): String = "host-writer" - private val schema: Schema = SchemaBuilder + companion object { + private val SCHEMA: Schema = SchemaBuilder .record("host") .namespace("org.opendc.telemetry.compute") .fields() - .name("timestamp").type().longType().noDefault() - .name("host_id").type().stringType().noDefault() - .name("state").type().stringType().noDefault() - .name("requested_work").type().longType().noDefault() - .name("granted_work").type().longType().noDefault() - .name("overcommitted_work").type().longType().noDefault() - .name("interfered_work").type().longType().noDefault() - .name("cpu_usage").type().doubleType().noDefault() - .name("cpu_demand").type().doubleType().noDefault() - .name("power_draw").type().doubleType().noDefault() - .name("instance_count").type().intType().noDefault() - .name("cores").type().intType().noDefault() + .requiredLong("timestamp") + .requiredString("host_id") + .requiredBoolean("powered_on") + .requiredLong("uptime") + .requiredLong("downtime") + .requiredDouble("total_work") + .requiredDouble("granted_work") + .requiredDouble("overcommitted_work") + .requiredDouble("interfered_work") + .requiredDouble("cpu_usage") + .requiredDouble("cpu_demand") + .requiredDouble("power_draw") + .requiredInt("num_instances") + .requiredInt("num_cpus") .endRecord() } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt new file mode 100644 index 00000000..9904adde --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.export.parquet + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.opendc.telemetry.compute.table.ServerData +import java.io.File + +/** + * A Parquet event writer for [ServerData]s. + */ +public class ParquetServerDataWriter(path: File, bufferSize: Int) : + ParquetDataWriter(path, SCHEMA, bufferSize) { + + override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { + return builder + .withDictionaryEncoding("server_id", true) + .withDictionaryEncoding("state", true) + .build() + } + + override fun convert(builder: GenericRecordBuilder, data: ServerData) { + builder["timestamp"] = data.timestamp + builder["server_id"] = data.server.uid.toString() + builder["state"] = data.server.state + builder["uptime"] = data.uptime + builder["downtime"] = data.downtime + builder["num_vcpus"] = data.server.flavor.cpuCount + builder["mem_capacity"] = data.server.flavor.memorySize + } + + override fun toString(): String = "server-writer" + + companion object { + private val SCHEMA: Schema = SchemaBuilder + .record("server") + .namespace("org.opendc.telemetry.compute") + .fields() + .requiredLong("timestamp") + .requiredString("server_id") + .requiredString("state") + .requiredLong("uptime") + .requiredLong("downtime") + .requiredInt("num_vcpus") + .requiredLong("mem_capacity") + .endRecord() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt index 36d630f3..e1428fe7 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt @@ -24,7 +24,7 @@ package org.opendc.experiments.capelin.export.parquet import org.apache.avro.Schema import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder import org.opendc.telemetry.compute.table.ServiceData import java.io.File @@ -32,34 +32,34 @@ import java.io.File * A Parquet event writer for [ServiceData]s. */ public class ParquetServiceDataWriter(path: File, bufferSize: Int) : - ParquetDataWriter(path, schema, convert, bufferSize) { + ParquetDataWriter(path, SCHEMA, bufferSize) { - override fun toString(): String = "service-writer" + override fun convert(builder: GenericRecordBuilder, data: ServiceData) { + builder["timestamp"] = data.timestamp + builder["host_total_count"] = data.hostCount + builder["host_available_count"] = data.activeHostCount + builder["instance_total_count"] = data.instanceCount + builder["instance_active_count"] = data.runningInstanceCount + builder["instance_inactive_count"] = data.finishedInstanceCount + builder["instance_waiting_count"] = data.queuedInstanceCount + builder["instance_failed_count"] = data.failedInstanceCount + } - public companion object { - private val convert: (ServiceData, GenericData.Record) -> Unit = { data, record -> - record.put("timestamp", data.timestamp) - record.put("host_total_count", data.hostCount) - record.put("host_available_count", data.activeHostCount) - record.put("instance_total_count", data.instanceCount) - record.put("instance_active_count", data.runningInstanceCount) - record.put("instance_inactive_count", data.finishedInstanceCount) - record.put("instance_waiting_count", data.queuedInstanceCount) - record.put("instance_failed_count", data.failedInstanceCount) - } + override fun toString(): String = "service-writer" - private val schema: Schema = SchemaBuilder + companion object { + private val SCHEMA: Schema = SchemaBuilder .record("service") .namespace("org.opendc.telemetry.compute") .fields() - .name("timestamp").type().longType().noDefault() - .name("host_total_count").type().intType().noDefault() - .name("host_available_count").type().intType().noDefault() - .name("instance_total_count").type().intType().noDefault() - .name("instance_active_count").type().intType().noDefault() - .name("instance_inactive_count").type().intType().noDefault() - .name("instance_waiting_count").type().intType().noDefault() - .name("instance_failed_count").type().intType().noDefault() + .requiredLong("timestamp") + .requiredInt("host_total_count") + .requiredInt("host_available_count") + .requiredInt("instance_total_count") + .requiredInt("instance_active_count") + .requiredInt("instance_inactive_count") + .requiredInt("instance_waiting_count") + .requiredInt("instance_failed_count") .endRecord() } } -- cgit v1.2.3 From 5f0b6b372487d79594cf59010822e160f351e0be Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 13 Sep 2021 14:48:02 +0200 Subject: refactor(telemetry): Simplify CoroutineMetricReader This change simplifies the CoroutineMetricReader implementation by removing the seperation of reader and exporter jobs. --- .../org/opendc/compute/simulator/SimHostTest.kt | 5 ++- .../kotlin/org/opendc/telemetry/compute/Helpers.kt | 3 +- .../sdk/metrics/export/CoroutineMetricReader.kt | 52 +++++++--------------- 3 files changed, 22 insertions(+), 38 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 31215e9a..9fa8af34 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -46,6 +46,7 @@ import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import org.opendc.telemetry.sdk.toOtelClock +import java.time.Duration import java.util.* import kotlin.coroutines.resume @@ -149,7 +150,7 @@ internal class SimHostTest { override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() }, - exportInterval = duration * 1000L + exportInterval = Duration.ofSeconds(duration) ) coroutineScope { @@ -261,7 +262,7 @@ internal class SimHostTest { override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() }, - exportInterval = duration * 1000L + exportInterval = Duration.ofSeconds(duration) ) coroutineScope { diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt index d3d983b9..01df0e69 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt @@ -33,6 +33,7 @@ import org.opendc.compute.service.driver.HostState import org.opendc.telemetry.compute.table.ServiceData import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.time.Clock +import java.time.Duration /** * Attach the specified monitor to the OpenDC Compute service. @@ -42,7 +43,7 @@ public suspend fun withMonitor( clock: Clock, metricProducer: MetricProducer, monitor: ComputeMonitor, - exportInterval: Long = 5L * 60 * 1000, /* Every 5 min (which is the granularity of the workload trace) */ + exportInterval: Duration = Duration.ofMinutes(5), /* Every 5 min (which is the granularity of the workload trace) */ block: suspend CoroutineScope.() -> Unit ): Unit = coroutineScope { // Monitor host events diff --git a/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt b/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt index 9ee16fac..8f19ab81 100644 --- a/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt +++ b/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt @@ -26,14 +26,8 @@ import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.consumeAsFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import mu.KotlinLogging -import java.util.* -import kotlin.coroutines.resume -import kotlin.coroutines.suspendCoroutine +import java.time.Duration /** * A helper class to read the metrics from a list of [MetricProducer]s and automatically export the metrics every @@ -44,56 +38,44 @@ import kotlin.coroutines.suspendCoroutine * @param scope The [CoroutineScope] to run the reader in. * @param producers The metric producers to gather metrics from. * @param exporter The export to export the metrics to. - * @param exportInterval The export interval in milliseconds. + * @param exportInterval The export interval. */ public class CoroutineMetricReader( scope: CoroutineScope, private val producers: List, private val exporter: MetricExporter, - private val exportInterval: Long = 60_000 + private val exportInterval: Duration = Duration.ofMinutes(1) ) : AutoCloseable { private val logger = KotlinLogging.logger {} - private val chan = Channel>(Channel.RENDEZVOUS) /** - * The metric reader job. + * The background job that is responsible for collecting the metrics every cycle. */ - private val readerJob = scope.launch { + private val job = scope.launch { + val intervalMs = exportInterval.toMillis() + while (isActive) { - delay(exportInterval) + delay(intervalMs) val metrics = mutableListOf() for (producer in producers) { metrics.addAll(producer.collectAllMetrics()) } - chan.send(Collections.unmodifiableList(metrics)) - } - } - /** - * The exporter job runs in the background to actually export the metrics. - */ - private val exporterJob = chan.consumeAsFlow() - .onEach { metrics -> - suspendCoroutine { cont -> - try { - val result = exporter.export(metrics) - result.whenComplete { - if (!result.isSuccess) { - logger.trace { "Exporter failed" } - } - cont.resume(Unit) + try { + val result = exporter.export(metrics) + result.whenComplete { + if (!result.isSuccess) { + logger.trace { "Exporter failed" } } - } catch (cause: Throwable) { - logger.warn(cause) { "Exporter threw an Exception" } - cont.resume(Unit) } + } catch (cause: Throwable) { + logger.warn(cause) { "Exporter threw an Exception" } } } - .launchIn(scope) + } override fun close() { - readerJob.cancel() - exporterJob.cancel() + job.cancel() } } -- cgit v1.2.3 From 3ca64e0110adab65526a0ccfd5b252e9f047ab10 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 14 Sep 2021 14:41:05 +0200 Subject: refactor(telemetry): Create separate MeterProvider per service/host This change refactors the telemetry implementation by creating a separate MeterProvider per service or host. This means we have to keep track of multiple metric producers, but that we can attach resource information to each of the MeterProviders like we would in a real world scenario. --- .../org/opendc/compute/service/ComputeService.kt | 10 +- .../compute/service/internal/ComputeServiceImpl.kt | 26 +- .../compute/service/internal/InternalServer.kt | 18 ++ .../opendc/compute/service/ComputeServiceTest.kt | 3 +- .../opendc/compute/service/InternalServerTest.kt | 81 +++--- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 43 +-- .../org/opendc/compute/simulator/SimHostTest.kt | 54 ++-- .../experiments/capelin/ExperimentHelpers.kt | 256 ------------------ .../org/opendc/experiments/capelin/Portfolio.kt | 67 ++--- .../export/parquet/ParquetHostDataWriter.kt | 7 +- .../export/parquet/ParquetServerDataWriter.kt | 8 +- .../experiments/capelin/util/ComputeSchedulers.kt | 86 ++++++ .../capelin/util/ComputeServiceSimulator.kt | 222 ++++++++++++++++ .../experiments/capelin/util/FailureModel.kt | 38 +++ .../experiments/capelin/util/FailureModels.kt | 97 +++++++ .../experiments/capelin/CapelinIntegrationTest.kt | 190 +++++++------ .../experiments/serverless/ServerlessExperiment.kt | 3 +- opendc-faas/opendc-faas-service/build.gradle.kts | 1 + .../kotlin/org/opendc/faas/service/FaaSService.kt | 7 +- .../org/opendc/faas/service/FunctionObject.kt | 26 +- .../autoscaler/FunctionTerminationPolicyFixed.kt | 5 +- .../faas/service/internal/FaaSServiceImpl.kt | 8 +- .../org/opendc/faas/service/FaaSServiceTest.kt | 30 +-- .../opendc/faas/simulator/SimFaaSServiceTest.kt | 6 +- .../opendc-telemetry-compute/build.gradle.kts | 1 - .../telemetry/compute/ComputeMetricExporter.kt | 295 +++++++++++++++------ .../org/opendc/telemetry/compute/ComputeMonitor.kt | 14 - .../kotlin/org/opendc/telemetry/compute/Helpers.kt | 44 --- .../org/opendc/telemetry/compute/HostAttributes.kt | 51 ++++ .../org/opendc/telemetry/compute/table/HostData.kt | 4 +- .../org/opendc/telemetry/compute/table/HostInfo.kt | 28 ++ .../opendc/telemetry/compute/table/ServerData.kt | 5 +- .../opendc/telemetry/compute/table/ServerInfo.kt | 37 +++ .../src/main/kotlin/org/opendc/web/runner/Main.kt | 72 +++-- .../org/opendc/web/runner/WebComputeMonitor.kt | 40 ++- .../org/opendc/workflow/service/WorkflowService.kt | 8 +- .../service/internal/WorkflowServiceImpl.kt | 8 +- .../opendc/workflow/service/WorkflowServiceTest.kt | 8 +- 38 files changed, 1148 insertions(+), 759 deletions(-) delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt index 1873eb99..2a1fbaa0 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt @@ -23,11 +23,13 @@ package org.opendc.compute.service import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.api.metrics.MeterProvider import org.opendc.compute.api.ComputeClient import org.opendc.compute.service.driver.Host import org.opendc.compute.service.internal.ComputeServiceImpl import org.opendc.compute.service.scheduler.ComputeScheduler import java.time.Clock +import java.time.Duration import kotlin.coroutines.CoroutineContext /** @@ -70,16 +72,18 @@ public interface ComputeService : AutoCloseable { * * @param context The [CoroutineContext] to use in the service. * @param clock The clock instance to use. + * @param meterProvider The [MeterProvider] for creating a [Meter] for the service. * @param scheduler The scheduler implementation to use. + * @param schedulingQuantum The interval between scheduling cycles. */ public operator fun invoke( context: CoroutineContext, clock: Clock, - meter: Meter, + meterProvider: MeterProvider, scheduler: ComputeScheduler, - schedulingQuantum: Long = 300000, + schedulingQuantum: Duration = Duration.ofMinutes(5), ): ComputeService { - return ComputeServiceImpl(context, clock, meter, scheduler, schedulingQuantum) + return ComputeServiceImpl(context, clock, meterProvider, scheduler, schedulingQuantum) } } } diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index f1c055d4..824becf4 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -22,9 +22,8 @@ package org.opendc.compute.service.internal -import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.* import mu.KotlinLogging import org.opendc.compute.api.* @@ -35,6 +34,7 @@ import org.opendc.compute.service.driver.HostState import org.opendc.compute.service.scheduler.ComputeScheduler import org.opendc.utils.TimerScheduler import java.time.Clock +import java.time.Duration import java.util.* import kotlin.coroutines.CoroutineContext import kotlin.math.max @@ -42,15 +42,18 @@ import kotlin.math.max /** * Internal implementation of the OpenDC Compute service. * - * @param context The [CoroutineContext] to use. - * @param clock The clock instance to keep track of time. + * @param context The [CoroutineContext] to use in the service. + * @param clock The clock instance to use. + * @param meterProvider The [MeterProvider] for creating a [Meter] for the service. + * @param scheduler The scheduler implementation to use. + * @param schedulingQuantum The interval between scheduling cycles. */ internal class ComputeServiceImpl( private val context: CoroutineContext, private val clock: Clock, - private val meter: Meter, + meterProvider: MeterProvider, private val scheduler: ComputeScheduler, - private val schedulingQuantum: Long + private val schedulingQuantum: Duration ) : ComputeService, HostListener { /** * The [CoroutineScope] of the service bounded by the lifecycle of the service. @@ -62,6 +65,11 @@ internal class ComputeServiceImpl( */ private val logger = KotlinLogging.logger {} + /** + * The [Meter] to track metrics of the [ComputeService]. + */ + private val meter = meterProvider.get("org.opendc.compute.service") + /** * The [Random] instance used to generate unique identifiers for the objects. */ @@ -365,10 +373,12 @@ internal class ComputeServiceImpl( return } + val quantum = schedulingQuantum.toMillis() + // We assume that the provisioner runs at a fixed slot every time quantum (e.g t=0, t=60, t=120). // This is important because the slices of the VMs need to be aligned. // We calculate here the delay until the next scheduling slot. - val delay = schedulingQuantum - (clock.millis() % schedulingQuantum) + val delay = quantum - (clock.millis() % quantum) timerScheduler.startSingleTimer(Unit, delay) { doSchedule() @@ -414,7 +424,7 @@ internal class ComputeServiceImpl( // Remove request from queue queue.poll() _waitingServers.add(-1) - _schedulerDuration.record(now - request.submitTime, Attributes.of(ResourceAttributes.HOST_ID, server.uid.toString())) + _schedulerDuration.record(now - request.submitTime, server.attributes) logger.info { "Assigned server $server to host $host." } diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt index d9d0f3fc..05a7e1bf 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt @@ -22,6 +22,9 @@ package org.opendc.compute.service.internal +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import mu.KotlinLogging import org.opendc.compute.api.* import org.opendc.compute.service.driver.Host @@ -49,6 +52,21 @@ internal class InternalServer( */ private val watchers = mutableListOf() + /** + * The attributes of a server. + */ + internal val attributes: Attributes = Attributes.builder() + .put(ResourceAttributes.HOST_NAME, name) + .put(ResourceAttributes.HOST_ID, uid.toString()) + .put(ResourceAttributes.HOST_TYPE, flavor.name) + .put(AttributeKey.longKey("host.num_cpus"), flavor.cpuCount.toLong()) + .put(AttributeKey.longKey("host.mem_capacity"), flavor.memorySize) + .put(AttributeKey.stringArrayKey("host.labels"), labels.map { (k, v) -> "$k:$v" }) + .put(ResourceAttributes.HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(ResourceAttributes.HOST_IMAGE_NAME, image.name) + .put(ResourceAttributes.HOST_IMAGE_ID, image.uid.toString()) + .build() + /** * The [Host] that has been assigned to host the server. */ diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt index d036ec00..564f9493 100644 --- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt @@ -61,8 +61,7 @@ internal class ComputeServiceTest { filters = listOf(ComputeFilter(), VCpuFilter(allocationRatio = 1.0), RamFilter(allocationRatio = 1.0)), weighers = listOf(RamWeigher()) ) - val meter = MeterProvider.noop().get("opendc-compute") - service = ComputeService(scope.coroutineContext, clock, meter, computeScheduler) + service = ComputeService(scope.coroutineContext, clock, MeterProvider.noop(), computeScheduler) } @Test diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt index 28fd8217..dfd3bc67 100644 --- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt +++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt @@ -47,8 +47,9 @@ class InternalServerTest { fun testEquality() { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() + val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val b = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) @@ -59,8 +60,8 @@ class InternalServerTest { fun testEqualityWithDifferentType() { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val b = mockk(relaxUnitFun = true) @@ -73,8 +74,8 @@ class InternalServerTest { fun testInequalityWithDifferentType() { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val b = mockk(relaxUnitFun = true) @@ -87,8 +88,8 @@ class InternalServerTest { fun testInequalityWithIncorrectType() { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) assertNotEquals(a, Unit) @@ -98,8 +99,8 @@ class InternalServerTest { fun testStartTerminatedServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) every { service.schedule(any()) } answers { ComputeServiceImpl.SchedulingRequest(it.invocation.args[0] as InternalServer, 0) } @@ -114,8 +115,8 @@ class InternalServerTest { fun testStartDeletedServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.DELETED @@ -127,8 +128,8 @@ class InternalServerTest { fun testStartProvisioningServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.PROVISIONING @@ -142,8 +143,8 @@ class InternalServerTest { fun testStartRunningServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.RUNNING @@ -157,8 +158,8 @@ class InternalServerTest { fun testStopProvisioningServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val request = ComputeServiceImpl.SchedulingRequest(server, 0) @@ -175,8 +176,8 @@ class InternalServerTest { fun testStopTerminatedServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.TERMINATED @@ -189,8 +190,8 @@ class InternalServerTest { fun testStopDeletedServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.DELETED @@ -203,8 +204,8 @@ class InternalServerTest { fun testStopRunningServer() = runBlockingSimulation { val service = mockk() val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val host = mockk(relaxUnitFun = true) @@ -220,8 +221,8 @@ class InternalServerTest { fun testDeleteProvisioningServer() = runBlockingSimulation { val service = mockk(relaxUnitFun = true) val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val request = ComputeServiceImpl.SchedulingRequest(server, 0) @@ -239,8 +240,8 @@ class InternalServerTest { fun testDeleteTerminatedServer() = runBlockingSimulation { val service = mockk(relaxUnitFun = true) val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.TERMINATED @@ -255,8 +256,8 @@ class InternalServerTest { fun testDeleteDeletedServer() = runBlockingSimulation { val service = mockk(relaxUnitFun = true) val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) server.state = ServerState.DELETED @@ -269,8 +270,8 @@ class InternalServerTest { fun testDeleteRunningServer() = runBlockingSimulation { val service = mockk(relaxUnitFun = true) val uid = UUID.randomUUID() - val flavor = mockk() - val image = mockk() + val flavor = mockFlavor() + val image = mockImage() val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf()) val host = mockk(relaxUnitFun = true) @@ -282,4 +283,20 @@ class InternalServerTest { coVerify { host.delete(server) } verify { service.delete(server) } } + + private fun mockFlavor(): InternalFlavor { + val flavor = mockk() + every { flavor.name } returns "c5.large" + every { flavor.uid } returns UUID.randomUUID() + every { flavor.cpuCount } returns 2 + every { flavor.memorySize } returns 4096 + return flavor + } + + private fun mockImage(): InternalImage { + val image = mockk() + every { image.name } returns "ubuntu-20.04" + every { image.uid } returns UUID.randomUUID() + return image + } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index a1cc3390..be6ef11e 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -25,6 +25,7 @@ package org.opendc.compute.simulator import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import kotlinx.coroutines.* import mu.KotlinLogging @@ -59,7 +60,7 @@ public class SimHost( override val meta: Map, context: CoroutineContext, interpreter: SimResourceInterpreter, - private val meter: Meter, + meterProvider: MeterProvider, hypervisor: SimHypervisorProvider, scalingGovernor: ScalingGovernor = PerformanceScalingGovernor(), powerDriver: PowerDriver = SimplePowerDriver(ConstantPowerModel(0.0)), @@ -81,6 +82,11 @@ public class SimHost( */ private val logger = KotlinLogging.logger {} + /** + * The [Meter] to track metrics of the simulated host. + */ + private val meter = meterProvider.get("org.opendc.compute.simulator") + /** * The event listeners registered with this host. */ @@ -142,10 +148,9 @@ public class SimHost( * The total number of guests. */ private val _guests = meter.upDownCounterBuilder("guests.total") - .setDescription("Number of guests") + .setDescription("Total number of guests") .setUnit("1") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The number of active guests on the host. @@ -154,7 +159,6 @@ public class SimHost( .setDescription("Number of active guests") .setUnit("1") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The CPU demand of the host. @@ -163,7 +167,6 @@ public class SimHost( .setDescription("The amount of CPU resources the guests would use if there were no CPU contention or CPU limits") .setUnit("MHz") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The CPU usage of the host. @@ -172,7 +175,6 @@ public class SimHost( .setDescription("The amount of CPU resources used by the host") .setUnit("MHz") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The power usage of the host. @@ -181,7 +183,6 @@ public class SimHost( .setDescription("The amount of power used by the CPU") .setUnit("W") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The total amount of work supplied to the CPU. @@ -191,7 +192,6 @@ public class SimHost( .setUnit("1") .ofDoubles() .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The work performed by the CPU. @@ -201,7 +201,6 @@ public class SimHost( .setUnit("1") .ofDoubles() .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The amount not performed by the CPU due to overcommitment. @@ -211,7 +210,6 @@ public class SimHost( .setUnit("1") .ofDoubles() .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The amount of work not performed by the CPU due to interference. @@ -221,7 +219,6 @@ public class SimHost( .setUnit("1") .ofDoubles() .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The amount of time in the system. @@ -230,7 +227,6 @@ public class SimHost( .setDescription("The amount of time in the system") .setUnit("ms") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The uptime of the host. @@ -239,7 +235,6 @@ public class SimHost( .setDescription("The uptime of the host") .setUnit("ms") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) /** * The downtime of the host. @@ -248,7 +243,6 @@ public class SimHost( .setDescription("The downtime of the host") .setUnit("ms") .build() - .bind(Attributes.of(ResourceAttributes.HOST_ID, uid.toString())) init { // Launch hypervisor onto machine @@ -390,6 +384,21 @@ public class SimHost( private inner class Guest(val server: Server, val machine: SimMachine) { var state: ServerState = ServerState.TERMINATED + /** + * The attributes of the guest. + */ + val attributes: Attributes = Attributes.builder() + .put(ResourceAttributes.HOST_NAME, server.name) + .put(ResourceAttributes.HOST_ID, server.uid.toString()) + .put(ResourceAttributes.HOST_TYPE, server.flavor.name) + .put(AttributeKey.longKey("host.num_cpus"), server.flavor.cpuCount.toLong()) + .put(AttributeKey.longKey("host.mem_capacity"), server.flavor.memorySize) + .put(AttributeKey.stringArrayKey("host.labels"), server.labels.map { (k, v) -> "$k:$v" }) + .put(ResourceAttributes.HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(ResourceAttributes.HOST_IMAGE_NAME, server.image.name) + .put(ResourceAttributes.HOST_IMAGE_ID, server.image.uid.toString()) + .build() + /** * The amount of time in the system. */ @@ -397,7 +406,7 @@ public class SimHost( .setDescription("The amount of time in the system") .setUnit("ms") .build() - .bind(Attributes.of(AttributeKey.stringKey("server.id"), server.uid.toString())) + .bind(attributes) /** * The uptime of the guest. @@ -406,7 +415,7 @@ public class SimHost( .setDescription("The uptime of the guest") .setUnit("ms") .build() - .bind(Attributes.of(AttributeKey.stringKey("server.id"), server.uid.toString())) + .bind(attributes) /** * The time the guest is in an error state. @@ -415,7 +424,7 @@ public class SimHost( .setDescription("The time the guest is in an error state") .setUnit("ms") .build() - .bind(Attributes.of(AttributeKey.stringKey("server.id"), server.uid.toString())) + .bind(attributes) suspend fun start() { when (state) { diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 9fa8af34..318b5a5d 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -49,6 +49,7 @@ import org.opendc.telemetry.sdk.toOtelClock import java.time.Duration import java.util.* import kotlin.coroutines.resume +import kotlin.math.roundToLong /** * Basic test-suite for the hypervisor. @@ -72,7 +73,7 @@ internal class SimHostTest { */ @Test fun testOvercommitted() = runBlockingSimulation { - var requestedWork = 0L + var totalWork = 0L var grantedWork = 0L var overcommittedWork = 0L @@ -89,7 +90,7 @@ internal class SimHostTest { meta = emptyMap(), coroutineContext, interpreter, - meterProvider.get("opendc-compute-simulator"), + meterProvider, SimFairShareHypervisorProvider() ) val duration = 5 * 60L @@ -134,15 +135,10 @@ internal class SimHostTest { object : MetricExporter { override fun export(metrics: Collection): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } - metricsByName["cpu.work.total"]?.let { - requestedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() - } - metricsByName["cpu.work.granted"]?.let { - grantedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() - } - metricsByName["cpu.work.overcommit"]?.let { - overcommittedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() - } + + totalWork = metricsByName.getValue("cpu.work.total").doubleSumData.points.first().value.roundToLong() + grantedWork = metricsByName.getValue("cpu.work.granted").doubleSumData.points.first().value.roundToLong() + overcommittedWork = metricsByName.getValue("cpu.work.overcommit").doubleSumData.points.first().value.roundToLong() return CompletableResultCode.ofSuccess() } @@ -176,7 +172,7 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(4147200, requestedWork, "Requested work does not match") }, + { assertEquals(4147200, totalWork, "Requested work does not match") }, { assertEquals(2107200, grantedWork, "Granted work does not match") }, { assertEquals(2040000, overcommittedWork, "Overcommitted work does not match") }, { assertEquals(1500001, clock.millis()) } @@ -188,7 +184,7 @@ internal class SimHostTest { */ @Test fun testFailure() = runBlockingSimulation { - var requestedWork = 0L + var totalWork = 0L var grantedWork = 0L var totalTime = 0L var downTime = 0L @@ -208,7 +204,7 @@ internal class SimHostTest { meta = emptyMap(), coroutineContext, interpreter, - meterProvider.get("opendc-compute-simulator"), + meterProvider, SimFairShareHypervisorProvider() ) val duration = 5 * 60L @@ -237,24 +233,14 @@ internal class SimHostTest { object : MetricExporter { override fun export(metrics: Collection): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } - metricsByName["cpu.work.total"]?.let { - requestedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() - } - metricsByName["cpu.work.granted"]?.let { - grantedWork = it.doubleSumData.points.sumOf { point -> point.value }.toLong() - } - metricsByName["host.time.total"]?.let { - totalTime = it.longSumData.points.first().value - } - metricsByName["host.time.down"]?.let { - downTime = it.longSumData.points.first().value - } - metricsByName["guest.time.total"]?.let { - guestTotalTime = it.longSumData.points.first().value - } - metricsByName["guest.time.error"]?.let { - guestDownTime = it.longSumData.points.first().value - } + + totalWork = metricsByName.getValue("cpu.work.total").doubleSumData.points.first().value.roundToLong() + grantedWork = metricsByName.getValue("cpu.work.granted").doubleSumData.points.first().value.roundToLong() + totalTime = metricsByName.getValue("host.time.total").longSumData.points.first().value + downTime = metricsByName.getValue("host.time.down").longSumData.points.first().value + guestTotalTime = metricsByName.getValue("guest.time.total").longSumData.points.first().value + guestDownTime = metricsByName.getValue("guest.time.error").longSumData.points.first().value + return CompletableResultCode.ofSuccess() } @@ -290,8 +276,8 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(2226039, requestedWork, "Total time does not match") }, - { assertEquals(1086039, grantedWork, "Down time does not match") }, + { assertEquals(2226040, totalWork, "Total time does not match") }, + { assertEquals(1086040, grantedWork, "Down time does not match") }, { assertEquals(1200001, totalTime, "Total time does not match") }, { assertEquals(1200001, guestTotalTime, "Guest total time does not match") }, { assertEquals(5000, downTime, "Down time does not match") }, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt deleted file mode 100644 index 8227bca9..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin - -import io.opentelemetry.api.metrics.MeterProvider -import io.opentelemetry.sdk.metrics.SdkMeterProvider -import kotlinx.coroutines.* -import org.apache.commons.math3.distribution.LogNormalDistribution -import org.apache.commons.math3.random.Well19937c -import org.opendc.compute.api.* -import org.opendc.compute.service.ComputeService -import org.opendc.compute.service.scheduler.ComputeScheduler -import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.ReplayScheduler -import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.filters.RamFilter -import org.opendc.compute.service.scheduler.filters.VCpuFilter -import org.opendc.compute.service.scheduler.weights.CoreRamWeigher -import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher -import org.opendc.compute.service.scheduler.weights.RamWeigher -import org.opendc.compute.service.scheduler.weights.VCpuWeigher -import org.opendc.compute.simulator.SimHost -import org.opendc.compute.simulator.failure.HostFaultInjector -import org.opendc.compute.simulator.failure.StartStopHostFault -import org.opendc.compute.simulator.failure.StochasticVictimSelector -import org.opendc.experiments.capelin.env.EnvironmentReader -import org.opendc.experiments.capelin.trace.TraceReader -import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider -import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel -import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.telemetry.compute.ComputeMonitor -import org.opendc.telemetry.sdk.toOtelClock -import java.time.Clock -import kotlin.coroutines.CoroutineContext -import kotlin.math.ln -import kotlin.math.max -import kotlin.random.Random - -/** - * Obtain the [FaultInjector] to use for the experiments. - */ -fun createFaultInjector( - context: CoroutineContext, - clock: Clock, - hosts: Set, - seed: Int, - failureInterval: Double -): HostFaultInjector { - val rng = Well19937c(seed) - - // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 - // GRID'5000 - return HostFaultInjector( - context, - clock, - hosts, - iat = LogNormalDistribution(rng, ln(failureInterval), 1.03), - selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), - fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) - ) -} - -/** - * Construct the environment for a simulated compute service.. - */ -suspend fun withComputeService( - clock: Clock, - meterProvider: MeterProvider, - environmentReader: EnvironmentReader, - scheduler: ComputeScheduler, - interferenceModel: VmInterferenceModel? = null, - block: suspend CoroutineScope.(ComputeService) -> Unit -): Unit = coroutineScope { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val hosts = environmentReader - .use { it.read() } - .map { def -> - SimHost( - def.uid, - def.name, - def.model, - def.meta, - coroutineContext, - interpreter, - meterProvider.get("opendc-compute-simulator"), - SimFairShareHypervisorProvider(), - powerDriver = SimplePowerDriver(def.powerModel), - interferenceDomain = interferenceModel?.newDomain() - ) - } - - val serviceMeter = meterProvider.get("opendc-compute") - val service = - ComputeService(coroutineContext, clock, serviceMeter, scheduler) - - for (host in hosts) { - service.addHost(host) - } - - try { - block(this, service) - } finally { - service.close() - hosts.forEach(SimHost::close) - } -} - -/** - * Process the trace. - */ -suspend fun processTrace( - clock: Clock, - reader: TraceReader, - scheduler: ComputeService, - monitor: ComputeMonitor? = null, -) { - val client = scheduler.newClient() - val watcher = object : ServerWatcher { - override fun onStateChanged(server: Server, newState: ServerState) { - monitor?.onStateChange(clock.millis(), server, newState) - } - } - - // Create new image for the virtual machine - val image = client.newImage("vm-image") - - try { - coroutineScope { - var offset = Long.MIN_VALUE - - while (reader.hasNext()) { - val entry = reader.next() - - if (offset < 0) { - offset = entry.start - clock.millis() - } - - // Make sure the trace entries are ordered by submission time - assert(entry.start - offset >= 0) { "Invalid trace order" } - delay(max(0, (entry.start - offset) - clock.millis())) - - launch { - val workloadOffset = -offset + 300001 - val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) - - val server = client.newServer( - entry.name, - image, - client.newFlavor( - entry.name, - entry.meta["cores"] as Int, - entry.meta["required-memory"] as Long - ), - meta = entry.meta + mapOf("workload" to workload) - ) - server.watch(watcher) - - // Wait for the server reach its end time - val endTime = entry.meta["end-time"] as Long - delay(endTime + workloadOffset - clock.millis() + 1) - - // Delete the server after reaching the end-time of the virtual machine - server.delete() - } - } - } - - yield() - } finally { - reader.close() - client.close() - } -} - -/** - * Create a [MeterProvider] instance for the experiment. - */ -fun createMeterProvider(clock: Clock): MeterProvider { - return SdkMeterProvider - .builder() - .setClock(clock.toOtelClock()) - .build() -} - -/** - * Create a [ComputeScheduler] for the experiment. - */ -fun createComputeScheduler(allocationPolicy: String, seeder: Random, vmPlacements: Map = emptyMap()): ComputeScheduler { - val cpuAllocationRatio = 16.0 - val ramAllocationRatio = 1.5 - return when (allocationPolicy) { - "mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(RamWeigher(multiplier = 1.0)) - ) - "mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(RamWeigher(multiplier = -1.0)) - ) - "core-mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) - "core-mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(CoreRamWeigher(multiplier = -1.0)) - ) - "active-servers" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(InstanceCountWeigher(multiplier = -1.0)) - ) - "active-servers-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(InstanceCountWeigher(multiplier = 1.0)) - ) - "provisioned-cores" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)) - ) - "provisioned-cores-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)) - ) - "random" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = emptyList(), - subsetSize = Int.MAX_VALUE, - random = java.util.Random(seeder.nextLong()) - ) - "replay" -> ReplayScheduler(vmPlacements) - else -> throw IllegalArgumentException("Unknown policy $allocationPolicy") - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 82794471..f7f9336e 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -23,10 +23,7 @@ package org.opendc.experiments.capelin import com.typesafe.config.ConfigFactory -import io.opentelemetry.sdk.metrics.export.MetricProducer -import kotlinx.coroutines.ExperimentalCoroutinesApi import mu.KotlinLogging -import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.export.parquet.ParquetExportMonitor import org.opendc.experiments.capelin.model.CompositeWorkload @@ -36,17 +33,21 @@ import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader +import org.opendc.experiments.capelin.util.ComputeServiceSimulator +import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.collectServiceMetrics -import org.opendc.telemetry.compute.withMonitor +import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.io.File import java.io.FileInputStream +import java.time.Duration import java.util.* import java.util.concurrent.ConcurrentHashMap -import kotlin.random.asKotlinRandom +import kotlin.math.roundToLong /** * A portfolio represents a collection of scenarios are tested for the work. @@ -97,28 +98,23 @@ abstract class Portfolio(name: String) : Experiment(name) { /** * Perform a single trial for this portfolio. */ - @OptIn(ExperimentalCoroutinesApi::class) override fun doRun(repeat: Int): Unit = runBlockingSimulation { val seeder = Random(repeat.toLong()) val environment = ClusterEnvironmentReader(File(config.getString("env-path"), "${topology.name}.txt")) - val allocationPolicy = createComputeScheduler(allocationPolicy, seeder.asKotlinRandom(), vmPlacements) - - val meterProvider = createMeterProvider(clock) val workload = workload val workloadNames = if (workload is CompositeWorkload) { workload.workloads.map { it.name } } else { listOf(workload.name) } - val rawReaders = workloadNames.map { workloadName -> traceReaders.computeIfAbsent(workloadName) { logger.info { "Loading trace $workloadName" } RawParquetTraceReader(File(config.getString("trace-path"), workloadName)) } } - + val trace = ParquetTraceReader(rawReaders, workload, seeder.nextInt()) val performanceInterferenceModel = if (operationalPhenomena.hasInterference) PerformanceInterferenceReader() .read(FileInputStream(config.getString("interference-model"))) @@ -126,43 +122,36 @@ abstract class Portfolio(name: String) : Experiment(name) { else null - val trace = ParquetTraceReader(rawReaders, workload, seeder.nextInt()) + val computeScheduler = createComputeScheduler(allocationPolicy, seeder, vmPlacements) + val failureModel = + if (operationalPhenomena.failureFrequency > 0) + grid5000(Duration.ofSeconds((operationalPhenomena.failureFrequency * 60).roundToLong()), seeder.nextInt()) + else + null + val simulator = ComputeServiceSimulator( + coroutineContext, + clock, + computeScheduler, + environment.read(), + failureModel, + performanceInterferenceModel + ) val monitor = ParquetExportMonitor( File(config.getString("output-path")), "portfolio_id=$name/scenario_id=$id/run_id=$repeat", 4096 ) + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) - withComputeService(clock, meterProvider, environment, allocationPolicy, performanceInterferenceModel) { scheduler -> - val faultInjector = if (operationalPhenomena.failureFrequency > 0) { - logger.debug("ENABLING failures") - createFaultInjector( - coroutineContext, - clock, - scheduler.hosts.map { it as SimHost }.toSet(), - seeder.nextInt(), - operationalPhenomena.failureFrequency, - ) - } else { - null - } - - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - faultInjector?.start() - processTrace( - clock, - trace, - scheduler, - monitor - ) - } - - faultInjector?.close() - monitor.close() + try { + simulator.run(trace) + } finally { + simulator.close() + metricReader.close() } - val monitorResults = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + val monitorResults = collectServiceMetrics(clock.millis(), simulator.producers[0]) logger.debug { "Finish " + "SUBMIT=${monitorResults.instanceCount} " + diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt index 7062a275..fa00fc35 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt @@ -28,7 +28,6 @@ import org.apache.avro.generic.GenericData import org.apache.avro.generic.GenericRecordBuilder import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter -import org.opendc.compute.service.driver.HostState import org.opendc.telemetry.compute.table.HostData import java.io.File @@ -46,8 +45,8 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : override fun convert(builder: GenericRecordBuilder, data: HostData) { builder["timestamp"] = data.timestamp - builder["host_id"] = data.host.name - builder["powered_on"] = data.host.state == HostState.UP + builder["host_id"] = data.host.id + builder["powered_on"] = true builder["uptime"] = data.uptime builder["downtime"] = data.downtime builder["total_work"] = data.totalWork @@ -58,7 +57,7 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : builder["cpu_demand"] = data.cpuDemand builder["power_draw"] = data.powerDraw builder["num_instances"] = data.instanceCount - builder["num_cpus"] = data.host.model.cpuCount + builder["num_cpus"] = data.host.cpuCount } override fun toString(): String = "host-writer" diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt index 9904adde..bb2db4b7 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt @@ -46,12 +46,12 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : override fun convert(builder: GenericRecordBuilder, data: ServerData) { builder["timestamp"] = data.timestamp - builder["server_id"] = data.server.uid.toString() - builder["state"] = data.server.state + builder["server_id"] = data.server + // builder["state"] = data.server.state builder["uptime"] = data.uptime builder["downtime"] = data.downtime - builder["num_vcpus"] = data.server.flavor.cpuCount - builder["mem_capacity"] = data.server.flavor.memorySize + // builder["num_vcpus"] = data.server.flavor.cpuCount + // builder["mem_capacity"] = data.server.flavor.memorySize } override fun toString(): String = "server-writer" diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt new file mode 100644 index 00000000..3b7c3f0f --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("ComputeSchedulers") +package org.opendc.experiments.capelin.util + +import org.opendc.compute.service.scheduler.ComputeScheduler +import org.opendc.compute.service.scheduler.FilterScheduler +import org.opendc.compute.service.scheduler.ReplayScheduler +import org.opendc.compute.service.scheduler.filters.ComputeFilter +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher +import org.opendc.compute.service.scheduler.weights.RamWeigher +import org.opendc.compute.service.scheduler.weights.VCpuWeigher +import java.util.* + +/** + * Create a [ComputeScheduler] for the experiment. + */ +fun createComputeScheduler(allocationPolicy: String, seeder: Random, vmPlacements: Map = emptyMap()): ComputeScheduler { + val cpuAllocationRatio = 16.0 + val ramAllocationRatio = 1.5 + return when (allocationPolicy) { + "mem" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(RamWeigher(multiplier = 1.0)) + ) + "mem-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(RamWeigher(multiplier = -1.0)) + ) + "core-mem" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) + "core-mem-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(CoreRamWeigher(multiplier = -1.0)) + ) + "active-servers" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(InstanceCountWeigher(multiplier = -1.0)) + ) + "active-servers-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(InstanceCountWeigher(multiplier = 1.0)) + ) + "provisioned-cores" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)) + ) + "provisioned-cores-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)) + ) + "random" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = emptyList(), + subsetSize = Int.MAX_VALUE, + random = Random(seeder.nextLong()) + ) + "replay" -> ReplayScheduler(vmPlacements) + else -> throw IllegalArgumentException("Unknown policy $allocationPolicy") + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt new file mode 100644 index 00000000..065a8c93 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.util + +import io.opentelemetry.sdk.metrics.SdkMeterProvider +import io.opentelemetry.sdk.metrics.export.MetricProducer +import io.opentelemetry.sdk.resources.Resource +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield +import org.opendc.compute.service.ComputeService +import org.opendc.compute.service.scheduler.ComputeScheduler +import org.opendc.compute.simulator.SimHost +import org.opendc.experiments.capelin.env.MachineDef +import org.opendc.experiments.capelin.trace.TraceReader +import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider +import org.opendc.simulator.compute.kernel.SimHypervisorProvider +import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel +import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.telemetry.compute.* +import org.opendc.telemetry.sdk.toOtelClock +import java.time.Clock +import kotlin.coroutines.CoroutineContext +import kotlin.math.max + +/** + * Helper class to manage a [ComputeService] simulation. + */ +class ComputeServiceSimulator( + private val context: CoroutineContext, + private val clock: Clock, + scheduler: ComputeScheduler, + machines: List, + private val failureModel: FailureModel? = null, + interferenceModel: VmInterferenceModel? = null, + hypervisorProvider: SimHypervisorProvider = SimFairShareHypervisorProvider() +) : AutoCloseable { + /** + * The [ComputeService] that has been configured by the manager. + */ + val service: ComputeService + + /** + * The [MetricProducer] that are used by the [ComputeService] and the simulated hosts. + */ + val producers: List + get() = _metricProducers + private val _metricProducers = mutableListOf() + + /** + * The [SimResourceInterpreter] to simulate the hosts. + */ + private val interpreter = SimResourceInterpreter(context, clock) + + /** + * The hosts that belong to this class. + */ + private val hosts = mutableSetOf() + + init { + val (service, serviceMeterProvider) = createService(scheduler) + this._metricProducers.add(serviceMeterProvider) + this.service = service + + for (def in machines) { + val (host, hostMeterProvider) = createHost(def, hypervisorProvider, interferenceModel) + this._metricProducers.add(hostMeterProvider) + hosts.add(host) + this.service.addHost(host) + } + } + + /** + * Run a simulation of the [ComputeService] by replaying the workload trace given by [reader]. + */ + suspend fun run(reader: TraceReader) { + val injector = failureModel?.createInjector(context, clock, service) + val client = service.newClient() + + // Create new image for the virtual machine + val image = client.newImage("vm-image") + + try { + coroutineScope { + // Start the fault injector + injector?.start() + + var offset = Long.MIN_VALUE + + while (reader.hasNext()) { + val entry = reader.next() + + if (offset < 0) { + offset = entry.start - clock.millis() + } + + // Make sure the trace entries are ordered by submission time + assert(entry.start - offset >= 0) { "Invalid trace order" } + delay(max(0, (entry.start - offset) - clock.millis())) + + launch { + val workloadOffset = -offset + 300001 + val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) + + val server = client.newServer( + entry.name, + image, + client.newFlavor( + entry.name, + entry.meta["cores"] as Int, + entry.meta["required-memory"] as Long + ), + meta = entry.meta + mapOf("workload" to workload) + ) + + // Wait for the server reach its end time + val endTime = entry.meta["end-time"] as Long + delay(endTime + workloadOffset - clock.millis() + 1) + + // Delete the server after reaching the end-time of the virtual machine + server.delete() + } + } + } + + yield() + } finally { + injector?.close() + reader.close() + client.close() + } + } + + override fun close() { + service.close() + + for (host in hosts) { + host.close() + } + + hosts.clear() + } + + /** + * Construct a [ComputeService] instance. + */ + private fun createService(scheduler: ComputeScheduler): Pair { + val resource = Resource.builder() + .put(ResourceAttributes.SERVICE_NAME, "opendc-compute") + .build() + + val meterProvider = SdkMeterProvider.builder() + .setClock(clock.toOtelClock()) + .setResource(resource) + .build() + + val service = ComputeService(context, clock, meterProvider, scheduler) + return service to meterProvider + } + + /** + * Construct a [SimHost] instance for the specified [MachineDef]. + */ + private fun createHost( + def: MachineDef, + hypervisorProvider: SimHypervisorProvider, + interferenceModel: VmInterferenceModel? = null + ): Pair { + val resource = Resource.builder() + .put(HOST_ID, def.uid.toString()) + .put(HOST_NAME, def.name) + .put(HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(HOST_NCPUS, def.model.cpus.size) + .put(HOST_MEM_CAPACITY, def.model.memory.sumOf { it.size }) + .build() + + val meterProvider = SdkMeterProvider.builder() + .setClock(clock.toOtelClock()) + .setResource(resource) + .build() + + val host = SimHost( + def.uid, + def.name, + def.model, + def.meta, + context, + interpreter, + meterProvider, + hypervisorProvider, + powerDriver = SimplePowerDriver(def.powerModel), + interferenceDomain = interferenceModel?.newDomain() + ) + + return host to meterProvider + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt new file mode 100644 index 00000000..83393896 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.util + +import org.opendc.compute.service.ComputeService +import org.opendc.compute.simulator.failure.HostFaultInjector +import java.time.Clock +import kotlin.coroutines.CoroutineContext + +/** + * Factory interface for constructing [HostFaultInjector] for modeling failures of compute service hosts. + */ +interface FailureModel { + /** + * Construct a [HostFaultInjector] for the specified [service]. + */ + fun createInjector(context: CoroutineContext, clock: Clock, service: ComputeService): HostFaultInjector +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt new file mode 100644 index 00000000..89b4a31c --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("FailureModels") +package org.opendc.experiments.capelin + +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.service.ComputeService +import org.opendc.compute.simulator.SimHost +import org.opendc.compute.simulator.failure.HostFaultInjector +import org.opendc.compute.simulator.failure.StartStopHostFault +import org.opendc.compute.simulator.failure.StochasticVictimSelector +import org.opendc.experiments.capelin.util.FailureModel +import java.time.Clock +import java.time.Duration +import kotlin.coroutines.CoroutineContext +import kotlin.math.ln +import kotlin.random.Random + +/** + * Obtain a [FailureModel] based on the GRID'5000 failure trace. + * + * This fault injector uses parameters from the GRID'5000 failure trace as described in + * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. + */ +fun grid5000(failureInterval: Duration, seed: Int): FailureModel { + return object : FailureModel { + override fun createInjector( + context: CoroutineContext, + clock: Clock, + service: ComputeService + ): HostFaultInjector { + val rng = Well19937c(seed) + val hosts = service.hosts.map { it as SimHost }.toSet() + + // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 + // GRID'5000 + return HostFaultInjector( + context, + clock, + hosts, + iat = LogNormalDistribution(rng, ln(failureInterval.toHours().toDouble()), 1.03), + selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), + fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) + ) + } + + override fun toString(): String = "Grid5000FailureModel" + } +} + +/** + * Obtain the [HostFaultInjector] to use for the experiments. + * + * This fault injector uses parameters from the GRID'5000 failure trace as described in + * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. + */ +fun createFaultInjector( + context: CoroutineContext, + clock: Clock, + hosts: Set, + seed: Int, + failureInterval: Double +): HostFaultInjector { + val rng = Well19937c(seed) + + // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 + // GRID'5000 + return HostFaultInjector( + context, + clock, + hosts, + iat = LogNormalDistribution(rng, ln(failureInterval), 1.03), + selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), + fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) + ) +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index cf88535d..f4cf3e5e 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -22,7 +22,6 @@ package org.opendc.experiments.capelin -import io.opentelemetry.sdk.metrics.export.MetricProducer import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -32,7 +31,6 @@ import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.filters.RamFilter import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.service.scheduler.weights.CoreRamWeigher -import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload @@ -40,15 +38,19 @@ import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader import org.opendc.experiments.capelin.trace.TraceReader +import org.opendc.experiments.capelin.util.ComputeServiceSimulator import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.compute.collectServiceMetrics import org.opendc.telemetry.compute.table.HostData -import org.opendc.telemetry.compute.withMonitor +import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.io.File +import java.time.Duration import java.util.* +import kotlin.math.roundToLong /** * An integration test suite for the Capelin experiments. @@ -59,12 +61,21 @@ class CapelinIntegrationTest { */ private lateinit var monitor: TestExperimentReporter + /** + * The [FilterScheduler] to use for all experiments. + */ + private lateinit var computeScheduler: FilterScheduler + /** * Setup the experimental environment. */ @BeforeEach fun setUp() { monitor = TestExperimentReporter() + computeScheduler = FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) } /** @@ -72,26 +83,26 @@ class CapelinIntegrationTest { */ @Test fun testLarge() = runBlockingSimulation { - val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) val traceReader = createTestTraceReader() val environmentReader = createTestEnvironmentReader() - val meterProvider = createMeterProvider(clock) - withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - processTrace( - clock, - traceReader, - scheduler, - monitor - ) - } + val simulator = ComputeServiceSimulator( + coroutineContext, + clock, + computeScheduler, + environmentReader.read(), + ) + + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + + try { + simulator.run(traceReader) + } finally { + simulator.close() + metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( "Finish " + "SUBMIT=${serviceMetrics.instanceCount} " + @@ -106,11 +117,11 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.runningInstanceCount, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.failedInstanceCount, "No VM should not be unscheduled") }, { assertEquals(0, serviceMetrics.queuedInstanceCount, "No VM should not be in the queue") }, - { assertEquals(220346369753, monitor.totalWork) { "Incorrect requested burst" } }, - { assertEquals(206667809529, monitor.totalGrantedWork) { "Incorrect granted burst" } }, - { assertEquals(1151611104, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, + { assertEquals(220346412191, monitor.totalWork) { "Incorrect requested burst" } }, + { assertEquals(206667852689, monitor.totalGrantedWork) { "Incorrect granted burst" } }, + { assertEquals(1151612221, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedWork) { "Incorrect interfered burst" } }, - { assertEquals(1.8175860403178412E7, monitor.totalPowerDraw, 0.01) { "Incorrect power draw" } }, + { assertEquals(9.088769763540529E7, monitor.totalPowerDraw, 0.01) { "Incorrect power draw" } }, ) } @@ -120,27 +131,26 @@ class CapelinIntegrationTest { @Test fun testSmall() = runBlockingSimulation { val seed = 1 - val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) val traceReader = createTestTraceReader(0.25, seed) val environmentReader = createTestEnvironmentReader("single") - val meterProvider = createMeterProvider(clock) - - withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - processTrace( - clock, - traceReader, - scheduler, - monitor - ) - } + val simulator = ComputeServiceSimulator( + coroutineContext, + clock, + computeScheduler, + environmentReader.read(), + ) + + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + + try { + simulator.run(traceReader) + } finally { + simulator.close() + metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( "Finish " + "SUBMIT=${serviceMetrics.instanceCount} " + @@ -151,9 +161,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(39183961335, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(35649903197, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(1043641877, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(39183965664, monitor.totalWork) { "Total work incorrect" } }, + { assertEquals(35649907631, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(1043642275, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -164,10 +174,6 @@ class CapelinIntegrationTest { @Test fun testInterference() = runBlockingSimulation { val seed = 1 - val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) val traceReader = createTestTraceReader(0.25, seed) val environmentReader = createTestEnvironmentReader("single") @@ -177,20 +183,24 @@ class CapelinIntegrationTest { .read(perfInterferenceInput) .let { VmInterferenceModel(it, Random(seed.toLong())) } - val meterProvider = createMeterProvider(clock) - - withComputeService(clock, meterProvider, environmentReader, allocationPolicy, performanceInterferenceModel) { scheduler -> - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - processTrace( - clock, - traceReader, - scheduler, - monitor - ) - } + val simulator = ComputeServiceSimulator( + coroutineContext, + clock, + computeScheduler, + environmentReader.read(), + interferenceModel = performanceInterferenceModel + ) + + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + + try { + simulator.run(traceReader) + } finally { + simulator.close() + metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( "Finish " + "SUBMIT=${serviceMetrics.instanceCount} " + @@ -201,10 +211,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(39183961335, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(35649903197, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(1043641877, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, - { assertEquals(2960970230, monitor.totalInterferedWork) { "Total interfered work incorrect" } } + { assertEquals(39183965664, monitor.totalWork) { "Total work incorrect" } }, + { assertEquals(35649907631, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(1043642275, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(2960974524, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -214,39 +224,27 @@ class CapelinIntegrationTest { @Test fun testFailures() = runBlockingSimulation { val seed = 1 - val allocationPolicy = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) val traceReader = createTestTraceReader(0.25, seed) val environmentReader = createTestEnvironmentReader("single") - val meterProvider = createMeterProvider(clock) - - withComputeService(clock, meterProvider, environmentReader, allocationPolicy) { scheduler -> - val faultInjector = - createFaultInjector( - coroutineContext, - clock, - scheduler.hosts.map { it as SimHost }.toSet(), - seed, - 24.0 * 7, - ) - - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - faultInjector.start() - processTrace( - clock, - traceReader, - scheduler, - monitor - ) - } - - faultInjector.close() + val simulator = ComputeServiceSimulator( + coroutineContext, + clock, + computeScheduler, + environmentReader.read(), + grid5000(Duration.ofDays(7), seed) + ) + + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + + try { + simulator.run(traceReader) + } finally { + simulator.close() + metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), meterProvider as MetricProducer) + val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( "Finish " + "SUBMIT=${serviceMetrics.instanceCount} " + @@ -257,9 +255,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(38385852453, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(34886665781, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(979997253, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, + { assertEquals(38385856700, monitor.totalWork) { "Total requested work incorrect" } }, + { assertEquals(34886670127, monitor.totalGrantedWork) { "Total granted work incorrect" } }, + { assertEquals(979997628, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } ) } @@ -291,10 +289,10 @@ class CapelinIntegrationTest { var totalPowerDraw = 0.0 override fun record(data: HostData) { - this.totalWork += data.totalWork.toLong() - totalGrantedWork += data.grantedWork.toLong() - totalOvercommittedWork += data.overcommittedWork.toLong() - totalInterferedWork += data.interferedWork.toLong() + this.totalWork += data.totalWork.roundToLong() + totalGrantedWork += data.grantedWork.roundToLong() + totalOvercommittedWork += data.overcommittedWork.roundToLong() + totalInterferedWork += data.interferedWork.roundToLong() totalPowerDraw += data.powerDraw } } diff --git a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt index 650416f5..3312d6c0 100644 --- a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt +++ b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt @@ -46,6 +46,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.sdk.toOtelClock import java.io.File +import java.time.Duration import java.util.* import kotlin.math.max @@ -85,7 +86,7 @@ public class ServerlessExperiment : Experiment("Serverless") { val delayInjector = StochasticDelayInjector(coldStartModel, Random()) val deployer = SimFunctionDeployer(clock, this, createMachineModel(), delayInjector) { FunctionTraceWorkload(traceById.getValue(it.name)) } val service = - FaaSService(coroutineContext, clock, meterProvider.get("opendc-serverless"), deployer, routingPolicy, FunctionTerminationPolicyFixed(coroutineContext, clock, timeout = 10L * 60 * 1000)) + FaaSService(coroutineContext, clock, meterProvider, deployer, routingPolicy, FunctionTerminationPolicyFixed(coroutineContext, clock, timeout = Duration.ofMinutes(10))) val client = service.newClient() coroutineScope { diff --git a/opendc-faas/opendc-faas-service/build.gradle.kts b/opendc-faas/opendc-faas-service/build.gradle.kts index 63bed8bc..6f4fcc9b 100644 --- a/opendc-faas/opendc-faas-service/build.gradle.kts +++ b/opendc-faas/opendc-faas-service/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { api(projects.opendcTelemetry.opendcTelemetryApi) implementation(projects.opendcUtils) implementation(libs.kotlin.logging) + implementation(libs.opentelemetry.semconv) testImplementation(projects.opendcSimulator.opendcSimulatorCore) testRuntimeOnly(libs.log4j.slf4j) diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt index 7e716a34..1d5331cb 100644 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt +++ b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt @@ -23,6 +23,7 @@ package org.opendc.faas.service import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.api.metrics.MeterProvider import org.opendc.faas.api.FaaSClient import org.opendc.faas.service.autoscaler.FunctionTerminationPolicy import org.opendc.faas.service.deployer.FunctionDeployer @@ -51,7 +52,7 @@ public interface FaaSService : AutoCloseable { * * @param context The [CoroutineContext] to use in the service. * @param clock The clock instance to use. - * @param meter The meter to report metrics to. + * @param meterProvider The [MeterProvider] to create a [Meter] with. * @param deployer the [FunctionDeployer] to use for deploying function instances. * @param routingPolicy The policy to route function invocations. * @param terminationPolicy The policy for terminating function instances. @@ -59,12 +60,12 @@ public interface FaaSService : AutoCloseable { public operator fun invoke( context: CoroutineContext, clock: Clock, - meter: Meter, + meterProvider: MeterProvider, deployer: FunctionDeployer, routingPolicy: RoutingPolicy, terminationPolicy: FunctionTerminationPolicy, ): FaaSService { - return FaaSServiceImpl(context, clock, meter, deployer, routingPolicy, terminationPolicy) + return FaaSServiceImpl(context, clock, meterProvider, deployer, routingPolicy, terminationPolicy) } } } diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt index a1cb1dbf..54df2b59 100644 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt +++ b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt @@ -28,6 +28,7 @@ import io.opentelemetry.api.metrics.BoundLongCounter import io.opentelemetry.api.metrics.BoundLongHistogram import io.opentelemetry.api.metrics.BoundLongUpDownCounter import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes import org.opendc.faas.service.deployer.FunctionInstance import java.util.* @@ -43,9 +44,14 @@ public class FunctionObject( meta: Map ) : AutoCloseable { /** - * The function identifier attached to the metrics. + * The attributes of this function. */ - private val functionId = AttributeKey.stringKey("function") + public val attributes: Attributes = Attributes.builder() + .put(ResourceAttributes.FAAS_ID, uid.toString()) + .put(ResourceAttributes.FAAS_NAME, name) + .put(ResourceAttributes.FAAS_MAX_MEMORY, allocatedMemory) + .put(AttributeKey.stringArrayKey("faas.labels"), labels.map { (k, v) -> "$k:$v" }) + .build() /** * The total amount of function invocations received by the function. @@ -54,7 +60,7 @@ public class FunctionObject( .setDescription("Number of function invocations") .setUnit("1") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The amount of function invocations that could be handled directly. @@ -63,7 +69,7 @@ public class FunctionObject( .setDescription("Number of function invocations handled directly") .setUnit("1") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The amount of function invocations that were delayed due to function deployment. @@ -72,7 +78,7 @@ public class FunctionObject( .setDescription("Number of function invocations that are delayed") .setUnit("1") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The amount of function invocations that failed. @@ -81,7 +87,7 @@ public class FunctionObject( .setDescription("Number of function invocations that failed") .setUnit("1") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The amount of instances for this function. @@ -90,7 +96,7 @@ public class FunctionObject( .setDescription("Number of active function instances") .setUnit("1") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The amount of idle instances for this function. @@ -99,7 +105,7 @@ public class FunctionObject( .setDescription("Number of idle function instances") .setUnit("1") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The time that the function waited. @@ -109,7 +115,7 @@ public class FunctionObject( .setDescription("Time the function has to wait before being started") .setUnit("ms") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The time that the function was running. @@ -119,7 +125,7 @@ public class FunctionObject( .setDescription("Time the function was running") .setUnit("ms") .build() - .bind(Attributes.of(functionId, uid.toString())) + .bind(attributes) /** * The instances associated with this function. diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.kt index 1e224ed1..63dbadc7 100644 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.kt +++ b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.kt @@ -26,6 +26,7 @@ import org.opendc.faas.service.deployer.FunctionInstance import org.opendc.faas.service.deployer.FunctionInstanceState import org.opendc.utils.TimerScheduler import java.time.Clock +import java.time.Duration import kotlin.coroutines.CoroutineContext /** @@ -36,7 +37,7 @@ import kotlin.coroutines.CoroutineContext public class FunctionTerminationPolicyFixed( context: CoroutineContext, clock: Clock, - public val timeout: Long + public val timeout: Duration ) : FunctionTerminationPolicy { /** * The [TimerScheduler] used to schedule the function terminations. @@ -60,6 +61,6 @@ public class FunctionTerminationPolicyFixed( * Schedule termination for the specified [instance]. */ private fun schedule(instance: FunctionInstance) { - scheduler.startSingleTimer(instance, delay = timeout) { instance.close() } + scheduler.startSingleTimer(instance, delay = timeout.toMillis()) { instance.close() } } } diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt index ccf9a5d9..3b560cd3 100644 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt +++ b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt @@ -23,6 +23,7 @@ package org.opendc.faas.service.internal import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.* import kotlinx.coroutines.intrinsics.startCoroutineCancellable import mu.KotlinLogging @@ -54,7 +55,7 @@ import kotlin.coroutines.resumeWithException internal class FaaSServiceImpl( context: CoroutineContext, private val clock: Clock, - private val meter: Meter, + private val meterProvider: MeterProvider, private val deployer: FunctionDeployer, private val routingPolicy: RoutingPolicy, private val terminationPolicy: FunctionTerminationPolicy @@ -69,6 +70,11 @@ internal class FaaSServiceImpl( */ private val logger = KotlinLogging.logger {} + /** + * The [Meter] that collects the metrics of this service. + */ + private val meter = meterProvider.get("org.opendc.faas.service") + /** * The [TimerScheduler] to use for scheduling the scheduler cycles. */ diff --git a/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt b/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt index 6b99684a..1612e10b 100644 --- a/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt +++ b/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt @@ -44,8 +44,7 @@ internal class FaaSServiceTest { @Test fun testClientState() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = assertDoesNotThrow { service.newClient() } assertDoesNotThrow { client.close() } @@ -59,8 +58,7 @@ internal class FaaSServiceTest { @Test fun testClientInvokeUnknown() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() @@ -69,8 +67,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionCreation() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() @@ -81,8 +78,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionQuery() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() @@ -95,8 +91,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionFindById() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() @@ -109,8 +104,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionFindByName() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() @@ -123,8 +117,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionDuplicateName() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() @@ -135,8 +128,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionDelete() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() val function = client.newFunction("test", 128) @@ -150,8 +142,7 @@ internal class FaaSServiceTest { @Test fun testClientFunctionCannotInvokeDeleted() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") - val service = FaaSService(coroutineContext, clock, meter, mockk(), mockk(), mockk()) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), mockk(), mockk(), mockk()) val client = service.newClient() val function = client.newFunction("test", 128) @@ -163,9 +154,8 @@ internal class FaaSServiceTest { @Test fun testClientFunctionInvoke() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") val deployer = mockk() - val service = FaaSService(coroutineContext, clock, meter, deployer, mockk(), mockk(relaxUnitFun = true)) + val service = FaaSService(coroutineContext, clock, MeterProvider.noop(), deployer, mockk(), mockk(relaxUnitFun = true)) every { deployer.deploy(any(), any()) } answers { object : FunctionInstance { diff --git a/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt b/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt index 64f2551b..0dc9ba87 100644 --- a/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt +++ b/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt @@ -43,6 +43,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimFlopsWorkload import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation +import java.time.Duration /** * A test suite for the [FaaSService] implementation under simulated conditions. @@ -64,14 +65,13 @@ internal class SimFaaSServiceTest { @Test fun testSmoke() = runBlockingSimulation { - val meter = MeterProvider.noop().get("opendc-faas") val workload = spyk(object : SimFaaSWorkload, SimWorkload by SimFlopsWorkload(1000) { override suspend fun invoke() {} }) val deployer = SimFunctionDeployer(clock, this, machineModel, ZeroDelayInjector) { workload } val service = FaaSService( - coroutineContext, clock, meter, deployer, RandomRoutingPolicy(), - FunctionTerminationPolicyFixed(coroutineContext, clock, timeout = 10000) + coroutineContext, clock, MeterProvider.noop(), deployer, RandomRoutingPolicy(), + FunctionTerminationPolicyFixed(coroutineContext, clock, timeout = Duration.ofMillis(10000)) ) val client = service.newClient() diff --git a/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts b/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts index 6a3de9bc..cd8cb57a 100644 --- a/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts +++ b/opendc-telemetry/opendc-telemetry-compute/build.gradle.kts @@ -31,7 +31,6 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcTelemetry.opendcTelemetrySdk) - implementation(projects.opendcCompute.opendcComputeSimulator) implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt index 57d43c60..408d1325 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt @@ -22,137 +22,260 @@ package org.opendc.telemetry.compute +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes import io.opentelemetry.sdk.common.CompletableResultCode -import io.opentelemetry.sdk.metrics.data.MetricData +import io.opentelemetry.sdk.metrics.data.* import io.opentelemetry.sdk.metrics.export.MetricExporter +import io.opentelemetry.sdk.resources.Resource import io.opentelemetry.semconv.resource.attributes.ResourceAttributes -import org.opendc.compute.service.driver.Host import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.HostInfo +import org.opendc.telemetry.compute.table.ServerData +import org.opendc.telemetry.compute.table.ServerInfo import java.time.Clock /** * A [MetricExporter] that redirects data to a [ComputeMonitor] implementation. */ -public class ComputeMetricExporter( - private val clock: Clock, - private val hosts: Map, - private val monitor: ComputeMonitor -) : MetricExporter { - +public class ComputeMetricExporter(private val clock: Clock, private val monitor: ComputeMonitor) : MetricExporter { override fun export(metrics: Collection): CompletableResultCode { return try { - reportHostMetrics(metrics) reportServiceMetrics(metrics) + reportHostMetrics(metrics) + reportServerMetrics(metrics) CompletableResultCode.ofSuccess() } catch (e: Throwable) { CompletableResultCode.ofFailure() } } - private var lastHostMetrics: Map = emptyMap() - private val hostMetricsSingleton = HBuffer() + override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() + + override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() + + private fun reportServiceMetrics(metrics: Collection) { + monitor.record(extractServiceMetrics(clock.millis(), metrics)) + } + + private val hosts = mutableMapOf() + private val servers = mutableMapOf() private fun reportHostMetrics(metrics: Collection) { - val hostMetrics = mutableMapOf() + val hosts = hosts + val servers = servers + + for (metric in metrics) { + val resource = metric.resource + val hostId = resource.attributes[HOST_ID] ?: continue + val agg = hosts.computeIfAbsent(hostId) { HostAggregator(resource) } + agg.accept(metric) + } + + val monitor = monitor + val now = clock.millis() + for ((_, server) in servers) { + server.record(monitor, now) + } + } + + private fun reportServerMetrics(metrics: Collection) { + val hosts = hosts for (metric in metrics) { + val resource = metric.resource + val host = resource.attributes[HOST_ID]?.let { hosts[it]?.host } + when (metric.name) { - "cpu.demand" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuDemand = v } - "cpu.usage" -> mapDoubleSummary(metric, hostMetrics) { m, v -> m.cpuUsage = v } - "power.usage" -> mapDoubleHistogram(metric, hostMetrics) { m, v -> m.powerDraw = v } - "cpu.work.total" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.totalWork = v } - "cpu.work.granted" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.grantedWork = v } - "cpu.work.overcommit" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.overcommittedWork = v } - "cpu.work.interference" -> mapDoubleSum(metric, hostMetrics) { m, v -> m.interferedWork = v } - "guests.active" -> mapLongSum(metric, hostMetrics) { m, v -> m.instanceCount = v.toInt() } - "host.time.up" -> mapLongSum(metric, hostMetrics) { m, v -> m.uptime = v } - "host.time.down" -> mapLongSum(metric, hostMetrics) { m, v -> m.downtime = v } + "scheduler.duration" -> mapByServer(metric.doubleHistogramData.points, host) { agg, point -> + agg.schedulingLatency = point.sum / point.count + } + "guest.time.running" -> mapByServer(metric.longSumData.points, host) { agg, point -> + agg.uptime = point.value + } + "guest.time.error" -> mapByServer(metric.longSumData.points, host) { agg, point -> + agg.downtime = point.value + } } } - for ((id, hostMetric) in hostMetrics) { - val lastHostMetric = lastHostMetrics.getOrDefault(id, hostMetricsSingleton) - val host = hosts[id] ?: continue + val monitor = monitor + val now = clock.millis() + for ((_, host) in hosts) { + host.record(monitor, now) + } + } + + /** + * Helper function to map a metric by the server. + */ + private inline fun

    mapByServer(points: Collection

    , host: HostInfo? = null, block: (ServerAggregator, P) -> Unit) { + for (point in points) { + val serverId = point.attributes[ResourceAttributes.HOST_ID] ?: continue + val agg = servers.computeIfAbsent(serverId) { ServerAggregator(point.attributes) } + + if (host != null) { + agg.host = host + } + + block(agg, point) + } + } + + /** + * An aggregator for host metrics before they are reported. + */ + private class HostAggregator(resource: Resource) { + /** + * The static information about this host. + */ + val host = HostInfo( + resource.attributes[HOST_ID]!!, + resource.attributes[HOST_NAME]!!, + resource.attributes[HOST_ARCH]!!, + resource.attributes[HOST_NCPUS]!!.toInt(), + resource.attributes[HOST_MEM_CAPACITY]!!, + ) + + private var totalWork: Double = 0.0 + private var previousTotalWork = 0.0 + private var grantedWork: Double = 0.0 + private var previousGrantedWork = 0.0 + private var overcommittedWork: Double = 0.0 + private var previousOvercommittedWork = 0.0 + private var interferedWork: Double = 0.0 + private var previousInterferedWork = 0.0 + private var cpuUsage: Double = 0.0 + private var cpuDemand: Double = 0.0 + private var instanceCount: Int = 0 + private var powerDraw: Double = 0.0 + private var uptime: Long = 0 + private var previousUptime = 0L + private var downtime: Long = 0 + private var previousDowntime = 0L + fun record(monitor: ComputeMonitor, now: Long) { monitor.record( HostData( - clock.millis(), + now, host, - hostMetric.totalWork - lastHostMetric.totalWork, - hostMetric.grantedWork - lastHostMetric.grantedWork, - hostMetric.overcommittedWork - lastHostMetric.overcommittedWork, - hostMetric.interferedWork - lastHostMetric.interferedWork, - hostMetric.cpuUsage, - hostMetric.cpuDemand, - hostMetric.instanceCount, - hostMetric.powerDraw, - hostMetric.uptime - lastHostMetric.uptime, - hostMetric.downtime - lastHostMetric.downtime, + totalWork - previousTotalWork, + grantedWork - previousGrantedWork, + overcommittedWork - previousOvercommittedWork, + interferedWork - previousInterferedWork, + cpuUsage, + cpuDemand, + instanceCount, + powerDraw, + uptime - previousUptime, + downtime - previousDowntime, ) ) - } - - lastHostMetrics = hostMetrics - } - private fun mapDoubleSummary(data: MetricData, hostMetrics: MutableMap, block: (HBuffer, Double) -> Unit) { - val points = data.doubleSummaryData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } - val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2 - block(hostMetric, avg) + previousTotalWork = totalWork + previousGrantedWork = grantedWork + previousOvercommittedWork = overcommittedWork + previousInterferedWork = interferedWork + previousUptime = uptime + previousDowntime = downtime + reset() } - } - private fun mapDoubleHistogram(data: MetricData, hostMetrics: MutableMap, block: (HBuffer, Double) -> Unit) { - val points = data.doubleHistogramData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } - block(hostMetric, point.sum / point.count) + /** + * Accept the [MetricData] for this host. + */ + fun accept(data: MetricData) { + when (data.name) { + "cpu.work.total" -> totalWork = data.doubleSumData.points.first().value + "cpu.work.granted" -> grantedWork = data.doubleSumData.points.first().value + "cpu.work.overcommit" -> overcommittedWork = data.doubleSumData.points.first().value + "cpu.work.interference" -> interferedWork = data.doubleSumData.points.first().value + "power.usage" -> powerDraw = acceptHistogram(data) + "cpu.usage" -> cpuUsage = acceptHistogram(data) + "cpu.demand" -> cpuDemand = acceptHistogram(data) + "guests.active" -> instanceCount = data.longSumData.points.first().value.toInt() + "host.time.up" -> uptime = data.longSumData.points.first().value + "host.time.down" -> downtime = data.longSumData.points.first().value + } } - } - private fun mapLongSum(data: MetricData?, hostMetrics: MutableMap, block: (HBuffer, Long) -> Unit) { - val points = data?.longSumData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } - block(hostMetric, point.value) + private fun acceptHistogram(data: MetricData): Double { + return when (data.type) { + MetricDataType.HISTOGRAM -> { + val point = data.doubleHistogramData.points.first() + point.sum / point.count + } + MetricDataType.SUMMARY -> { + val point = data.doubleSummaryData.points.first() + point.sum / point.count + } + else -> error("Invalid metric type") + } } - } - private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HBuffer, Double) -> Unit) { - val points = data?.doubleSumData?.points ?: emptyList() - for (point in points) { - val uid = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val hostMetric = hostMetrics.computeIfAbsent(uid) { HBuffer() } - block(hostMetric, point.value) + private fun reset() { + totalWork = 0.0 + grantedWork = 0.0 + overcommittedWork = 0.0 + interferedWork = 0.0 + cpuUsage = 0.0 + cpuDemand = 0.0 + instanceCount = 0 + powerDraw = 0.0 + uptime = 0L + downtime = 0L } } /** - * A buffer for host metrics before they are reported. + * An aggregator for server metrics before they are reported. */ - private class HBuffer { - var totalWork: Double = 0.0 - var grantedWork: Double = 0.0 - var overcommittedWork: Double = 0.0 - var interferedWork: Double = 0.0 - var cpuUsage: Double = 0.0 - var cpuDemand: Double = 0.0 - var instanceCount: Int = 0 - var powerDraw: Double = 0.0 - var uptime: Long = 0 - var downtime: Long = 0 - } + private class ServerAggregator(attributes: Attributes) { + /** + * The static information about this server. + */ + val server = ServerInfo( + attributes[ResourceAttributes.HOST_ID]!!, + attributes[ResourceAttributes.HOST_NAME]!!, + attributes[ResourceAttributes.HOST_TYPE]!!, + attributes[ResourceAttributes.HOST_ARCH]!!, + attributes[ResourceAttributes.HOST_IMAGE_ID]!!, + attributes[ResourceAttributes.HOST_IMAGE_NAME]!!, + attributes[AttributeKey.longKey("host.num_cpus")]!!.toInt(), + attributes[AttributeKey.longKey("host.mem_capacity")]!!, + ) - private fun reportServiceMetrics(metrics: Collection) { - monitor.record(extractServiceMetrics(clock.millis(), metrics)) - } + /** + * The [HostInfo] of the host on which the server is hosted. + */ + var host: HostInfo? = null - override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() + @JvmField var uptime: Long = 0 + private var previousUptime = 0L + @JvmField var downtime: Long = 0 + private var previousDowntime = 0L + @JvmField var schedulingLatency = 0.0 - override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() + fun record(monitor: ComputeMonitor, now: Long) { + monitor.record( + ServerData( + now, + server, + null, + uptime - previousUptime, + downtime - previousDowntime, + ) + ) + + previousUptime = uptime + previousDowntime = downtime + reset() + } + + private fun reset() { + host = null + uptime = 0L + downtime = 0L + } + } } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt index ec303b37..d51bcab4 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMonitor.kt @@ -22,10 +22,6 @@ package org.opendc.telemetry.compute -import org.opendc.compute.api.Server -import org.opendc.compute.api.ServerState -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostState import org.opendc.telemetry.compute.table.HostData import org.opendc.telemetry.compute.table.ServerData import org.opendc.telemetry.compute.table.ServiceData @@ -34,16 +30,6 @@ import org.opendc.telemetry.compute.table.ServiceData * A monitor that tracks the metrics and events of the OpenDC Compute service. */ public interface ComputeMonitor { - /** - * This method is invoked when the state of a [Server] changes. - */ - public fun onStateChange(timestamp: Long, server: Server, newState: ServerState) {} - - /** - * This method is invoked when the state of a [Host] changes. - */ - public fun onStateChange(time: Long, host: Host, newState: HostState) {} - /** * Record the specified [data]. */ diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt index 01df0e69..1f309f1b 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt @@ -24,51 +24,7 @@ package org.opendc.telemetry.compute import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricProducer -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.coroutineScope -import org.opendc.compute.service.ComputeService -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostListener -import org.opendc.compute.service.driver.HostState import org.opendc.telemetry.compute.table.ServiceData -import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader -import java.time.Clock -import java.time.Duration - -/** - * Attach the specified monitor to the OpenDC Compute service. - */ -public suspend fun withMonitor( - scheduler: ComputeService, - clock: Clock, - metricProducer: MetricProducer, - monitor: ComputeMonitor, - exportInterval: Duration = Duration.ofMinutes(5), /* Every 5 min (which is the granularity of the workload trace) */ - block: suspend CoroutineScope.() -> Unit -): Unit = coroutineScope { - // Monitor host events - for (host in scheduler.hosts) { - monitor.onStateChange(clock.millis(), host, HostState.UP) - host.addListener(object : HostListener { - override fun onStateChanged(host: Host, newState: HostState) { - monitor.onStateChange(clock.millis(), host, newState) - } - }) - } - - val reader = CoroutineMetricReader( - this, - listOf(metricProducer), - ComputeMetricExporter(clock, scheduler.hosts.associateBy { it.uid.toString() }, monitor), - exportInterval - ) - - try { - block(this) - } finally { - reader.close() - } -} /** * Collect the metrics of the compute service. diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt new file mode 100644 index 00000000..7dca6186 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/HostAttributes.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("HostAttributes") +package org.opendc.telemetry.compute + +import io.opentelemetry.api.common.AttributeKey + +/** + * The identifier of the node hosting virtual machines. + */ +public val HOST_ID: AttributeKey = AttributeKey.stringKey("node.id") + +/** + * The name of the node hosting virtual machines. + */ +public val HOST_NAME: AttributeKey = AttributeKey.stringKey("node.name") + +/** + * The CPU architecture of the host node. + */ +public val HOST_ARCH: AttributeKey = AttributeKey.stringKey("node.arch") + +/** + * The number of CPUs in the host node. + */ +public val HOST_NCPUS: AttributeKey = AttributeKey.longKey("node.num_cpus") + +/** + * The amount of memory installed in the host node in MiB. + */ +public val HOST_MEM_CAPACITY: AttributeKey = AttributeKey.longKey("node.mem_capacity") diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt index 8e6c34d0..e3ecda3d 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt @@ -22,14 +22,12 @@ package org.opendc.telemetry.compute.table -import org.opendc.compute.service.driver.Host - /** * A trace entry for a particular host. */ public data class HostData( public val timestamp: Long, - public val host: Host, + public val host: HostInfo, public val totalWork: Double, public val grantedWork: Double, public val overcommittedWork: Double, diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt new file mode 100644 index 00000000..d9a5906b --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostInfo.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute.table + +/** + * Information about a host exposed to the telemetry service. + */ +public data class HostInfo(val id: String, val name: String, val arch: String, val cpuCount: Int, val memCapacity: Long) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt index 2a9fa8a6..7fde86d9 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt @@ -22,14 +22,13 @@ package org.opendc.telemetry.compute.table -import org.opendc.compute.api.Server - /** * A trace entry for a particular server. */ public data class ServerData( public val timestamp: Long, - public val server: Server, + public val server: ServerInfo, + public val host: HostInfo?, public val uptime: Long, public val downtime: Long, ) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt new file mode 100644 index 00000000..b16e5f3d --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerInfo.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute.table + +/** + * Static information about a server exposed to the telemetry service. + */ +public data class ServerInfo( + val id: String, + val name: String, + val type: String, + val arch: String, + val imageId: String, + val imageName: String, + val cpuCount: Int, + val memCapacity: Long +) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index b565e90d..b9d5a3f5 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -28,10 +28,8 @@ import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.long import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* import mu.KotlinLogging -import org.opendc.compute.simulator.SimHost import org.opendc.experiments.capelin.* import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.env.MachineDef @@ -39,6 +37,8 @@ import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader import org.opendc.experiments.capelin.trace.RawParquetTraceReader +import org.opendc.experiments.capelin.util.ComputeServiceSimulator +import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit @@ -46,8 +46,9 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.LinearPowerModel import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.collectServiceMetrics -import org.opendc.telemetry.compute.withMonitor +import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import org.opendc.telemetry.sdk.toOtelClock import org.opendc.web.client.ApiClient import org.opendc.web.client.AuthConfiguration @@ -55,9 +56,8 @@ import org.opendc.web.client.model.Scenario import org.opendc.web.client.model.Topology import java.io.File import java.net.URI +import java.time.Duration import java.util.* -import kotlin.random.Random -import kotlin.random.asJavaRandom import org.opendc.web.client.model.Portfolio as ClientPortfolio private val logger = KotlinLogging.logger {} @@ -158,7 +158,7 @@ class RunnerCli : CliktCommand(name = "runner") { val results = (0 until targets.repeatsPerScenario).map { repeat -> logger.info { "Starting repeat $repeat" } withTimeout(runTimeout * 1000) { - val interferenceModel = interferenceGroups?.let { VmInterferenceModel(it, Random(repeat.toLong()).asJavaRandom()) } + val interferenceModel = interferenceGroups?.let { VmInterferenceModel(it, Random(repeat.toLong())) } runRepeat(scenario, repeat, environment, traceReader, interferenceModel) } } @@ -182,63 +182,55 @@ class RunnerCli : CliktCommand(name = "runner") { try { runBlockingSimulation { - val seed = repeat val workloadName = scenario.trace.traceId val workloadFraction = scenario.trace.loadSamplingFraction - val seeder = Random(seed) + val seeder = Random(repeat.toLong()) val meterProvider: MeterProvider = SdkMeterProvider .builder() .setClock(clock.toOtelClock()) .build() - val metricProducer = meterProvider as MetricProducer val operational = scenario.operationalPhenomena - val allocationPolicy = createComputeScheduler(operational.schedulerName, seeder) + val computeScheduler = createComputeScheduler(operational.schedulerName, seeder) val trace = ParquetTraceReader( listOf(traceReader), Workload(workloadName, workloadFraction), - seed + repeat ) - val failureFrequency = if (operational.failuresEnabled) 24.0 * 7 else 0.0 - - withComputeService(clock, meterProvider, environment, allocationPolicy, interferenceModel) { scheduler -> - val faultInjector = if (failureFrequency > 0) { - logger.debug { "ENABLING failures" } - createFaultInjector( - coroutineContext, - clock, - scheduler.hosts.map { it as SimHost }.toSet(), - seeder.nextInt(), - failureFrequency, - ) - } else { + val failureModel = + if (operational.failuresEnabled) + grid5000(Duration.ofDays(7), repeat) + else null - } - withMonitor(scheduler, clock, meterProvider as MetricProducer, monitor) { - faultInjector?.start() + val simulator = ComputeServiceSimulator( + coroutineContext, + clock, + computeScheduler, + environment.read(), + failureModel, + interferenceModel.takeIf { operational.performanceInterferenceEnabled } + ) - processTrace( - clock, - trace, - scheduler, - monitor - ) + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) - faultInjector?.close() - } + try { + simulator.run(trace) + } finally { + simulator.close() + metricReader.close() } - val monitorResults = collectServiceMetrics(clock.millis(), metricProducer) + val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) logger.debug { "Finish " + - "SUBMIT=${monitorResults.instanceCount} " + - "FAIL=${monitorResults.failedInstanceCount} " + - "QUEUE=${monitorResults.queuedInstanceCount} " + - "RUNNING=${monitorResults.runningInstanceCount}" + "SUBMIT=${serviceMetrics.instanceCount} " + + "FAIL=${serviceMetrics.failedInstanceCount} " + + "QUEUE=${serviceMetrics.queuedInstanceCount} " + + "RUNNING=${serviceMetrics.runningInstanceCount}" } } } catch (cause: Throwable) { diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt index c8e58dde..4b813310 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt @@ -22,27 +22,19 @@ package org.opendc.web.runner -import mu.KotlinLogging -import org.opendc.compute.service.driver.Host -import org.opendc.compute.service.driver.HostState import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.compute.table.HostData import org.opendc.telemetry.compute.table.ServiceData import kotlin.math.max +import kotlin.math.roundToLong /** * A [ComputeMonitor] that tracks the aggregate metrics for each repeat. */ -public class WebComputeMonitor : ComputeMonitor { - private val logger = KotlinLogging.logger {} - - override fun onStateChange(time: Long, host: Host, newState: HostState) { - logger.debug { "Host ${host.uid} changed state $newState [$time]" } - } - +class WebComputeMonitor : ComputeMonitor { override fun record(data: HostData) { - val duration = 5 * 60 * 1000L - val slices = duration / SLICE_LENGTH + val duration = data.uptime + val slices = data.downtime / SLICE_LENGTH hostAggregateMetrics = AggregateHostMetrics( hostAggregateMetrics.totalWork + data.totalWork, @@ -50,14 +42,14 @@ public class WebComputeMonitor : ComputeMonitor { hostAggregateMetrics.totalOvercommittedWork + data.overcommittedWork, hostAggregateMetrics.totalInterferedWork + data.overcommittedWork, hostAggregateMetrics.totalPowerDraw + (duration * data.powerDraw) / 3600, - hostAggregateMetrics.totalFailureSlices + if (data.host.state != HostState.UP) slices else 0, - hostAggregateMetrics.totalFailureVmSlices + if (data.host.state != HostState.UP) data.instanceCount * slices else 0 + hostAggregateMetrics.totalFailureSlices + slices, + hostAggregateMetrics.totalFailureVmSlices + data.instanceCount * slices ) - hostMetrics.compute(data.host) { _, prev -> + hostMetrics.compute(data.host.id) { _, prev -> HostMetrics( - (data.cpuUsage.takeIf { data.host.state == HostState.UP } ?: 0.0) + (prev?.cpuUsage ?: 0.0), - (data.cpuDemand.takeIf { data.host.state == HostState.UP } ?: 0.0) + (prev?.cpuDemand ?: 0.0), + data.cpuUsage + (prev?.cpuUsage ?: 0.0), + data.cpuDemand + (prev?.cpuDemand ?: 0.0), data.instanceCount + (prev?.instanceCount ?: 0), 1 + (prev?.count ?: 0) ) @@ -65,7 +57,7 @@ public class WebComputeMonitor : ComputeMonitor { } private var hostAggregateMetrics: AggregateHostMetrics = AggregateHostMetrics() - private val hostMetrics: MutableMap = mutableMapOf() + private val hostMetrics: MutableMap = mutableMapOf() private val SLICE_LENGTH: Long = 5 * 60 * 1000 data class AggregateHostMetrics( @@ -74,8 +66,8 @@ public class WebComputeMonitor : ComputeMonitor { val totalOvercommittedWork: Double = 0.0, val totalInterferedWork: Double = 0.0, val totalPowerDraw: Double = 0.0, - val totalFailureSlices: Long = 0, - val totalFailureVmSlices: Long = 0, + val totalFailureSlices: Double = 0.0, + val totalFailureVmSlices: Double = 0.0, ) data class HostMetrics( @@ -97,7 +89,7 @@ public class WebComputeMonitor : ComputeMonitor { ) } - public data class AggregateServiceMetrics( + data class AggregateServiceMetrics( val vmTotalCount: Int = 0, val vmWaitingCount: Int = 0, val vmActiveCount: Int = 0, @@ -105,7 +97,7 @@ public class WebComputeMonitor : ComputeMonitor { val vmFailedCount: Int = 0 ) - public fun getResult(): Result { + fun getResult(): Result { return Result( hostAggregateMetrics.totalWork, hostAggregateMetrics.totalGrantedWork, @@ -116,8 +108,8 @@ public class WebComputeMonitor : ComputeMonitor { hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.average(), hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.maxOrNull() ?: 0.0, hostAggregateMetrics.totalPowerDraw, - hostAggregateMetrics.totalFailureSlices, - hostAggregateMetrics.totalFailureVmSlices, + hostAggregateMetrics.totalFailureSlices.roundToLong(), + hostAggregateMetrics.totalFailureVmSlices.roundToLong(), serviceMetrics.vmTotalCount, serviceMetrics.vmWaitingCount, serviceMetrics.vmInactiveCount, diff --git a/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/WorkflowService.kt b/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/WorkflowService.kt index d3358ef1..a0248a93 100644 --- a/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/WorkflowService.kt +++ b/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/WorkflowService.kt @@ -22,7 +22,7 @@ package org.opendc.workflow.service -import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.api.metrics.MeterProvider import org.opendc.compute.api.ComputeClient import org.opendc.workflow.api.Job import org.opendc.workflow.service.internal.WorkflowServiceImpl @@ -62,7 +62,7 @@ public interface WorkflowService : AutoCloseable { * @param context The [CoroutineContext] to use in the service. * @param clock The clock instance to use. * @param tracer The event tracer to use. - * @param meter The meter to use. + * @param meterProvider The meter provider to use. * @param compute The compute client to use. * @param mode The scheduling mode to use. * @param jobAdmissionPolicy The job admission policy to use. @@ -73,7 +73,7 @@ public interface WorkflowService : AutoCloseable { public operator fun invoke( context: CoroutineContext, clock: Clock, - meter: Meter, + meterProvider: MeterProvider, compute: ComputeClient, mode: WorkflowSchedulerMode, jobAdmissionPolicy: JobAdmissionPolicy, @@ -84,7 +84,7 @@ public interface WorkflowService : AutoCloseable { return WorkflowServiceImpl( context, clock, - meter, + meterProvider, compute, mode, jobAdmissionPolicy, diff --git a/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt b/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt index 5329143d..a0fd3fad 100644 --- a/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt +++ b/opendc-workflow/opendc-workflow-service/src/main/kotlin/org/opendc/workflow/service/internal/WorkflowServiceImpl.kt @@ -23,6 +23,7 @@ package org.opendc.workflow.service.internal import io.opentelemetry.api.metrics.Meter +import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.* import kotlinx.coroutines.flow.map import mu.KotlinLogging @@ -48,7 +49,7 @@ import kotlin.coroutines.resume public class WorkflowServiceImpl( context: CoroutineContext, internal val clock: Clock, - private val meter: Meter, + meterProvider: MeterProvider, private val computeClient: ComputeClient, mode: WorkflowSchedulerMode, jobAdmissionPolicy: JobAdmissionPolicy, @@ -66,6 +67,11 @@ public class WorkflowServiceImpl( */ private val logger = KotlinLogging.logger {} + /** + * The [Meter] to collect metrics of this service. + */ + private val meter = meterProvider.get("org.opendc.workflow.service") + /** * The incoming jobs ready to be processed by the scheduler. */ diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt index 07433d1f..74316437 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt @@ -51,6 +51,7 @@ import org.opendc.workflow.service.scheduler.job.NullJobAdmissionPolicy import org.opendc.workflow.service.scheduler.job.SubmissionTimeJobOrderPolicy import org.opendc.workflow.service.scheduler.task.NullTaskEligibilityPolicy import org.opendc.workflow.service.scheduler.task.SubmissionTimeTaskOrderPolicy +import java.time.Duration import java.util.* /** @@ -79,24 +80,23 @@ internal class WorkflowServiceTest { emptyMap(), coroutineContext, interpreter, - meterProvider.get("opendc-compute-simulator"), + MeterProvider.noop(), hvProvider, ) } - val meter = MeterProvider.noop().get("opendc-compute") val computeScheduler = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(1.0), RamFilter(1.0)), weighers = listOf(VCpuWeigher(1.0, multiplier = 1.0)) ) - val compute = ComputeService(coroutineContext, clock, meter, computeScheduler, schedulingQuantum = 1000) + val compute = ComputeService(coroutineContext, clock, MeterProvider.noop(), computeScheduler, schedulingQuantum = Duration.ofSeconds(1)) hosts.forEach { compute.addHost(it) } val scheduler = WorkflowService( coroutineContext, clock, - meterProvider.get("opendc-workflow"), + meterProvider, compute.newClient(), mode = WorkflowSchedulerMode.Batch(100), jobAdmissionPolicy = NullJobAdmissionPolicy, -- cgit v1.2.3 From 8d899e29dbd757f6df320212d6e0d77ce8216ab9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 14 Sep 2021 15:38:38 +0200 Subject: refactor(telemetry): Standardize compute scheduler metrics This change updates the OpenDC compute service implementation with multiple meters that follow the OpenTelemetry conventions. --- .../compute/service/internal/ComputeServiceImpl.kt | 137 +++++++++------------ .../org/opendc/experiments/capelin/Portfolio.kt | 11 +- .../export/parquet/ParquetServiceDataWriter.kt | 28 ++--- .../experiments/capelin/CapelinIntegrationTest.kt | 52 ++++---- .../kotlin/org/opendc/telemetry/compute/Helpers.kt | 59 +++++---- .../opendc/telemetry/compute/table/ServiceData.kt | 14 +-- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 11 +- .../org/opendc/web/runner/WebComputeMonitor.kt | 10 +- 8 files changed, 162 insertions(+), 160 deletions(-) diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index 824becf4..57e70fcd 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -22,6 +22,8 @@ package org.opendc.compute.service.internal +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.* @@ -114,69 +116,37 @@ internal class ComputeServiceImpl( private var maxMemory = 0L /** - * The number of servers that have been submitted to the service for provisioning. + * The number of scheduling attempts. */ - private val _submittedServers = meter.counterBuilder("servers.submitted") - .setDescription("Number of start requests") + private val _schedulingAttempts = meter.counterBuilder("scheduler.attempts") + .setDescription("Number of scheduling attempts") .setUnit("1") .build() + private val _schedulingAttemptsSuccess = _schedulingAttempts + .bind(Attributes.of(AttributeKey.stringKey("result"), "success")) + private val _schedulingAttemptsFailure = _schedulingAttempts + .bind(Attributes.of(AttributeKey.stringKey("result"), "failure")) + private val _schedulingAttemptsError = _schedulingAttempts + .bind(Attributes.of(AttributeKey.stringKey("result"), "error")) /** - * The number of servers that failed to be scheduled. - */ - private val _unscheduledServers = meter.counterBuilder("servers.unscheduled") - .setDescription("Number of unscheduled servers") - .setUnit("1") - .build() - - /** - * The number of servers that are waiting to be provisioned. - */ - private val _waitingServers = meter.upDownCounterBuilder("servers.waiting") - .setDescription("Number of servers waiting to be provisioned") - .setUnit("1") - .build() - - /** - * The number of servers that are waiting to be provisioned. - */ - private val _runningServers = meter.upDownCounterBuilder("servers.active") - .setDescription("Number of servers currently running") - .setUnit("1") - .build() - - /** - * The number of servers that have finished running. - */ - private val _finishedServers = meter.counterBuilder("servers.finished") - .setDescription("Number of servers that finished running") - .setUnit("1") - .build() - - /** - * The number of hosts registered at the compute service. + * The response time of the service. */ - private val _hostCount = meter.upDownCounterBuilder("hosts.total") - .setDescription("Number of hosts") - .setUnit("1") + private val _schedulingLatency = meter.histogramBuilder("scheduler.latency") + .setDescription("End to end latency for a server to be scheduled (in multiple attempts)") + .ofLongs() + .setUnit("ms") .build() /** - * The number of available hosts registered at the compute service. + * The number of servers that are pending. */ - private val _availableHostCount = meter.upDownCounterBuilder("hosts.available") - .setDescription("Number of available hosts") + private val _servers = meter.upDownCounterBuilder("scheduler.servers") + .setDescription("Number of servers managed by the scheduler") .setUnit("1") .build() - - /** - * The response time of the service. - */ - private val _schedulerDuration = meter.histogramBuilder("scheduler.duration") - .setDescription("End to end latency for a server to be scheduled (in multiple attempts)") - .ofLongs() - .setUnit("ms") - .build() + private val _serversPending = _servers.bind(Attributes.of(AttributeKey.stringKey("state"), "pending")) + private val _serversActive = _servers.bind(Attributes.of(AttributeKey.stringKey("state"), "active")) /** * The [TimerScheduler] to use for scheduling the scheduler cycles. @@ -189,6 +159,22 @@ internal class ComputeServiceImpl( override val hostCount: Int get() = hostToView.size + init { + val upState = Attributes.of(AttributeKey.stringKey("state"), "up") + val downState = Attributes.of(AttributeKey.stringKey("state"), "down") + + meter.upDownCounterBuilder("scheduler.hosts") + .setDescription("Number of hosts registered with the scheduler") + .setUnit("1") + .buildWithCallback { result -> + val total = hostCount + val available = availableHosts.size.toLong() + + result.observe(available, upState) + result.observe(total - available, downState) + } + } + override fun newClient(): ComputeClient { check(scope.isActive) { "Service is already closed" } return object : ComputeClient { @@ -316,24 +302,19 @@ internal class ComputeServiceImpl( hostToView[host] = hv if (host.state == HostState.UP) { - _availableHostCount.add(1) availableHosts += hv } scheduler.addHost(hv) - _hostCount.add(1) host.addListener(this) } override fun removeHost(host: Host) { val view = hostToView.remove(host) if (view != null) { - if (availableHosts.remove(view)) { - _availableHostCount.add(-1) - } + availableHosts.remove(view) scheduler.removeHost(view) host.removeListener(this) - _hostCount.add(-1) } } @@ -346,8 +327,7 @@ internal class ComputeServiceImpl( val request = SchedulingRequest(server, clock.millis()) queue.add(request) - _submittedServers.add(1) - _waitingServers.add(1) + _serversPending.add(1) requestSchedulingCycle() return request } @@ -395,7 +375,7 @@ internal class ComputeServiceImpl( if (request.isCancelled) { queue.poll() - _waitingServers.add(-1) + _serversPending.add(-1) continue } @@ -407,10 +387,10 @@ internal class ComputeServiceImpl( if (server.flavor.memorySize > maxMemory || server.flavor.cpuCount > maxCores) { // Remove the incoming image queue.poll() - _waitingServers.add(-1) - _unscheduledServers.add(1) + _serversPending.add(-1) + _schedulingAttemptsFailure.add(1) - logger.warn("Failed to spawn $server: does not fit [${clock.millis()}]") + logger.warn { "Failed to spawn $server: does not fit [${clock.instant()}]" } server.state = ServerState.TERMINATED continue @@ -423,8 +403,8 @@ internal class ComputeServiceImpl( // Remove request from queue queue.poll() - _waitingServers.add(-1) - _schedulerDuration.record(now - request.submitTime, server.attributes) + _serversPending.add(-1) + _schedulingLatency.record(now - request.submitTime, server.attributes) logger.info { "Assigned server $server to host $host." } @@ -439,12 +419,17 @@ internal class ComputeServiceImpl( server.host = host host.spawn(server) activeServers[server] = host + + _serversActive.add(1) + _schedulingAttemptsSuccess.add(1) } catch (e: Throwable) { - logger.error("Failed to deploy VM", e) + logger.error(e) { "Failed to deploy VM" } hv.instanceCount-- hv.provisionedCores -= server.flavor.cpuCount hv.availableMemory += server.flavor.memorySize + + _schedulingAttemptsError.add(1) } } } @@ -463,24 +448,22 @@ internal class ComputeServiceImpl( override fun onStateChanged(host: Host, newState: HostState) { when (newState) { HostState.UP -> { - logger.debug { "[${clock.millis()}] Host ${host.uid} state changed: $newState" } + logger.debug { "[${clock.instant()}] Host ${host.uid} state changed: $newState" } val hv = hostToView[host] if (hv != null) { // Corner case for when the hypervisor already exists availableHosts += hv - _availableHostCount.add(1) } // Re-schedule on the new machine requestSchedulingCycle() } HostState.DOWN -> { - logger.debug { "[${clock.millis()}] Host ${host.uid} state changed: $newState" } + logger.debug { "[${clock.instant()}] Host ${host.uid} state changed: $newState" } val hv = hostToView[host] ?: return availableHosts -= hv - _availableHostCount.add(-1) requestSchedulingCycle() } @@ -498,16 +481,12 @@ internal class ComputeServiceImpl( server.state = newState - if (newState == ServerState.RUNNING) { - _runningServers.add(1) - } else if (newState == ServerState.ERROR) { - _runningServers.add(-1) - } else if (newState == ServerState.TERMINATED || newState == ServerState.DELETED) { - logger.info { "[${clock.millis()}] Server ${server.uid} ${server.name} ${server.flavor} finished." } + if (newState == ServerState.TERMINATED || newState == ServerState.DELETED) { + logger.info { "[${clock.instant()}] Server ${server.uid} ${server.name} ${server.flavor} finished." } - activeServers -= server - _runningServers.add(-1) - _finishedServers.add(1) + if (activeServers.remove(server) != null) { + _serversActive.add(-1) + } val hv = hostToView[host] if (hv != null) { diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index f7f9336e..3ec424f1 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -153,11 +153,12 @@ abstract class Portfolio(name: String) : Experiment(name) { val monitorResults = collectServiceMetrics(clock.millis(), simulator.producers[0]) logger.debug { - "Finish " + - "SUBMIT=${monitorResults.instanceCount} " + - "FAIL=${monitorResults.failedInstanceCount} " + - "QUEUE=${monitorResults.queuedInstanceCount} " + - "RUNNING=${monitorResults.activeHostCount}" + "Scheduler " + + "Success=${monitorResults.attemptsSuccess} " + + "Failure=${monitorResults.attemptsFailure} " + + "Error=${monitorResults.attemptsError} " + + "Pending=${monitorResults.serversPending} " + + "Active=${monitorResults.serversActive}" } } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt index e1428fe7..29b48878 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt @@ -36,13 +36,13 @@ public class ParquetServiceDataWriter(path: File, bufferSize: Int) : override fun convert(builder: GenericRecordBuilder, data: ServiceData) { builder["timestamp"] = data.timestamp - builder["host_total_count"] = data.hostCount - builder["host_available_count"] = data.activeHostCount - builder["instance_total_count"] = data.instanceCount - builder["instance_active_count"] = data.runningInstanceCount - builder["instance_inactive_count"] = data.finishedInstanceCount - builder["instance_waiting_count"] = data.queuedInstanceCount - builder["instance_failed_count"] = data.failedInstanceCount + builder["hosts_up"] = data.hostsUp + builder["hosts_down"] = data.hostsDown + builder["servers_pending"] = data.serversPending + builder["servers_active"] = data.serversActive + builder["attempts_success"] = data.attemptsSuccess + builder["attempts_failure"] = data.attemptsFailure + builder["attempts_error"] = data.attemptsError } override fun toString(): String = "service-writer" @@ -53,13 +53,13 @@ public class ParquetServiceDataWriter(path: File, bufferSize: Int) : .namespace("org.opendc.telemetry.compute") .fields() .requiredLong("timestamp") - .requiredInt("host_total_count") - .requiredInt("host_available_count") - .requiredInt("instance_total_count") - .requiredInt("instance_active_count") - .requiredInt("instance_inactive_count") - .requiredInt("instance_waiting_count") - .requiredInt("instance_failed_count") + .requiredInt("hosts_up") + .requiredInt("hosts_down") + .requiredInt("servers_pending") + .requiredInt("servers_active") + .requiredInt("attempts_success") + .requiredInt("attempts_failure") + .requiredInt("attempts_error") .endRecord() } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index f4cf3e5e..81405acf 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -104,19 +104,20 @@ class CapelinIntegrationTest { val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( - "Finish " + - "SUBMIT=${serviceMetrics.instanceCount} " + - "FAIL=${serviceMetrics.failedInstanceCount} " + - "QUEUE=${serviceMetrics.queuedInstanceCount} " + - "RUNNING=${serviceMetrics.runningInstanceCount}" + "Scheduler " + + "Success=${serviceMetrics.attemptsSuccess} " + + "Failure=${serviceMetrics.attemptsFailure} " + + "Error=${serviceMetrics.attemptsError} " + + "Pending=${serviceMetrics.serversPending} " + + "Active=${serviceMetrics.serversActive}" ) // Note that these values have been verified beforehand assertAll( - { assertEquals(50, serviceMetrics.instanceCount, "The trace contains 50 VMs") }, - { assertEquals(0, serviceMetrics.runningInstanceCount, "All VMs should finish after a run") }, - { assertEquals(0, serviceMetrics.failedInstanceCount, "No VM should not be unscheduled") }, - { assertEquals(0, serviceMetrics.queuedInstanceCount, "No VM should not be in the queue") }, + { assertEquals(50, serviceMetrics.attemptsSuccess, "The scheduler should schedule 50 VMs") }, + { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, + { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, + { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, { assertEquals(220346412191, monitor.totalWork) { "Incorrect requested burst" } }, { assertEquals(206667852689, monitor.totalGrantedWork) { "Incorrect granted burst" } }, { assertEquals(1151612221, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, @@ -152,11 +153,12 @@ class CapelinIntegrationTest { val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( - "Finish " + - "SUBMIT=${serviceMetrics.instanceCount} " + - "FAIL=${serviceMetrics.failedInstanceCount} " + - "QUEUE=${serviceMetrics.queuedInstanceCount} " + - "RUNNING=${serviceMetrics.runningInstanceCount}" + "Scheduler " + + "Success=${serviceMetrics.attemptsSuccess} " + + "Failure=${serviceMetrics.attemptsFailure} " + + "Error=${serviceMetrics.attemptsError} " + + "Pending=${serviceMetrics.serversPending} " + + "Active=${serviceMetrics.serversActive}" ) // Note that these values have been verified beforehand @@ -202,11 +204,12 @@ class CapelinIntegrationTest { val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( - "Finish " + - "SUBMIT=${serviceMetrics.instanceCount} " + - "FAIL=${serviceMetrics.failedInstanceCount} " + - "QUEUE=${serviceMetrics.queuedInstanceCount} " + - "RUNNING=${serviceMetrics.runningInstanceCount}" + "Scheduler " + + "Success=${serviceMetrics.attemptsSuccess} " + + "Failure=${serviceMetrics.attemptsFailure} " + + "Error=${serviceMetrics.attemptsError} " + + "Pending=${serviceMetrics.serversPending} " + + "Active=${serviceMetrics.serversActive}" ) // Note that these values have been verified beforehand @@ -246,11 +249,12 @@ class CapelinIntegrationTest { val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) println( - "Finish " + - "SUBMIT=${serviceMetrics.instanceCount} " + - "FAIL=${serviceMetrics.failedInstanceCount} " + - "QUEUE=${serviceMetrics.queuedInstanceCount} " + - "RUNNING=${serviceMetrics.runningInstanceCount}" + "Scheduler " + + "Success=${serviceMetrics.attemptsSuccess} " + + "Failure=${serviceMetrics.attemptsFailure} " + + "Error=${serviceMetrics.attemptsError} " + + "Pending=${serviceMetrics.serversPending} " + + "Active=${serviceMetrics.serversActive}" ) // Note that these values have been verified beforehand diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt index 1f309f1b..f3690ee8 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt @@ -22,6 +22,7 @@ package org.opendc.telemetry.compute +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricProducer import org.opendc.telemetry.compute.table.ServiceData @@ -37,32 +38,48 @@ public fun collectServiceMetrics(timestamp: Long, metricProducer: MetricProducer * Extract a [ServiceData] object from the specified list of metric data. */ public fun extractServiceMetrics(timestamp: Long, metrics: Collection): ServiceData { - var submittedVms = 0 - var queuedVms = 0 - var unscheduledVms = 0 - var runningVms = 0 - var finishedVms = 0 - var hosts = 0 - var availableHosts = 0 + val resultKey = AttributeKey.stringKey("result") + val stateKey = AttributeKey.stringKey("state") - for (metric in metrics) { - val points = metric.longSumData.points + var hostsUp = 0 + var hostsDown = 0 - if (points.isEmpty()) { - continue - } + var serversPending = 0 + var serversActive = 0 - val value = points.first().value.toInt() + var attemptsSuccess = 0 + var attemptsFailure = 0 + var attemptsError = 0 + + for (metric in metrics) { when (metric.name) { - "servers.submitted" -> submittedVms = value - "servers.waiting" -> queuedVms = value - "servers.unscheduled" -> unscheduledVms = value - "servers.active" -> runningVms = value - "servers.finished" -> finishedVms = value - "hosts.total" -> hosts = value - "hosts.available" -> availableHosts = value + "scheduler.hosts" -> { + for (point in metric.longSumData.points) { + when (point.attributes[stateKey]) { + "up" -> hostsUp = point.value.toInt() + "down" -> hostsDown = point.value.toInt() + } + } + } + "scheduler.servers" -> { + for (point in metric.longSumData.points) { + when (point.attributes[stateKey]) { + "pending" -> serversPending = point.value.toInt() + "active" -> serversActive = point.value.toInt() + } + } + } + "scheduler.attempts" -> { + for (point in metric.longSumData.points) { + when (point.attributes[resultKey]) { + "success" -> attemptsSuccess = point.value.toInt() + "failure" -> attemptsFailure = point.value.toInt() + "error" -> attemptsError = point.value.toInt() + } + } + } } } - return ServiceData(timestamp, hosts, availableHosts, submittedVms, runningVms, finishedVms, queuedVms, unscheduledVms) + return ServiceData(timestamp, hostsUp, hostsDown, serversPending, serversActive, attemptsSuccess, attemptsFailure, attemptsError) } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt index f6ff5db5..da2ebdf4 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt @@ -27,11 +27,11 @@ package org.opendc.telemetry.compute.table */ public data class ServiceData( public val timestamp: Long, - public val hostCount: Int, - public val activeHostCount: Int, - public val instanceCount: Int, - public val runningInstanceCount: Int, - public val finishedInstanceCount: Int, - public val queuedInstanceCount: Int, - public val failedInstanceCount: Int + public val hostsUp: Int, + public val hostsDown: Int, + public val serversPending: Int, + public val serversActive: Int, + public val attemptsSuccess: Int, + public val attemptsFailure: Int, + public val attemptsError: Int ) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index b9d5a3f5..960d5ebd 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -226,11 +226,12 @@ class RunnerCli : CliktCommand(name = "runner") { val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) logger.debug { - "Finish " + - "SUBMIT=${serviceMetrics.instanceCount} " + - "FAIL=${serviceMetrics.failedInstanceCount} " + - "QUEUE=${serviceMetrics.queuedInstanceCount} " + - "RUNNING=${serviceMetrics.runningInstanceCount}" + "Scheduler " + + "Success=${serviceMetrics.attemptsSuccess} " + + "Failure=${serviceMetrics.attemptsFailure} " + + "Error=${serviceMetrics.attemptsError} " + + "Pending=${serviceMetrics.serversPending} " + + "Active=${serviceMetrics.serversActive}" } } } catch (cause: Throwable) { diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt index 4b813310..5f2c474b 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt @@ -81,11 +81,11 @@ class WebComputeMonitor : ComputeMonitor { override fun record(data: ServiceData) { serviceMetrics = AggregateServiceMetrics( - max(data.instanceCount, serviceMetrics.vmTotalCount), - max(data.queuedInstanceCount, serviceMetrics.vmWaitingCount), - max(data.runningInstanceCount, serviceMetrics.vmActiveCount), - max(data.finishedInstanceCount, serviceMetrics.vmInactiveCount), - max(data.failedInstanceCount, serviceMetrics.vmFailedCount), + max(data.attemptsSuccess, serviceMetrics.vmTotalCount), + max(data.serversPending, serviceMetrics.vmWaitingCount), + max(data.serversActive, serviceMetrics.vmActiveCount), + max(0, serviceMetrics.vmInactiveCount), + max(data.attemptsFailure, serviceMetrics.vmFailedCount), ) } -- cgit v1.2.3 From 0d8bccc68705d036fbf60f312d9c34ca4392c6b2 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 7 Sep 2021 17:30:46 +0200 Subject: refactor(telemetry): Standardize SimHost metrics This change standardizes the metrics emitted by SimHost instances and their guests based on the OpenTelemetry semantic conventions. We now also report CPU time as opposed to CPU work as this metric is more commonly used. --- .../opendc-compute-simulator/build.gradle.kts | 1 + .../kotlin/org/opendc/compute/simulator/SimHost.kt | 504 ++++++++++----------- .../org/opendc/compute/simulator/internal/Guest.kt | 305 +++++++++++++ .../compute/simulator/internal/GuestListener.kt | 38 ++ .../org/opendc/compute/simulator/SimHostTest.kt | 117 ++--- .../org/opendc/experiments/capelin/Portfolio.kt | 3 +- .../capelin/export/parquet/ParquetDataWriter.kt | 1 - .../export/parquet/ParquetHostDataWriter.kt | 56 ++- .../export/parquet/ParquetServerDataWriter.kt | 38 +- .../export/parquet/ParquetServiceDataWriter.kt | 2 +- .../experiments/capelin/CapelinIntegrationTest.kt | 66 +-- .../opendc/simulator/compute/SimAbstractMachine.kt | 8 +- .../simulator/compute/kernel/SimHypervisor.kt | 2 +- .../simulator/compute/kernel/SimHypervisorTest.kt | 8 +- .../telemetry/compute/ComputeMetricAggregator.kt | 448 ++++++++++++++++++ .../telemetry/compute/ComputeMetricExporter.kt | 243 +--------- .../kotlin/org/opendc/telemetry/compute/Helpers.kt | 55 +-- .../org/opendc/telemetry/compute/table/HostData.kt | 33 +- .../opendc/telemetry/compute/table/ServerData.kt | 19 +- .../opendc/telemetry/compute/table/ServiceData.kt | 18 +- .../sdk/metrics/export/CoroutineMetricReader.kt | 2 +- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 12 +- .../org/opendc/web/runner/ScenarioManager.kt | 8 +- .../org/opendc/web/runner/WebComputeMonitor.kt | 41 +- 24 files changed, 1285 insertions(+), 743 deletions(-) create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt create mode 100644 opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt create mode 100644 opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt diff --git a/opendc-compute/opendc-compute-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts index cad051e6..aaf69f78 100644 --- a/opendc-compute/opendc-compute-simulator/build.gradle.kts +++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts @@ -40,5 +40,6 @@ dependencies { testImplementation(projects.opendcSimulator.opendcSimulatorCore) testImplementation(projects.opendcTelemetry.opendcTelemetrySdk) + testImplementation(projects.opendcTelemetry.opendcTelemetryCompute) testRuntimeOnly(libs.slf4j.simple) } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index be6ef11e..793db907 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -26,13 +26,16 @@ import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.metrics.Meter import io.opentelemetry.api.metrics.MeterProvider -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement +import io.opentelemetry.api.metrics.ObservableLongMeasurement import kotlinx.coroutines.* import mu.KotlinLogging import org.opendc.compute.api.Flavor import org.opendc.compute.api.Server import org.opendc.compute.api.ServerState import org.opendc.compute.service.driver.* +import org.opendc.compute.simulator.internal.Guest +import org.opendc.compute.simulator.internal.GuestListener import org.opendc.simulator.compute.* import org.opendc.simulator.compute.kernel.SimHypervisor import org.opendc.simulator.compute.kernel.SimHypervisorProvider @@ -44,11 +47,11 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.resources.SimResourceDistributorMaxMin import org.opendc.simulator.resources.SimResourceInterpreter import java.util.* import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException +import kotlin.math.roundToLong /** * A [Host] that is simulates virtual machines on a physical machine using [SimHypervisor]. @@ -100,32 +103,29 @@ public class SimHost( /** * The hypervisor to run multiple workloads. */ - public val hypervisor: SimHypervisor = hypervisor.create( + private val hypervisor: SimHypervisor = hypervisor.create( interpreter, scalingGovernor = scalingGovernor, interferenceDomain = interferenceDomain, listener = object : SimHypervisor.Listener { override fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Double, + totalWork: Double, grantedWork: Double, overcommittedWork: Double, interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) { - _totalWork.add(requestedWork) - _grantedWork.add(grantedWork) - _overcommittedWork.add(overcommittedWork) - _interferedWork.add(interferedWork) - _cpuDemand.record(cpuDemand) - _cpuUsage.record(cpuUsage) - _powerUsage.record(machine.powerDraw) - - reportTime() + _cpuDemand = cpuDemand + _cpuUsage = cpuUsage + + collectTime() } } ) + private var _cpuUsage = 0.0 + private var _cpuDemand = 0.0 /** * The virtual machines running on the hypervisor. @@ -145,109 +145,23 @@ public class SimHost( override val model: HostModel = HostModel(model.cpus.size, model.memory.sumOf { it.size }) /** - * The total number of guests. - */ - private val _guests = meter.upDownCounterBuilder("guests.total") - .setDescription("Total number of guests") - .setUnit("1") - .build() - - /** - * The number of active guests on the host. - */ - private val _activeGuests = meter.upDownCounterBuilder("guests.active") - .setDescription("Number of active guests") - .setUnit("1") - .build() - - /** - * The CPU demand of the host. - */ - private val _cpuDemand = meter.histogramBuilder("cpu.demand") - .setDescription("The amount of CPU resources the guests would use if there were no CPU contention or CPU limits") - .setUnit("MHz") - .build() - - /** - * The CPU usage of the host. - */ - private val _cpuUsage = meter.histogramBuilder("cpu.usage") - .setDescription("The amount of CPU resources used by the host") - .setUnit("MHz") - .build() - - /** - * The power usage of the host. - */ - private val _powerUsage = meter.histogramBuilder("power.usage") - .setDescription("The amount of power used by the CPU") - .setUnit("W") - .build() - - /** - * The total amount of work supplied to the CPU. - */ - private val _totalWork = meter.counterBuilder("cpu.work.total") - .setDescription("The amount of work supplied to the CPU") - .setUnit("1") - .ofDoubles() - .build() - - /** - * The work performed by the CPU. - */ - private val _grantedWork = meter.counterBuilder("cpu.work.granted") - .setDescription("The amount of work performed by the CPU") - .setUnit("1") - .ofDoubles() - .build() - - /** - * The amount not performed by the CPU due to overcommitment. - */ - private val _overcommittedWork = meter.counterBuilder("cpu.work.overcommit") - .setDescription("The amount of work not performed by the CPU due to overcommitment") - .setUnit("1") - .ofDoubles() - .build() - - /** - * The amount of work not performed by the CPU due to interference. - */ - private val _interferedWork = meter.counterBuilder("cpu.work.interference") - .setDescription("The amount of work not performed by the CPU due to interference") - .setUnit("1") - .ofDoubles() - .build() - - /** - * The amount of time in the system. + * The [GuestListener] that listens for guest events. */ - private val _totalTime = meter.counterBuilder("host.time.total") - .setDescription("The amount of time in the system") - .setUnit("ms") - .build() - - /** - * The uptime of the host. - */ - private val _upTime = meter.counterBuilder("host.time.up") - .setDescription("The uptime of the host") - .setUnit("ms") - .build() + private val guestListener = object : GuestListener { + override fun onStart(guest: Guest) { + listeners.forEach { it.onStateChanged(this@SimHost, guest.server, guest.state) } + } - /** - * The downtime of the host. - */ - private val _downTime = meter.counterBuilder("host.time.down") - .setDescription("The downtime of the host") - .setUnit("ms") - .build() + override fun onStop(guest: Guest) { + listeners.forEach { it.onStateChanged(this@SimHost, guest.server, guest.state) } + } + } init { // Launch hypervisor onto machine scope.launch { try { + _bootTime = clock.millis() _state = HostState.UP machine.run(this@SimHost.hypervisor, emptyMap()) } catch (_: CancellationException) { @@ -259,29 +173,48 @@ public class SimHost( _state = HostState.DOWN } } - } - - private var _lastReport = clock.millis() - - private fun reportTime() { - if (!scope.isActive) - return - - val now = clock.millis() - val duration = now - _lastReport - - _totalTime.add(duration) - when (_state) { - HostState.UP -> _upTime.add(duration) - HostState.DOWN -> _downTime.add(duration) - } - // Track time of guests - for (guest in guests.values) { - guest.reportTime() - } - - _lastReport = now + meter.upDownCounterBuilder("system.guests") + .setDescription("Number of guests on this host") + .setUnit("1") + .buildWithCallback(::collectGuests) + meter.gaugeBuilder("system.cpu.limit") + .setDescription("Amount of CPU resources available to the host") + .buildWithCallback(::collectCpuLimit) + meter.gaugeBuilder("system.cpu.demand") + .setDescription("Amount of CPU resources the guests would use if there were no CPU contention or CPU limits") + .setUnit("MHz") + .buildWithCallback { result -> result.observe(_cpuDemand) } + meter.gaugeBuilder("system.cpu.usage") + .setDescription("Amount of CPU resources used by the host") + .setUnit("MHz") + .buildWithCallback { result -> result.observe(_cpuUsage) } + meter.gaugeBuilder("system.cpu.utilization") + .setDescription("Utilization of the CPU resources of the host") + .setUnit("%") + .buildWithCallback { result -> result.observe(_cpuUsage / _cpuLimit) } + meter.counterBuilder("system.cpu.time") + .setDescription("Amount of CPU time spent by the host") + .setUnit("s") + .buildWithCallback(::collectCpuTime) + meter.gaugeBuilder("system.power.usage") + .setDescription("Power usage of the host ") + .setUnit("W") + .buildWithCallback { result -> result.observe(machine.powerDraw) } + meter.counterBuilder("system.power.total") + .setDescription("Amount of energy used by the CPU") + .setUnit("J") + .ofDoubles() + .buildWithCallback(::collectPowerTotal) + meter.counterBuilder("system.time") + .setDescription("The uptime of the host") + .setUnit("s") + .buildWithCallback(::collectTime) + meter.gaugeBuilder("system.time.boot") + .setDescription("The boot time of the host") + .setUnit("1") + .ofLongs() + .buildWithCallback(::collectBootTime) } override fun canFit(server: Server): Boolean { @@ -295,8 +228,17 @@ public class SimHost( override suspend fun spawn(server: Server, start: Boolean) { val guest = guests.computeIfAbsent(server) { key -> require(canFit(key)) { "Server does not fit" } - _guests.add(1) - Guest(key, hypervisor.createMachine(key.flavor.toMachineModel(), key.name)) + + val machine = hypervisor.createMachine(key.flavor.toMachineModel(), key.name) + Guest( + scope.coroutineContext, + clock, + this, + mapper, + guestListener, + server, + machine + ) } if (start) { @@ -320,7 +262,6 @@ public class SimHost( override suspend fun delete(server: Server) { val guest = guests.remove(server) ?: return - _guests.add(-1) guest.terminate() } @@ -333,7 +274,7 @@ public class SimHost( } override fun close() { - reportTime() + reset() scope.cancel() machine.close() } @@ -341,21 +282,34 @@ public class SimHost( override fun toString(): String = "SimHost[uid=$uid,name=$name,model=$model]" public suspend fun fail() { - reportTime() - _state = HostState.DOWN + reset() + for (guest in guests.values) { guest.fail() } } public suspend fun recover() { - reportTime() + collectTime() _state = HostState.UP + _bootTime = clock.millis() + for (guest in guests.values) { guest.start() } } + /** + * Reset the machine. + */ + private fun reset() { + collectTime() + + _state = HostState.DOWN + _cpuUsage = 0.0 + _cpuDemand = 0.0 + } + /** * Convert flavor to machine model. */ @@ -368,162 +322,168 @@ public class SimHost( return MachineModel(processingUnits, memoryUnits) } - private fun onGuestStart(vm: Guest) { - _activeGuests.add(1) - listeners.forEach { it.onStateChanged(this, vm.server, vm.state) } - } + private val STATE_KEY = AttributeKey.stringKey("state") - private fun onGuestStop(vm: Guest) { - _activeGuests.add(-1) - listeners.forEach { it.onStateChanged(this, vm.server, vm.state) } - } + private val terminatedState = Attributes.of(STATE_KEY, "terminated") + private val runningState = Attributes.of(STATE_KEY, "running") + private val errorState = Attributes.of(STATE_KEY, "error") + private val invalidState = Attributes.of(STATE_KEY, "invalid") /** - * A virtual machine instance that the driver manages. + * Helper function to collect the guest counts on this host. */ - private inner class Guest(val server: Server, val machine: SimMachine) { - var state: ServerState = ServerState.TERMINATED - - /** - * The attributes of the guest. - */ - val attributes: Attributes = Attributes.builder() - .put(ResourceAttributes.HOST_NAME, server.name) - .put(ResourceAttributes.HOST_ID, server.uid.toString()) - .put(ResourceAttributes.HOST_TYPE, server.flavor.name) - .put(AttributeKey.longKey("host.num_cpus"), server.flavor.cpuCount.toLong()) - .put(AttributeKey.longKey("host.mem_capacity"), server.flavor.memorySize) - .put(AttributeKey.stringArrayKey("host.labels"), server.labels.map { (k, v) -> "$k:$v" }) - .put(ResourceAttributes.HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) - .put(ResourceAttributes.HOST_IMAGE_NAME, server.image.name) - .put(ResourceAttributes.HOST_IMAGE_ID, server.image.uid.toString()) - .build() - - /** - * The amount of time in the system. - */ - private val _totalTime = meter.counterBuilder("guest.time.total") - .setDescription("The amount of time in the system") - .setUnit("ms") - .build() - .bind(attributes) - - /** - * The uptime of the guest. - */ - private val _runningTime = meter.counterBuilder("guest.time.running") - .setDescription("The uptime of the guest") - .setUnit("ms") - .build() - .bind(attributes) - - /** - * The time the guest is in an error state. - */ - private val _errorTime = meter.counterBuilder("guest.time.error") - .setDescription("The time the guest is in an error state") - .setUnit("ms") - .build() - .bind(attributes) - - suspend fun start() { - when (state) { - ServerState.TERMINATED, ServerState.ERROR -> { - logger.info { "User requested to start server ${server.uid}" } - launch() - } - ServerState.RUNNING -> return - ServerState.DELETED -> { - logger.warn { "User tried to start terminated server" } - throw IllegalArgumentException("Server is terminated") - } - else -> assert(false) { "Invalid state transition" } + private fun collectGuests(result: ObservableLongMeasurement) { + var terminated = 0L + var running = 0L + var error = 0L + var invalid = 0L + + for ((_, guest) in guests) { + when (guest.state) { + ServerState.TERMINATED -> terminated++ + ServerState.RUNNING -> running++ + ServerState.ERROR -> error++ + else -> invalid++ } } - suspend fun stop() { - when (state) { - ServerState.RUNNING, ServerState.ERROR -> { - val job = job ?: throw IllegalStateException("Server should be active") - job.cancel() - job.join() - } - ServerState.TERMINATED, ServerState.DELETED -> return - else -> assert(false) { "Invalid state transition" } - } - } + result.observe(terminated, terminatedState) + result.observe(running, runningState) + result.observe(error, errorState) + result.observe(invalid, invalidState) + } - suspend fun terminate() { - stop() - machine.close() - state = ServerState.DELETED + private val _cpuLimit = machine.model.cpus.sumOf { it.frequency } + + /** + * Helper function to collect the CPU limits of a machine. + */ + private fun collectCpuLimit(result: ObservableDoubleMeasurement) { + result.observe(_cpuLimit) + + for (guest in guests.values) { + guest.collectCpuLimit(result) } + } - suspend fun fail() { - if (state != ServerState.RUNNING) { - return - } - stop() - state = ServerState.ERROR + private var _lastCpuTimeCallback = clock.millis() + + /** + * Helper function to track the CPU time of a machine. + */ + private fun collectCpuTime(result: ObservableLongMeasurement) { + val now = clock.millis() + val duration = now - _lastCpuTimeCallback + + try { + collectCpuTime(duration, result) + } finally { + _lastCpuTimeCallback = now } + } - private var job: Job? = null - - private suspend fun launch() = suspendCancellableCoroutine { cont -> - assert(job == null) { "Concurrent job running" } - val workload = mapper.createWorkload(server) - - job = scope.launch { - try { - delay(1) // TODO Introduce boot time - init() - cont.resume(Unit) - } catch (e: Throwable) { - cont.resumeWithException(e) - } - try { - machine.run(workload, mapOf("driver" to this@SimHost, "server" to server)) - exit(null) - } catch (cause: Throwable) { - exit(cause) - } finally { - job = null - } - } + private val _activeState = Attributes.of(STATE_KEY, "active") + private val _stealState = Attributes.of(STATE_KEY, "steal") + private val _lostState = Attributes.of(STATE_KEY, "lost") + private val _idleState = Attributes.of(STATE_KEY, "idle") + private var _totalTime = 0.0 + + /** + * Helper function to track the CPU time of a machine. + */ + private fun collectCpuTime(duration: Long, result: ObservableLongMeasurement) { + val coreCount = this.model.cpuCount + val d = coreCount / _cpuLimit + + val counters = hypervisor.counters + val grantedWork = counters.actual + val overcommittedWork = counters.overcommit + val interferedWork = (counters as? SimResourceDistributorMaxMin.Counters)?.interference ?: 0.0 + + _totalTime += (duration / 1000.0) * coreCount + val activeTime = (grantedWork * d).roundToLong() + val idleTime = (_totalTime - grantedWork * d).roundToLong() + val stealTime = (overcommittedWork * d).roundToLong() + val lostTime = (interferedWork * d).roundToLong() + + result.observe(activeTime, _activeState) + result.observe(idleTime, _idleState) + result.observe(stealTime, _stealState) + result.observe(lostTime, _lostState) + + for (guest in guests.values) { + guest.collectCpuTime(duration, result) } + } + + private var _lastPowerCallback = clock.millis() + private var _totalPower = 0.0 - private fun init() { - state = ServerState.RUNNING - onGuestStart(this) + /** + * Helper function to collect the total power usage of the machine. + */ + private fun collectPowerTotal(result: ObservableDoubleMeasurement) { + val now = clock.millis() + val duration = now - _lastPowerCallback + + _totalPower += duration / 1000.0 * machine.powerDraw + result.observe(_totalPower) + + _lastPowerCallback = now + } + + private var _lastReport = clock.millis() + + /** + * Helper function to track the uptime of a machine. + */ + private fun collectTime(result: ObservableLongMeasurement? = null) { + val now = clock.millis() + val duration = now - _lastReport + + try { + collectTime(duration, result) + } finally { + _lastReport = now } + } - private fun exit(cause: Throwable?) { - state = - if (cause == null) - ServerState.TERMINATED - else - ServerState.ERROR + private var _uptime = 0L + private var _downtime = 0L + private val _upState = Attributes.of(STATE_KEY, "up") + private val _downState = Attributes.of(STATE_KEY, "down") - onGuestStop(this) + /** + * Helper function to track the uptime of a machine. + */ + private fun collectTime(duration: Long, result: ObservableLongMeasurement? = null) { + if (state == HostState.UP) { + _uptime += duration + } else if (state == HostState.DOWN && scope.isActive) { + // Only increment downtime if the machine is in a failure state + _downtime += duration } - private var _lastReport = clock.millis() + result?.observe(_uptime, _upState) + result?.observe(_downtime, _downState) - fun reportTime() { - if (state == ServerState.DELETED) - return + for (guest in guests.values) { + guest.collectUptime(duration, result) + } + } - val now = clock.millis() - val duration = now - _lastReport + private var _bootTime = Long.MIN_VALUE - _totalTime.add(duration) - when (state) { - ServerState.RUNNING -> _runningTime.add(duration) - ServerState.ERROR -> _errorTime.add(duration) - else -> {} - } + /** + * Helper function to track the boot time of a machine. + */ + private fun collectBootTime(result: ObservableLongMeasurement? = null) { + if (_bootTime != Long.MIN_VALUE) { + result?.observe(_bootTime) + } - _lastReport = now + for (guest in guests.values) { + guest.collectBootTime(result) } } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt new file mode 100644 index 00000000..90562e2f --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.internal + +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement +import io.opentelemetry.api.metrics.ObservableLongMeasurement +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import kotlinx.coroutines.* +import mu.KotlinLogging +import org.opendc.compute.api.Server +import org.opendc.compute.api.ServerState +import org.opendc.compute.simulator.SimHost +import org.opendc.compute.simulator.SimWorkloadMapper +import org.opendc.simulator.compute.SimAbstractMachine +import org.opendc.simulator.compute.SimMachine +import org.opendc.simulator.compute.workload.SimWorkload +import java.time.Clock +import kotlin.coroutines.CoroutineContext +import kotlin.math.roundToLong + +/** + * A virtual machine instance that is managed by a [SimHost]. + */ +internal class Guest( + context: CoroutineContext, + private val clock: Clock, + val host: SimHost, + private val mapper: SimWorkloadMapper, + private val listener: GuestListener, + val server: Server, + val machine: SimMachine +) { + /** + * The [CoroutineScope] of the guest. + */ + private val scope: CoroutineScope = CoroutineScope(context + Job()) + + /** + * The logger instance of this guest. + */ + private val logger = KotlinLogging.logger {} + + /** + * The state of the [Guest]. + * + * [ServerState.PROVISIONING] is an invalid value for a guest, since it applies before the host is selected for + * a server. + */ + var state: ServerState = ServerState.TERMINATED + + /** + * The attributes of the guest. + */ + val attributes: Attributes = Attributes.builder() + .put(ResourceAttributes.HOST_NAME, server.name) + .put(ResourceAttributes.HOST_ID, server.uid.toString()) + .put(ResourceAttributes.HOST_TYPE, server.flavor.name) + .put(AttributeKey.longKey("host.num_cpus"), server.flavor.cpuCount.toLong()) + .put(AttributeKey.longKey("host.mem_capacity"), server.flavor.memorySize) + .put(AttributeKey.stringArrayKey("host.labels"), server.labels.map { (k, v) -> "$k:$v" }) + .put(ResourceAttributes.HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(ResourceAttributes.HOST_IMAGE_NAME, server.image.name) + .put(ResourceAttributes.HOST_IMAGE_ID, server.image.uid.toString()) + .build() + + /** + * Start the guest. + */ + suspend fun start() { + when (state) { + ServerState.TERMINATED, ServerState.ERROR -> { + logger.info { "User requested to start server ${server.uid}" } + doStart() + } + ServerState.RUNNING -> return + ServerState.DELETED -> { + logger.warn { "User tried to start terminated server" } + throw IllegalArgumentException("Server is terminated") + } + else -> assert(false) { "Invalid state transition" } + } + } + + /** + * Stop the guest. + */ + suspend fun stop() { + when (state) { + ServerState.RUNNING -> doStop(ServerState.TERMINATED) + ServerState.ERROR -> doRecover() + ServerState.TERMINATED, ServerState.DELETED -> return + else -> assert(false) { "Invalid state transition" } + } + } + + /** + * Terminate the guest. + * + * This operation will stop the guest if it is running on the host and remove all resources associated with the + * guest. + */ + suspend fun terminate() { + stop() + + state = ServerState.DELETED + + machine.close() + scope.cancel() + } + + /** + * Fail the guest if it is active. + * + * This operation forcibly stops the guest and puts the server into an error state. + */ + suspend fun fail() { + if (state != ServerState.RUNNING) { + return + } + + doStop(ServerState.ERROR) + } + + /** + * The [Job] representing the current active virtual machine instance or `null` if no virtual machine is active. + */ + private var job: Job? = null + + /** + * Launch the guest on the simulated + */ + private suspend fun doStart() { + assert(job == null) { "Concurrent job running" } + val workload = mapper.createWorkload(server) + + val job = scope.launch { runMachine(workload) } + this.job = job + + state = ServerState.RUNNING + onStart() + + job.invokeOnCompletion { cause -> + this.job = null + onStop(if (cause != null && cause !is CancellationException) ServerState.ERROR else ServerState.TERMINATED) + } + } + + /** + * Attempt to stop the server and put it into [target] state. + */ + private suspend fun doStop(target: ServerState) { + assert(job != null) { "Invalid job state" } + val job = job ?: return + job.cancel() + job.join() + + state = target + } + + /** + * Attempt to recover from an error state. + */ + private fun doRecover() { + state = ServerState.TERMINATED + } + + /** + * Run the process that models the virtual machine lifecycle as a coroutine. + */ + private suspend fun runMachine(workload: SimWorkload) { + delay(1) // TODO Introduce model for boot time + machine.run(workload, mapOf("driver" to host, "server" to server)) + } + + /** + * This method is invoked when the guest was started on the host and has booted into a running state. + */ + private fun onStart() { + _bootTime = clock.millis() + state = ServerState.RUNNING + listener.onStart(this) + } + + /** + * This method is invoked when the guest stopped. + */ + private fun onStop(target: ServerState) { + state = target + listener.onStop(this) + } + + private val STATE_KEY = AttributeKey.stringKey("state") + + private var _uptime = 0L + private var _downtime = 0L + private val _upState = Attributes.builder() + .putAll(attributes) + .put(STATE_KEY, "up") + .build() + private val _downState = Attributes.builder() + .putAll(attributes) + .put(STATE_KEY, "down") + .build() + + /** + * Helper function to track the uptime of the guest. + */ + fun collectUptime(duration: Long, result: ObservableLongMeasurement? = null) { + if (state == ServerState.RUNNING) { + _uptime += duration + } else if (state == ServerState.ERROR) { + _downtime += duration + } + + result?.observe(_uptime, _upState) + result?.observe(_downtime, _downState) + } + + private var _bootTime = Long.MIN_VALUE + + /** + * Helper function to track the boot time of the guest. + */ + fun collectBootTime(result: ObservableLongMeasurement? = null) { + if (_bootTime != Long.MIN_VALUE) { + result?.observe(_bootTime) + } + } + + private val _activeState = Attributes.builder() + .putAll(attributes) + .put(STATE_KEY, "active") + .build() + private val _stealState = Attributes.builder() + .putAll(attributes) + .put(STATE_KEY, "steal") + .build() + private val _lostState = Attributes.builder() + .putAll(attributes) + .put(STATE_KEY, "lost") + .build() + private val _idleState = Attributes.builder() + .putAll(attributes) + .put(STATE_KEY, "idle") + .build() + private var _totalTime = 0.0 + + /** + * Helper function to track the CPU time of a machine. + */ + fun collectCpuTime(duration: Long, result: ObservableLongMeasurement) { + val coreCount = server.flavor.cpuCount + val d = coreCount / _cpuLimit + + var grantedWork = 0.0 + var overcommittedWork = 0.0 + + for (cpu in (machine as SimAbstractMachine).cpus) { + val counters = cpu.counters + grantedWork += counters.actual + overcommittedWork += counters.overcommit + } + + _totalTime += (duration / 1000.0) * coreCount + val activeTime = (grantedWork * d).roundToLong() + val idleTime = (_totalTime - grantedWork * d).roundToLong() + val stealTime = (overcommittedWork * d).roundToLong() + + result.observe(activeTime, _activeState) + result.observe(idleTime, _idleState) + result.observe(stealTime, _stealState) + result.observe(0, _lostState) + } + + private val _cpuLimit = machine.model.cpus.sumOf { it.frequency } + + /** + * Helper function to collect the CPU limits of a machine. + */ + fun collectCpuLimit(result: ObservableDoubleMeasurement) { + result.observe(_cpuLimit, attributes) + } +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt new file mode 100644 index 00000000..e6d0fdad --- /dev/null +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.simulator.internal + +/** + * Helper interface to listen for [Guest] events. + */ +internal interface GuestListener { + /** + * This method is invoked when the guest machine is running. + */ + fun onStart(guest: Guest) + + /** + * This method is invoked when the guest machine is stopped. + */ + fun onStop(guest: Guest) +} diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 318b5a5d..9c879e5e 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -23,11 +23,9 @@ package org.opendc.compute.simulator import io.opentelemetry.api.metrics.MeterProvider -import io.opentelemetry.sdk.common.CompletableResultCode import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.metrics.data.MetricData -import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.sdk.metrics.export.MetricProducer +import io.opentelemetry.sdk.resources.Resource import kotlinx.coroutines.* import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach @@ -44,17 +42,20 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.telemetry.compute.ComputeMetricExporter +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.HOST_ID +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServerData import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import org.opendc.telemetry.sdk.toOtelClock import java.time.Duration import java.util.* import kotlin.coroutines.resume -import kotlin.math.roundToLong /** * Basic test-suite for the hypervisor. */ -@OptIn(ExperimentalCoroutinesApi::class) internal class SimHostTest { private lateinit var machineModel: MachineModel @@ -73,18 +74,23 @@ internal class SimHostTest { */ @Test fun testOvercommitted() = runBlockingSimulation { - var totalWork = 0L - var grantedWork = 0L - var overcommittedWork = 0L + var idleTime = 0L + var activeTime = 0L + var stealTime = 0L + val hostId = UUID.randomUUID() + val hostResource = Resource.builder() + .put(HOST_ID, hostId.toString()) + .build() val meterProvider: MeterProvider = SdkMeterProvider .builder() + .setResource(hostResource) .setClock(clock.toOtelClock()) .build() val interpreter = SimResourceInterpreter(coroutineContext, clock) val virtDriver = SimHost( - uid = UUID.randomUUID(), + uid = hostId, name = "test", model = machineModel, meta = emptyMap(), @@ -132,20 +138,16 @@ internal class SimHostTest { // Setup metric reader val reader = CoroutineMetricReader( this, listOf(meterProvider as MetricProducer), - object : MetricExporter { - override fun export(metrics: Collection): CompletableResultCode { - val metricsByName = metrics.associateBy { it.name } - - totalWork = metricsByName.getValue("cpu.work.total").doubleSumData.points.first().value.roundToLong() - grantedWork = metricsByName.getValue("cpu.work.granted").doubleSumData.points.first().value.roundToLong() - overcommittedWork = metricsByName.getValue("cpu.work.overcommit").doubleSumData.points.first().value.roundToLong() - return CompletableResultCode.ofSuccess() + ComputeMetricExporter( + clock, + object : ComputeMonitor { + override fun record(data: HostData) { + activeTime += data.cpuActiveTime + idleTime += data.cpuIdleTime + stealTime += data.cpuStealTime + } } - - override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() - - override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() - }, + ), exportInterval = Duration.ofSeconds(duration) ) @@ -172,9 +174,9 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(4147200, totalWork, "Requested work does not match") }, - { assertEquals(2107200, grantedWork, "Granted work does not match") }, - { assertEquals(2040000, overcommittedWork, "Overcommitted work does not match") }, + { assertEquals(659, activeTime, "Active time does not match") }, + { assertEquals(2342, idleTime, "Idle time does not match") }, + { assertEquals(638, stealTime, "Steal time does not match") }, { assertEquals(1500001, clock.millis()) } ) } @@ -184,21 +186,26 @@ internal class SimHostTest { */ @Test fun testFailure() = runBlockingSimulation { - var totalWork = 0L - var grantedWork = 0L - var totalTime = 0L - var downTime = 0L - var guestTotalTime = 0L - var guestDownTime = 0L - + var activeTime = 0L + var idleTime = 0L + var uptime = 0L + var downtime = 0L + var guestUptime = 0L + var guestDowntime = 0L + + val hostId = UUID.randomUUID() + val hostResource = Resource.builder() + .put(HOST_ID, hostId.toString()) + .build() val meterProvider: MeterProvider = SdkMeterProvider .builder() + .setResource(hostResource) .setClock(clock.toOtelClock()) .build() val interpreter = SimResourceInterpreter(coroutineContext, clock) val host = SimHost( - uid = UUID.randomUUID(), + uid = hostId, name = "test", model = machineModel, meta = emptyMap(), @@ -230,24 +237,22 @@ internal class SimHostTest { // Setup metric reader val reader = CoroutineMetricReader( this, listOf(meterProvider as MetricProducer), - object : MetricExporter { - override fun export(metrics: Collection): CompletableResultCode { - val metricsByName = metrics.associateBy { it.name } - - totalWork = metricsByName.getValue("cpu.work.total").doubleSumData.points.first().value.roundToLong() - grantedWork = metricsByName.getValue("cpu.work.granted").doubleSumData.points.first().value.roundToLong() - totalTime = metricsByName.getValue("host.time.total").longSumData.points.first().value - downTime = metricsByName.getValue("host.time.down").longSumData.points.first().value - guestTotalTime = metricsByName.getValue("guest.time.total").longSumData.points.first().value - guestDownTime = metricsByName.getValue("guest.time.error").longSumData.points.first().value - - return CompletableResultCode.ofSuccess() - } - - override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() + ComputeMetricExporter( + clock, + object : ComputeMonitor { + override fun record(data: HostData) { + activeTime += data.cpuActiveTime + idleTime += data.cpuIdleTime + uptime += data.uptime + downtime += data.downtime + } - override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() - }, + override fun record(data: ServerData) { + guestUptime += data.uptime + guestDowntime += data.downtime + } + } + ), exportInterval = Duration.ofSeconds(duration) ) @@ -276,12 +281,12 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(2226040, totalWork, "Total time does not match") }, - { assertEquals(1086040, grantedWork, "Down time does not match") }, - { assertEquals(1200001, totalTime, "Total time does not match") }, - { assertEquals(1200001, guestTotalTime, "Guest total time does not match") }, - { assertEquals(5000, downTime, "Down time does not match") }, - { assertEquals(5000, guestDownTime, "Guest down time does not match") }, + { assertEquals(2661, idleTime, "Idle time does not match") }, + { assertEquals(339, activeTime, "Active time does not match") }, + { assertEquals(1195001, uptime, "Uptime does not match") }, + { assertEquals(5000, downtime, "Downtime does not match") }, + { assertEquals(1195000, guestUptime, "Guest uptime does not match") }, + { assertEquals(5000, guestDowntime, "Guest downtime does not match") }, ) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 3ec424f1..6261ebbf 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -149,9 +149,10 @@ abstract class Portfolio(name: String) : Experiment(name) { } finally { simulator.close() metricReader.close() + monitor.close() } - val monitorResults = collectServiceMetrics(clock.millis(), simulator.producers[0]) + val monitorResults = collectServiceMetrics(clock.instant(), simulator.producers[0]) logger.debug { "Scheduler " + "Success=${monitorResults.attemptsSuccess} " + diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt index 5684bde9..e3d15c3b 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt @@ -27,7 +27,6 @@ import org.apache.avro.Schema import org.apache.avro.generic.GenericData import org.apache.avro.generic.GenericRecordBuilder import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.example.Paper.schema import org.apache.parquet.hadoop.ParquetFileWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt index fa00fc35..36207045 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt @@ -44,20 +44,31 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : } override fun convert(builder: GenericRecordBuilder, data: HostData) { - builder["timestamp"] = data.timestamp + builder["timestamp"] = data.timestamp.toEpochMilli() + builder["host_id"] = data.host.id - builder["powered_on"] = true + builder["num_cpus"] = data.host.cpuCount + builder["mem_capacity"] = data.host.memCapacity + builder["uptime"] = data.uptime builder["downtime"] = data.downtime - builder["total_work"] = data.totalWork - builder["granted_work"] = data.grantedWork - builder["overcommitted_work"] = data.overcommittedWork - builder["interfered_work"] = data.interferedWork - builder["cpu_usage"] = data.cpuUsage - builder["cpu_demand"] = data.cpuDemand - builder["power_draw"] = data.powerDraw - builder["num_instances"] = data.instanceCount - builder["num_cpus"] = data.host.cpuCount + val bootTime = data.bootTime + if (bootTime != null) { + builder["boot_time"] = bootTime.toEpochMilli() + } + + builder["cpu_limit"] = data.cpuLimit + builder["cpu_time_active"] = data.cpuActiveTime + builder["cpu_time_idle"] = data.cpuIdleTime + builder["cpu_time_steal"] = data.cpuStealTime + builder["cpu_time_lost"] = data.cpuLostTime + + builder["power_total"] = data.powerTotal + + builder["guests_terminated"] = data.guestsTerminated + builder["guests_running"] = data.guestsRunning + builder["guests_error"] = data.guestsError + builder["guests_invalid"] = data.guestsInvalid } override fun toString(): String = "host-writer" @@ -69,18 +80,21 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : .fields() .requiredLong("timestamp") .requiredString("host_id") - .requiredBoolean("powered_on") + .requiredInt("num_cpus") + .requiredLong("mem_capacity") .requiredLong("uptime") .requiredLong("downtime") - .requiredDouble("total_work") - .requiredDouble("granted_work") - .requiredDouble("overcommitted_work") - .requiredDouble("interfered_work") - .requiredDouble("cpu_usage") - .requiredDouble("cpu_demand") - .requiredDouble("power_draw") - .requiredInt("num_instances") - .requiredInt("num_cpus") + .optionalLong("boot_time") + .requiredDouble("cpu_limit") + .requiredLong("cpu_time_active") + .requiredLong("cpu_time_idle") + .requiredLong("cpu_time_steal") + .requiredLong("cpu_time_lost") + .requiredDouble("power_total") + .requiredInt("guests_terminated") + .requiredInt("guests_running") + .requiredInt("guests_error") + .requiredInt("guests_invalid") .endRecord() } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt index bb2db4b7..c5a5e7c0 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt @@ -40,18 +40,31 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { return builder .withDictionaryEncoding("server_id", true) - .withDictionaryEncoding("state", true) + .withDictionaryEncoding("host_id", true) .build() } override fun convert(builder: GenericRecordBuilder, data: ServerData) { - builder["timestamp"] = data.timestamp - builder["server_id"] = data.server - // builder["state"] = data.server.state + builder["timestamp"] = data.timestamp.toEpochMilli() + + builder["server_id"] = data.server.id + builder["host_id"] = data.host?.id + builder["num_vcpus"] = data.server.cpuCount + builder["mem_capacity"] = data.server.memCapacity + builder["uptime"] = data.uptime builder["downtime"] = data.downtime - // builder["num_vcpus"] = data.server.flavor.cpuCount - // builder["mem_capacity"] = data.server.flavor.memorySize + val bootTime = data.bootTime + if (bootTime != null) { + builder["boot_time"] = bootTime.toEpochMilli() + } + builder["scheduling_latency"] = data.schedulingLatency + + builder["cpu_limit"] = data.cpuLimit + builder["cpu_time_active"] = data.cpuActiveTime + builder["cpu_time_idle"] = data.cpuIdleTime + builder["cpu_time_steal"] = data.cpuStealTime + builder["cpu_time_lost"] = data.cpuLostTime } override fun toString(): String = "server-writer" @@ -63,11 +76,18 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : .fields() .requiredLong("timestamp") .requiredString("server_id") - .requiredString("state") - .requiredLong("uptime") - .requiredLong("downtime") + .optionalString("host_id") .requiredInt("num_vcpus") .requiredLong("mem_capacity") + .requiredLong("uptime") + .requiredLong("downtime") + .optionalLong("boot_time") + .requiredLong("scheduling_latency") + .requiredDouble("cpu_limit") + .requiredLong("cpu_time_active") + .requiredLong("cpu_time_idle") + .requiredLong("cpu_time_steal") + .requiredLong("cpu_time_lost") .endRecord() } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt index 29b48878..d9ca55cb 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt @@ -35,7 +35,7 @@ public class ParquetServiceDataWriter(path: File, bufferSize: Int) : ParquetDataWriter(path, SCHEMA, bufferSize) { override fun convert(builder: GenericRecordBuilder, data: ServiceData) { - builder["timestamp"] = data.timestamp + builder["timestamp"] = data.timestamp.toEpochMilli() builder["hosts_up"] = data.hostsUp builder["hosts_down"] = data.hostsDown builder["servers_pending"] = data.serversPending diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 81405acf..727530e3 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -50,7 +50,6 @@ import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.io.File import java.time.Duration import java.util.* -import kotlin.math.roundToLong /** * An integration test suite for the Capelin experiments. @@ -102,7 +101,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -118,11 +117,11 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, - { assertEquals(220346412191, monitor.totalWork) { "Incorrect requested burst" } }, - { assertEquals(206667852689, monitor.totalGrantedWork) { "Incorrect granted burst" } }, - { assertEquals(1151612221, monitor.totalOvercommittedWork) { "Incorrect overcommitted burst" } }, - { assertEquals(0, monitor.totalInterferedWork) { "Incorrect interfered burst" } }, - { assertEquals(9.088769763540529E7, monitor.totalPowerDraw, 0.01) { "Incorrect power draw" } }, + { assertEquals(223856043, monitor.idleTime) { "Incorrect idle time" } }, + { assertEquals(66481557, monitor.activeTime) { "Incorrect active time" } }, + { assertEquals(360441, monitor.stealTime) { "Incorrect steal time" } }, + { assertEquals(0, monitor.lostTime) { "Incorrect lost time" } }, + { assertEquals(5.418336360461193E9, monitor.energyUsage, 0.01) { "Incorrect power draw" } }, ) } @@ -151,7 +150,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -163,10 +162,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(39183965664, monitor.totalWork) { "Total work incorrect" } }, - { assertEquals(35649907631, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(1043642275, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, - { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } + { assertEquals(9597804, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(11140596, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(326138, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } } ) } @@ -202,7 +201,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -214,10 +213,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(39183965664, monitor.totalWork) { "Total work incorrect" } }, - { assertEquals(35649907631, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(1043642275, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, - { assertEquals(2960974524, monitor.totalInterferedWork) { "Total interfered work incorrect" } } + { assertEquals(9597804, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(11140596, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(326138, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(925305, monitor.lostTime) { "Lost time incorrect" } } ) } @@ -247,7 +246,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -259,10 +258,11 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(38385856700, monitor.totalWork) { "Total requested work incorrect" } }, - { assertEquals(34886670127, monitor.totalGrantedWork) { "Total granted work incorrect" } }, - { assertEquals(979997628, monitor.totalOvercommittedWork) { "Total overcommitted work incorrect" } }, - { assertEquals(0, monitor.totalInterferedWork) { "Total interfered work incorrect" } } + { assertEquals(9836315, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(10902085, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(306249, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, + { assertEquals(2540877457, monitor.uptime) { "Uptime incorrect" } } ) } @@ -286,18 +286,20 @@ class CapelinIntegrationTest { } class TestExperimentReporter : ComputeMonitor { - var totalWork = 0L - var totalGrantedWork = 0L - var totalOvercommittedWork = 0L - var totalInterferedWork = 0L - var totalPowerDraw = 0.0 + var idleTime = 0L + var activeTime = 0L + var stealTime = 0L + var lostTime = 0L + var energyUsage = 0.0 + var uptime = 0L override fun record(data: HostData) { - this.totalWork += data.totalWork.roundToLong() - totalGrantedWork += data.grantedWork.roundToLong() - totalOvercommittedWork += data.overcommittedWork.roundToLong() - totalInterferedWork += data.interferedWork.roundToLong() - totalPowerDraw += data.powerDraw + idleTime += data.cpuIdleTime + activeTime += data.cpuActiveTime + stealTime += data.cpuStealTime + lostTime += data.cpuLostTime + energyUsage += data.powerTotal + uptime += data.uptime } } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index 266db0dd..f9db048d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -49,22 +49,22 @@ public abstract class SimAbstractMachine( /** * The resources allocated for this machine. */ - protected abstract val cpus: List + public abstract val cpus: List /** * The memory interface of the machine. */ - protected val memory: SimMemory = Memory(SimResourceSource(model.memory.sumOf { it.size }.toDouble(), interpreter), model.memory) + public val memory: SimMemory = Memory(SimResourceSource(model.memory.sumOf { it.size }.toDouble(), interpreter), model.memory) /** * The network interfaces available to the machine. */ - protected val net: List = model.net.mapIndexed { i, adapter -> NetworkAdapterImpl(adapter, i) } + public val net: List = model.net.mapIndexed { i, adapter -> NetworkAdapterImpl(adapter, i) } /** * The network interfaces available to the machine. */ - protected val storage: List = model.storage.mapIndexed { i, device -> StorageDeviceImpl(interpreter, device, i) } + public val storage: List = model.storage.mapIndexed { i, device -> StorageDeviceImpl(interpreter, device, i) } /** * The peripherals of the machine. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt index af28c346..3b49d515 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt @@ -64,7 +64,7 @@ public interface SimHypervisor : SimWorkload { */ public fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Double, + totalWork: Double, grantedWork: Double, overcommittedWork: Double, interferedWork: Double, diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index 8dea0045..1f010338 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -70,14 +70,14 @@ internal class SimHypervisorTest { override fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Double, + totalWork: Double, grantedWork: Double, overcommittedWork: Double, interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) { - totalRequestedWork += requestedWork + totalRequestedWork += totalWork totalGrantedWork += grantedWork totalOvercommittedWork += overcommittedWork } @@ -128,14 +128,14 @@ internal class SimHypervisorTest { override fun onSliceFinish( hypervisor: SimHypervisor, - requestedWork: Double, + totalWork: Double, grantedWork: Double, overcommittedWork: Double, interferedWork: Double, cpuUsage: Double, cpuDemand: Double ) { - totalRequestedWork += requestedWork + totalRequestedWork += totalWork totalGrantedWork += grantedWork totalOvercommittedWork += overcommittedWork } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt new file mode 100644 index 00000000..e9449634 --- /dev/null +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.telemetry.compute + +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes +import io.opentelemetry.sdk.metrics.data.MetricData +import io.opentelemetry.sdk.metrics.data.PointData +import io.opentelemetry.sdk.resources.Resource +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import org.opendc.telemetry.compute.table.* +import java.time.Instant +import kotlin.math.roundToLong + +/** + * Helper class responsible for aggregating [MetricData] into [ServiceData], [HostData] and [ServerData]. + */ +public class ComputeMetricAggregator { + private val _service = ServiceAggregator() + private val _hosts = mutableMapOf() + private val _servers = mutableMapOf() + + /** + * Process the specified [metrics] for this cycle. + */ + public fun process(metrics: Collection) { + val service = _service + val hosts = _hosts + val servers = _servers + + for (metric in metrics) { + val resource = metric.resource + + when (metric.name) { + // ComputeService + "scheduler.hosts" -> { + for (point in metric.longSumData.points) { + when (point.attributes[STATE_KEY]) { + "up" -> service.hostsUp = point.value.toInt() + "down" -> service.hostsDown = point.value.toInt() + } + } + } + "scheduler.servers" -> { + for (point in metric.longSumData.points) { + when (point.attributes[STATE_KEY]) { + "pending" -> service.serversPending = point.value.toInt() + "active" -> service.serversActive = point.value.toInt() + } + } + } + "scheduler.attempts" -> { + for (point in metric.longSumData.points) { + when (point.attributes[RESULT_KEY]) { + "success" -> service.attemptsSuccess = point.value.toInt() + "failure" -> service.attemptsFailure = point.value.toInt() + "error" -> service.attemptsError = point.value.toInt() + } + } + } + "scheduler.latency" -> { + for (point in metric.doubleHistogramData.points) { + val server = getServer(servers, point) ?: continue + server.schedulingLatency = (point.sum / point.count).roundToLong() + } + } + + // SimHost + "system.guests" -> { + val agg = getHost(hosts, resource) ?: continue + + for (point in metric.longSumData.points) { + when (point.attributes[STATE_KEY]) { + "terminated" -> agg.guestsTerminated = point.value.toInt() + "running" -> agg.guestsRunning = point.value.toInt() + "error" -> agg.guestsRunning = point.value.toInt() + "invalid" -> agg.guestsInvalid = point.value.toInt() + } + } + } + "system.cpu.limit" -> { + val agg = getHost(hosts, resource) ?: continue + + for (point in metric.doubleGaugeData.points) { + val server = getServer(servers, point) + + if (server != null) { + server.cpuLimit = point.value + server.host = agg.host + } else { + agg.cpuLimit = point.value + } + } + } + "system.cpu.usage" -> { + val agg = getHost(hosts, resource) ?: continue + agg.cpuUsage = metric.doubleGaugeData.points.first().value + } + "system.cpu.demand" -> { + val agg = getHost(hosts, resource) ?: continue + agg.cpuDemand = metric.doubleGaugeData.points.first().value + } + "system.cpu.utilization" -> { + val agg = getHost(hosts, resource) ?: continue + agg.cpuUtilization = metric.doubleGaugeData.points.first().value + } + "system.cpu.time" -> { + val agg = getHost(hosts, resource) ?: continue + + for (point in metric.longSumData.points) { + val server = getServer(servers, point) + val state = point.attributes[STATE_KEY] + if (server != null) { + when (state) { + "active" -> server.cpuActiveTime = point.value + "idle" -> server.cpuIdleTime = point.value + "steal" -> server.cpuStealTime = point.value + "lost" -> server.cpuLostTime = point.value + } + server.host = agg.host + } else { + when (state) { + "active" -> agg.cpuActiveTime = point.value + "idle" -> agg.cpuIdleTime = point.value + "steal" -> agg.cpuStealTime = point.value + "lost" -> agg.cpuLostTime = point.value + } + } + } + } + "system.power.usage" -> { + val agg = getHost(hosts, resource) ?: continue + agg.powerUsage = metric.doubleGaugeData.points.first().value + } + "system.power.total" -> { + val agg = getHost(hosts, resource) ?: continue + agg.powerTotal = metric.doubleSumData.points.first().value + } + "system.time" -> { + val agg = getHost(hosts, resource) ?: continue + + for (point in metric.longSumData.points) { + val server = getServer(servers, point) + + if (server != null) { + when (point.attributes[STATE_KEY]) { + "up" -> server.uptime = point.value + "down" -> server.downtime = point.value + } + server.host = agg.host + } else { + when (point.attributes[STATE_KEY]) { + "up" -> agg.uptime = point.value + "down" -> agg.downtime = point.value + } + } + } + } + "system.time.boot" -> { + val agg = getHost(hosts, resource) ?: continue + + for (point in metric.longGaugeData.points) { + val server = getServer(servers, point) + + if (server != null) { + server.bootTime = point.value + server.host = agg.host + } else { + agg.bootTime = point.value + } + } + } + } + } + } + + /** + * Collect the data via the [monitor]. + */ + public fun collect(now: Instant, monitor: ComputeMonitor) { + monitor.record(_service.collect(now)) + + for (host in _hosts.values) { + monitor.record(host.collect(now)) + } + + for (server in _servers.values) { + monitor.record(server.collect(now)) + } + } + + /** + * Obtain the [HostAggregator] for the specified [resource]. + */ + private fun getHost(hosts: MutableMap, resource: Resource): HostAggregator? { + val id = resource.attributes[HOST_ID] + return if (id != null) { + hosts.computeIfAbsent(id) { HostAggregator(resource) } + } else { + null + } + } + + /** + * Obtain the [ServerAggregator] for the specified [point]. + */ + private fun getServer(servers: MutableMap, point: PointData): ServerAggregator? { + val id = point.attributes[ResourceAttributes.HOST_ID] + return if (id != null) { + servers.computeIfAbsent(id) { ServerAggregator(point.attributes) } + } else { + null + } + } + + /** + * An aggregator for service metrics before they are reported. + */ + internal class ServiceAggregator { + @JvmField var hostsUp = 0 + @JvmField var hostsDown = 0 + + @JvmField var serversPending = 0 + @JvmField var serversActive = 0 + + @JvmField var attemptsSuccess = 0 + @JvmField var attemptsFailure = 0 + @JvmField var attemptsError = 0 + + /** + * Finish the aggregation for this cycle. + */ + fun collect(now: Instant): ServiceData = toServiceData(now) + + /** + * Convert the aggregator state to an immutable [ServiceData]. + */ + private fun toServiceData(now: Instant): ServiceData { + return ServiceData(now, hostsUp, hostsDown, serversPending, serversActive, attemptsSuccess, attemptsFailure, attemptsError) + } + } + + /** + * An aggregator for host metrics before they are reported. + */ + internal class HostAggregator(resource: Resource) { + /** + * The static information about this host. + */ + val host = HostInfo( + resource.attributes[HOST_ID]!!, + resource.attributes[HOST_NAME] ?: "", + resource.attributes[HOST_ARCH] ?: "", + resource.attributes[HOST_NCPUS]?.toInt() ?: 0, + resource.attributes[HOST_MEM_CAPACITY] ?: 0, + ) + + @JvmField var guestsTerminated = 0 + @JvmField var guestsRunning = 0 + @JvmField var guestsError = 0 + @JvmField var guestsInvalid = 0 + + @JvmField var cpuLimit = 0.0 + @JvmField var cpuUsage = 0.0 + @JvmField var cpuDemand = 0.0 + @JvmField var cpuUtilization = 0.0 + + @JvmField var cpuActiveTime = 0L + @JvmField var cpuIdleTime = 0L + @JvmField var cpuStealTime = 0L + @JvmField var cpuLostTime = 0L + private var previousCpuActiveTime = 0L + private var previousCpuIdleTime = 0L + private var previousCpuStealTime = 0L + private var previousCpuLostTime = 0L + + @JvmField var powerUsage = 0.0 + @JvmField var powerTotal = 0.0 + private var previousPowerTotal = 0.0 + + @JvmField var uptime = 0L + private var previousUptime = 0L + @JvmField var downtime = 0L + private var previousDowntime = 0L + @JvmField var bootTime = Long.MIN_VALUE + + /** + * Finish the aggregation for this cycle. + */ + fun collect(now: Instant): HostData { + val data = toHostData(now) + + // Reset intermediate state for next aggregation + previousCpuActiveTime = cpuActiveTime + previousCpuIdleTime = cpuIdleTime + previousCpuStealTime = cpuStealTime + previousCpuLostTime = cpuLostTime + previousPowerTotal = powerTotal + previousUptime = uptime + previousDowntime = downtime + + guestsTerminated = 0 + guestsRunning = 0 + guestsError = 0 + guestsInvalid = 0 + + cpuLimit = 0.0 + cpuUsage = 0.0 + cpuDemand = 0.0 + cpuUtilization = 0.0 + + powerUsage = 0.0 + + return data + } + + /** + * Convert the aggregator state to an immutable [HostData] instance. + */ + private fun toHostData(now: Instant): HostData { + return HostData( + now, + host, + guestsTerminated, + guestsRunning, + guestsError, + guestsInvalid, + cpuLimit, + cpuUsage, + cpuDemand, + cpuUtilization, + cpuActiveTime - previousCpuActiveTime, + cpuIdleTime - previousCpuIdleTime, + cpuStealTime - previousCpuStealTime, + cpuLostTime - previousCpuLostTime, + powerUsage, + powerTotal - previousPowerTotal, + uptime - previousUptime, + downtime - previousDowntime, + if (bootTime != Long.MIN_VALUE) Instant.ofEpochMilli(bootTime) else null + ) + } + } + + /** + * An aggregator for server metrics before they are reported. + */ + internal class ServerAggregator(attributes: Attributes) { + /** + * The static information about this server. + */ + val server = ServerInfo( + attributes[ResourceAttributes.HOST_ID]!!, + attributes[ResourceAttributes.HOST_NAME]!!, + attributes[ResourceAttributes.HOST_TYPE]!!, + attributes[ResourceAttributes.HOST_ARCH]!!, + attributes[ResourceAttributes.HOST_IMAGE_ID]!!, + attributes[ResourceAttributes.HOST_IMAGE_NAME]!!, + attributes[AttributeKey.longKey("host.num_cpus")]!!.toInt(), + attributes[AttributeKey.longKey("host.mem_capacity")]!!, + ) + + /** + * The [HostInfo] of the host on which the server is hosted. + */ + var host: HostInfo? = null + + @JvmField var uptime: Long = 0 + private var previousUptime = 0L + @JvmField var downtime: Long = 0 + private var previousDowntime = 0L + @JvmField var bootTime: Long = 0 + @JvmField var schedulingLatency = 0L + @JvmField var cpuLimit = 0.0 + @JvmField var cpuActiveTime = 0L + @JvmField var cpuIdleTime = 0L + @JvmField var cpuStealTime = 0L + @JvmField var cpuLostTime = 0L + private var previousCpuActiveTime = 0L + private var previousCpuIdleTime = 0L + private var previousCpuStealTime = 0L + private var previousCpuLostTime = 0L + + /** + * Finish the aggregation for this cycle. + */ + fun collect(now: Instant): ServerData { + val data = toServerData(now) + + previousUptime = uptime + previousDowntime = downtime + previousCpuActiveTime = cpuActiveTime + previousCpuIdleTime = cpuIdleTime + previousCpuStealTime = cpuStealTime + previousCpuLostTime = cpuLostTime + + host = null + cpuLimit = 0.0 + + return data + } + + /** + * Convert the aggregator state into an immutable [ServerData]. + */ + private fun toServerData(now: Instant): ServerData { + return ServerData( + now, + server, + host, + uptime - previousUptime, + downtime - previousDowntime, + if (bootTime != Long.MIN_VALUE) Instant.ofEpochMilli(bootTime) else null, + schedulingLatency, + cpuLimit, + cpuActiveTime - previousCpuActiveTime, + cpuIdleTime - previousCpuIdleTime, + cpuStealTime - previousCpuStealTime, + cpuLostTime - previousCpuLostTime + ) + } + } + + private companion object { + private val STATE_KEY = AttributeKey.stringKey("state") + private val RESULT_KEY = AttributeKey.stringKey("result") + } +} diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt index 408d1325..ea96f721 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt @@ -22,28 +22,24 @@ package org.opendc.telemetry.compute -import io.opentelemetry.api.common.AttributeKey -import io.opentelemetry.api.common.Attributes import io.opentelemetry.sdk.common.CompletableResultCode import io.opentelemetry.sdk.metrics.data.* import io.opentelemetry.sdk.metrics.export.MetricExporter -import io.opentelemetry.sdk.resources.Resource -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes -import org.opendc.telemetry.compute.table.HostData -import org.opendc.telemetry.compute.table.HostInfo -import org.opendc.telemetry.compute.table.ServerData -import org.opendc.telemetry.compute.table.ServerInfo import java.time.Clock /** * A [MetricExporter] that redirects data to a [ComputeMonitor] implementation. */ public class ComputeMetricExporter(private val clock: Clock, private val monitor: ComputeMonitor) : MetricExporter { + /** + * A [ComputeMetricAggregator] that actually performs the aggregation. + */ + private val agg = ComputeMetricAggregator() + override fun export(metrics: Collection): CompletableResultCode { return try { - reportServiceMetrics(metrics) - reportHostMetrics(metrics) - reportServerMetrics(metrics) + agg.process(metrics) + agg.collect(clock.instant(), monitor) CompletableResultCode.ofSuccess() } catch (e: Throwable) { CompletableResultCode.ofFailure() @@ -53,229 +49,4 @@ public class ComputeMetricExporter(private val clock: Clock, private val monitor override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess() override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess() - - private fun reportServiceMetrics(metrics: Collection) { - monitor.record(extractServiceMetrics(clock.millis(), metrics)) - } - - private val hosts = mutableMapOf() - private val servers = mutableMapOf() - - private fun reportHostMetrics(metrics: Collection) { - val hosts = hosts - val servers = servers - - for (metric in metrics) { - val resource = metric.resource - val hostId = resource.attributes[HOST_ID] ?: continue - val agg = hosts.computeIfAbsent(hostId) { HostAggregator(resource) } - agg.accept(metric) - } - - val monitor = monitor - val now = clock.millis() - for ((_, server) in servers) { - server.record(monitor, now) - } - } - - private fun reportServerMetrics(metrics: Collection) { - val hosts = hosts - - for (metric in metrics) { - val resource = metric.resource - val host = resource.attributes[HOST_ID]?.let { hosts[it]?.host } - - when (metric.name) { - "scheduler.duration" -> mapByServer(metric.doubleHistogramData.points, host) { agg, point -> - agg.schedulingLatency = point.sum / point.count - } - "guest.time.running" -> mapByServer(metric.longSumData.points, host) { agg, point -> - agg.uptime = point.value - } - "guest.time.error" -> mapByServer(metric.longSumData.points, host) { agg, point -> - agg.downtime = point.value - } - } - } - - val monitor = monitor - val now = clock.millis() - for ((_, host) in hosts) { - host.record(monitor, now) - } - } - - /** - * Helper function to map a metric by the server. - */ - private inline fun

    mapByServer(points: Collection

    , host: HostInfo? = null, block: (ServerAggregator, P) -> Unit) { - for (point in points) { - val serverId = point.attributes[ResourceAttributes.HOST_ID] ?: continue - val agg = servers.computeIfAbsent(serverId) { ServerAggregator(point.attributes) } - - if (host != null) { - agg.host = host - } - - block(agg, point) - } - } - - /** - * An aggregator for host metrics before they are reported. - */ - private class HostAggregator(resource: Resource) { - /** - * The static information about this host. - */ - val host = HostInfo( - resource.attributes[HOST_ID]!!, - resource.attributes[HOST_NAME]!!, - resource.attributes[HOST_ARCH]!!, - resource.attributes[HOST_NCPUS]!!.toInt(), - resource.attributes[HOST_MEM_CAPACITY]!!, - ) - - private var totalWork: Double = 0.0 - private var previousTotalWork = 0.0 - private var grantedWork: Double = 0.0 - private var previousGrantedWork = 0.0 - private var overcommittedWork: Double = 0.0 - private var previousOvercommittedWork = 0.0 - private var interferedWork: Double = 0.0 - private var previousInterferedWork = 0.0 - private var cpuUsage: Double = 0.0 - private var cpuDemand: Double = 0.0 - private var instanceCount: Int = 0 - private var powerDraw: Double = 0.0 - private var uptime: Long = 0 - private var previousUptime = 0L - private var downtime: Long = 0 - private var previousDowntime = 0L - - fun record(monitor: ComputeMonitor, now: Long) { - monitor.record( - HostData( - now, - host, - totalWork - previousTotalWork, - grantedWork - previousGrantedWork, - overcommittedWork - previousOvercommittedWork, - interferedWork - previousInterferedWork, - cpuUsage, - cpuDemand, - instanceCount, - powerDraw, - uptime - previousUptime, - downtime - previousDowntime, - ) - ) - - previousTotalWork = totalWork - previousGrantedWork = grantedWork - previousOvercommittedWork = overcommittedWork - previousInterferedWork = interferedWork - previousUptime = uptime - previousDowntime = downtime - reset() - } - - /** - * Accept the [MetricData] for this host. - */ - fun accept(data: MetricData) { - when (data.name) { - "cpu.work.total" -> totalWork = data.doubleSumData.points.first().value - "cpu.work.granted" -> grantedWork = data.doubleSumData.points.first().value - "cpu.work.overcommit" -> overcommittedWork = data.doubleSumData.points.first().value - "cpu.work.interference" -> interferedWork = data.doubleSumData.points.first().value - "power.usage" -> powerDraw = acceptHistogram(data) - "cpu.usage" -> cpuUsage = acceptHistogram(data) - "cpu.demand" -> cpuDemand = acceptHistogram(data) - "guests.active" -> instanceCount = data.longSumData.points.first().value.toInt() - "host.time.up" -> uptime = data.longSumData.points.first().value - "host.time.down" -> downtime = data.longSumData.points.first().value - } - } - - private fun acceptHistogram(data: MetricData): Double { - return when (data.type) { - MetricDataType.HISTOGRAM -> { - val point = data.doubleHistogramData.points.first() - point.sum / point.count - } - MetricDataType.SUMMARY -> { - val point = data.doubleSummaryData.points.first() - point.sum / point.count - } - else -> error("Invalid metric type") - } - } - - private fun reset() { - totalWork = 0.0 - grantedWork = 0.0 - overcommittedWork = 0.0 - interferedWork = 0.0 - cpuUsage = 0.0 - cpuDemand = 0.0 - instanceCount = 0 - powerDraw = 0.0 - uptime = 0L - downtime = 0L - } - } - - /** - * An aggregator for server metrics before they are reported. - */ - private class ServerAggregator(attributes: Attributes) { - /** - * The static information about this server. - */ - val server = ServerInfo( - attributes[ResourceAttributes.HOST_ID]!!, - attributes[ResourceAttributes.HOST_NAME]!!, - attributes[ResourceAttributes.HOST_TYPE]!!, - attributes[ResourceAttributes.HOST_ARCH]!!, - attributes[ResourceAttributes.HOST_IMAGE_ID]!!, - attributes[ResourceAttributes.HOST_IMAGE_NAME]!!, - attributes[AttributeKey.longKey("host.num_cpus")]!!.toInt(), - attributes[AttributeKey.longKey("host.mem_capacity")]!!, - ) - - /** - * The [HostInfo] of the host on which the server is hosted. - */ - var host: HostInfo? = null - - @JvmField var uptime: Long = 0 - private var previousUptime = 0L - @JvmField var downtime: Long = 0 - private var previousDowntime = 0L - @JvmField var schedulingLatency = 0.0 - - fun record(monitor: ComputeMonitor, now: Long) { - monitor.record( - ServerData( - now, - server, - null, - uptime - previousUptime, - downtime - previousDowntime, - ) - ) - - previousUptime = uptime - previousDowntime = downtime - reset() - } - - private fun reset() { - host = null - uptime = 0L - downtime = 0L - } - } } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt index f3690ee8..25d346fb 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt @@ -22,64 +22,31 @@ package org.opendc.telemetry.compute -import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricProducer import org.opendc.telemetry.compute.table.ServiceData +import java.time.Instant /** * Collect the metrics of the compute service. */ -public fun collectServiceMetrics(timestamp: Long, metricProducer: MetricProducer): ServiceData { +public fun collectServiceMetrics(timestamp: Instant, metricProducer: MetricProducer): ServiceData { return extractServiceMetrics(timestamp, metricProducer.collectAllMetrics()) } /** * Extract a [ServiceData] object from the specified list of metric data. */ -public fun extractServiceMetrics(timestamp: Long, metrics: Collection): ServiceData { - val resultKey = AttributeKey.stringKey("result") - val stateKey = AttributeKey.stringKey("state") - - var hostsUp = 0 - var hostsDown = 0 - - var serversPending = 0 - var serversActive = 0 - - var attemptsSuccess = 0 - var attemptsFailure = 0 - var attemptsError = 0 - - for (metric in metrics) { - when (metric.name) { - "scheduler.hosts" -> { - for (point in metric.longSumData.points) { - when (point.attributes[stateKey]) { - "up" -> hostsUp = point.value.toInt() - "down" -> hostsDown = point.value.toInt() - } - } - } - "scheduler.servers" -> { - for (point in metric.longSumData.points) { - when (point.attributes[stateKey]) { - "pending" -> serversPending = point.value.toInt() - "active" -> serversActive = point.value.toInt() - } - } - } - "scheduler.attempts" -> { - for (point in metric.longSumData.points) { - when (point.attributes[resultKey]) { - "success" -> attemptsSuccess = point.value.toInt() - "failure" -> attemptsFailure = point.value.toInt() - "error" -> attemptsError = point.value.toInt() - } - } - } +public fun extractServiceMetrics(timestamp: Instant, metrics: Collection): ServiceData { + lateinit var serviceData: ServiceData + val agg = ComputeMetricAggregator() + val monitor = object : ComputeMonitor { + override fun record(data: ServiceData) { + serviceData = data } } - return ServiceData(timestamp, hostsUp, hostsDown, serversPending, serversActive, attemptsSuccess, attemptsFailure, attemptsError) + agg.process(metrics) + agg.collect(timestamp, monitor) + return serviceData } diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt index e3ecda3d..8e787b97 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/HostData.kt @@ -22,20 +22,29 @@ package org.opendc.telemetry.compute.table +import java.time.Instant + /** * A trace entry for a particular host. */ public data class HostData( - public val timestamp: Long, - public val host: HostInfo, - public val totalWork: Double, - public val grantedWork: Double, - public val overcommittedWork: Double, - public val interferedWork: Double, - public val cpuUsage: Double, - public val cpuDemand: Double, - public val instanceCount: Int, - public val powerDraw: Double, - public val uptime: Long, - public val downtime: Long, + val timestamp: Instant, + val host: HostInfo, + val guestsTerminated: Int, + val guestsRunning: Int, + val guestsError: Int, + val guestsInvalid: Int, + val cpuLimit: Double, + val cpuUsage: Double, + val cpuDemand: Double, + val cpuUtilization: Double, + val cpuActiveTime: Long, + val cpuIdleTime: Long, + val cpuStealTime: Long, + val cpuLostTime: Long, + val powerUsage: Double, + val powerTotal: Double, + val uptime: Long, + val downtime: Long, + val bootTime: Instant? ) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt index 7fde86d9..c48bff3a 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServerData.kt @@ -22,13 +22,22 @@ package org.opendc.telemetry.compute.table +import java.time.Instant + /** * A trace entry for a particular server. */ public data class ServerData( - public val timestamp: Long, - public val server: ServerInfo, - public val host: HostInfo?, - public val uptime: Long, - public val downtime: Long, + val timestamp: Instant, + val server: ServerInfo, + val host: HostInfo?, + val uptime: Long, + val downtime: Long, + val bootTime: Instant?, + val schedulingLatency: Long, + val cpuLimit: Double, + val cpuActiveTime: Long, + val cpuIdleTime: Long, + val cpuStealTime: Long, + val cpuLostTime: Long, ) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt index da2ebdf4..6db1399d 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/table/ServiceData.kt @@ -22,16 +22,18 @@ package org.opendc.telemetry.compute.table +import java.time.Instant + /** * A trace entry for the compute service. */ public data class ServiceData( - public val timestamp: Long, - public val hostsUp: Int, - public val hostsDown: Int, - public val serversPending: Int, - public val serversActive: Int, - public val attemptsSuccess: Int, - public val attemptsFailure: Int, - public val attemptsError: Int + val timestamp: Instant, + val hostsUp: Int, + val hostsDown: Int, + val serversPending: Int, + val serversActive: Int, + val attemptsSuccess: Int, + val attemptsFailure: Int, + val attemptsError: Int ) diff --git a/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt b/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt index 8f19ab81..07f0ff7f 100644 --- a/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt +++ b/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt @@ -44,7 +44,7 @@ public class CoroutineMetricReader( scope: CoroutineScope, private val producers: List, private val exporter: MetricExporter, - private val exportInterval: Duration = Duration.ofMinutes(1) + private val exportInterval: Duration = Duration.ofMinutes(5) ) : AutoCloseable { private val logger = KotlinLogging.logger {} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 960d5ebd..483558e1 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -26,8 +26,6 @@ import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.options.* import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.long -import io.opentelemetry.api.metrics.MeterProvider -import io.opentelemetry.sdk.metrics.SdkMeterProvider import kotlinx.coroutines.* import mu.KotlinLogging import org.opendc.experiments.capelin.* @@ -49,7 +47,6 @@ import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.collectServiceMetrics import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader -import org.opendc.telemetry.sdk.toOtelClock import org.opendc.web.client.ApiClient import org.opendc.web.client.AuthConfiguration import org.opendc.web.client.model.Scenario @@ -187,11 +184,6 @@ class RunnerCli : CliktCommand(name = "runner") { val seeder = Random(repeat.toLong()) - val meterProvider: MeterProvider = SdkMeterProvider - .builder() - .setClock(clock.toOtelClock()) - .build() - val operational = scenario.operationalPhenomena val computeScheduler = createComputeScheduler(operational.schedulerName, seeder) @@ -215,7 +207,7 @@ class RunnerCli : CliktCommand(name = "runner") { interferenceModel.takeIf { operational.performanceInterferenceEnabled } ) - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor), exportInterval = Duration.ofHours(1)) try { simulator.run(trace) @@ -224,7 +216,7 @@ class RunnerCli : CliktCommand(name = "runner") { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.millis(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) logger.debug { "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt index e0e3488f..a0c281e8 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt @@ -65,10 +65,10 @@ public class ScenarioManager(private val client: ApiClient) { client.updateJob( id, SimulationState.FINISHED, mapOf( - "total_requested_burst" to results.map { it.totalWork }, - "total_granted_burst" to results.map { it.totalGrantedWork }, - "total_overcommitted_burst" to results.map { it.totalOvercommittedWork }, - "total_interfered_burst" to results.map { it.totalInterferedWork }, + "total_requested_burst" to results.map { it.totalActiveTime + it.totalIdleTime }, + "total_granted_burst" to results.map { it.totalActiveTime }, + "total_overcommitted_burst" to results.map { it.totalStealTime }, + "total_interfered_burst" to results.map { it.totalLostTime }, "mean_cpu_usage" to results.map { it.meanCpuUsage }, "mean_cpu_demand" to results.map { it.meanCpuDemand }, "mean_num_deployed_images" to results.map { it.meanNumDeployedImages }, diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt index 5f2c474b..bb412738 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt @@ -33,24 +33,23 @@ import kotlin.math.roundToLong */ class WebComputeMonitor : ComputeMonitor { override fun record(data: HostData) { - val duration = data.uptime val slices = data.downtime / SLICE_LENGTH hostAggregateMetrics = AggregateHostMetrics( - hostAggregateMetrics.totalWork + data.totalWork, - hostAggregateMetrics.totalGrantedWork + data.grantedWork, - hostAggregateMetrics.totalOvercommittedWork + data.overcommittedWork, - hostAggregateMetrics.totalInterferedWork + data.overcommittedWork, - hostAggregateMetrics.totalPowerDraw + (duration * data.powerDraw) / 3600, + hostAggregateMetrics.totalActiveTime + data.cpuActiveTime, + hostAggregateMetrics.totalIdleTime + data.cpuIdleTime, + hostAggregateMetrics.totalStealTime + data.cpuStealTime, + hostAggregateMetrics.totalLostTime + data.cpuLostTime, + hostAggregateMetrics.totalPowerDraw + data.powerTotal, hostAggregateMetrics.totalFailureSlices + slices, - hostAggregateMetrics.totalFailureVmSlices + data.instanceCount * slices + hostAggregateMetrics.totalFailureVmSlices + data.guestsRunning * slices ) hostMetrics.compute(data.host.id) { _, prev -> HostMetrics( data.cpuUsage + (prev?.cpuUsage ?: 0.0), data.cpuDemand + (prev?.cpuDemand ?: 0.0), - data.instanceCount + (prev?.instanceCount ?: 0), + data.guestsRunning + (prev?.instanceCount ?: 0), 1 + (prev?.count ?: 0) ) } @@ -58,13 +57,13 @@ class WebComputeMonitor : ComputeMonitor { private var hostAggregateMetrics: AggregateHostMetrics = AggregateHostMetrics() private val hostMetrics: MutableMap = mutableMapOf() - private val SLICE_LENGTH: Long = 5 * 60 * 1000 + private val SLICE_LENGTH: Long = 5 * 60 data class AggregateHostMetrics( - val totalWork: Double = 0.0, - val totalGrantedWork: Double = 0.0, - val totalOvercommittedWork: Double = 0.0, - val totalInterferedWork: Double = 0.0, + val totalActiveTime: Long = 0L, + val totalIdleTime: Long = 0L, + val totalStealTime: Long = 0L, + val totalLostTime: Long = 0L, val totalPowerDraw: Double = 0.0, val totalFailureSlices: Double = 0.0, val totalFailureVmSlices: Double = 0.0, @@ -99,10 +98,10 @@ class WebComputeMonitor : ComputeMonitor { fun getResult(): Result { return Result( - hostAggregateMetrics.totalWork, - hostAggregateMetrics.totalGrantedWork, - hostAggregateMetrics.totalOvercommittedWork, - hostAggregateMetrics.totalInterferedWork, + hostAggregateMetrics.totalActiveTime, + hostAggregateMetrics.totalIdleTime, + hostAggregateMetrics.totalStealTime, + hostAggregateMetrics.totalLostTime, hostMetrics.map { it.value.cpuUsage / it.value.count }.average(), hostMetrics.map { it.value.cpuDemand / it.value.count }.average(), hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.average(), @@ -118,10 +117,10 @@ class WebComputeMonitor : ComputeMonitor { } data class Result( - val totalWork: Double, - val totalGrantedWork: Double, - val totalOvercommittedWork: Double, - val totalInterferedWork: Double, + val totalActiveTime: Long, + val totalIdleTime: Long, + val totalStealTime: Long, + val totalLostTime: Long, val meanCpuUsage: Double, val meanCpuDemand: Double, val meanNumDeployedImages: Double, -- cgit v1.2.3 From e2537c59bef0645b948e92553cc5a42a8c0f7256 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 15 Sep 2021 21:34:00 +0200 Subject: feat(capelin): Use logical types for Parquet output columns This change updates the output schema for the experiment data to use logical types where possible. This adds additional context for the writer and the reader on how to process the column (efficiently). --- .../capelin/export/parquet/AvroUtils.kt | 44 ++++++++++++++++++++++ .../export/parquet/ParquetHostDataWriter.kt | 15 ++++---- .../export/parquet/ParquetServerDataWriter.kt | 18 +++++---- .../export/parquet/ParquetServiceDataWriter.kt | 2 +- 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt new file mode 100644 index 00000000..a4676f31 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("AvroUtils") +package org.opendc.experiments.capelin.export.parquet + +import org.apache.avro.LogicalTypes +import org.apache.avro.Schema + +/** + * Schema for UUID type. + */ +internal val UUID_SCHEMA = LogicalTypes.uuid().addToSchema(Schema.create(Schema.Type.STRING)) + +/** + * Schema for timestamp type. + */ +internal val TIMESTAMP_SCHEMA = LogicalTypes.timestampMillis().addToSchema(Schema.create(Schema.Type.LONG)) + +/** + * Helper function to make a [Schema] field optional. + */ +internal fun Schema.optional(): Schema { + return Schema.createUnion(Schema.create(Schema.Type.NULL), this) +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt index 36207045..58388cb1 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt @@ -47,8 +47,6 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : builder["timestamp"] = data.timestamp.toEpochMilli() builder["host_id"] = data.host.id - builder["num_cpus"] = data.host.cpuCount - builder["mem_capacity"] = data.host.memCapacity builder["uptime"] = data.uptime builder["downtime"] = data.downtime @@ -57,12 +55,15 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : builder["boot_time"] = bootTime.toEpochMilli() } + builder["cpu_count"] = data.host.cpuCount builder["cpu_limit"] = data.cpuLimit builder["cpu_time_active"] = data.cpuActiveTime builder["cpu_time_idle"] = data.cpuIdleTime builder["cpu_time_steal"] = data.cpuStealTime builder["cpu_time_lost"] = data.cpuLostTime + builder["mem_limit"] = data.host.memCapacity + builder["power_total"] = data.powerTotal builder["guests_terminated"] = data.guestsTerminated @@ -78,18 +79,18 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : .record("host") .namespace("org.opendc.telemetry.compute") .fields() - .requiredLong("timestamp") - .requiredString("host_id") - .requiredInt("num_cpus") - .requiredLong("mem_capacity") + .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() + .name("host_id").type(UUID_SCHEMA).noDefault() .requiredLong("uptime") .requiredLong("downtime") - .optionalLong("boot_time") + .name("boot_time").type(TIMESTAMP_SCHEMA.optional()).noDefault() + .requiredInt("cpu_count") .requiredDouble("cpu_limit") .requiredLong("cpu_time_active") .requiredLong("cpu_time_idle") .requiredLong("cpu_time_steal") .requiredLong("cpu_time_lost") + .requiredLong("mem_limit") .requiredDouble("power_total") .requiredInt("guests_terminated") .requiredInt("guests_running") diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt index c5a5e7c0..43b5f469 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt @@ -30,6 +30,7 @@ import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.opendc.telemetry.compute.table.ServerData import java.io.File +import java.util.* /** * A Parquet event writer for [ServerData]s. @@ -49,8 +50,6 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : builder["server_id"] = data.server.id builder["host_id"] = data.host?.id - builder["num_vcpus"] = data.server.cpuCount - builder["mem_capacity"] = data.server.memCapacity builder["uptime"] = data.uptime builder["downtime"] = data.downtime @@ -60,11 +59,14 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : } builder["scheduling_latency"] = data.schedulingLatency + builder["cpu_count"] = data.server.cpuCount builder["cpu_limit"] = data.cpuLimit builder["cpu_time_active"] = data.cpuActiveTime builder["cpu_time_idle"] = data.cpuIdleTime builder["cpu_time_steal"] = data.cpuStealTime builder["cpu_time_lost"] = data.cpuLostTime + + builder["mem_limit"] = data.server.memCapacity } override fun toString(): String = "server-writer" @@ -74,20 +76,20 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : .record("server") .namespace("org.opendc.telemetry.compute") .fields() - .requiredLong("timestamp") - .requiredString("server_id") - .optionalString("host_id") - .requiredInt("num_vcpus") - .requiredLong("mem_capacity") + .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() + .name("server_id").type(UUID_SCHEMA).noDefault() + .name("host_id").type(UUID_SCHEMA.optional()).noDefault() .requiredLong("uptime") .requiredLong("downtime") - .optionalLong("boot_time") + .name("boot_time").type(TIMESTAMP_SCHEMA.optional()).noDefault() .requiredLong("scheduling_latency") + .requiredInt("cpu_count") .requiredDouble("cpu_limit") .requiredLong("cpu_time_active") .requiredLong("cpu_time_idle") .requiredLong("cpu_time_steal") .requiredLong("cpu_time_lost") + .requiredLong("mem_limit") .endRecord() } } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt index d9ca55cb..2928f445 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt @@ -52,7 +52,7 @@ public class ParquetServiceDataWriter(path: File, bufferSize: Int) : .record("service") .namespace("org.opendc.telemetry.compute") .fields() - .requiredLong("timestamp") + .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() .requiredInt("hosts_up") .requiredInt("hosts_down") .requiredInt("servers_pending") -- cgit v1.2.3 From e26b81568db1b08c87dd43d416e129e32d5de26b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 13 Sep 2021 14:39:38 +0200 Subject: fix(simulator): Support workload/machine CPU count mismatch This change allows workloads that require more CPUs than available on the machine to still function properly. --- .../org/opendc/simulator/compute/workload/SimTraceWorkload.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index 48be8e1a..5a4c4f44 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -27,6 +27,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext +import kotlin.math.min /** * A [SimWorkload] that replays a workload trace consisting of multiple fragments, each indicating the resource @@ -89,15 +90,16 @@ public class SimTraceWorkload(public val trace: Sequence, private val return SimResourceCommand.Idle(timestamp) } + val cores = min(cpu.node.coreCount, fragment.cores) val usage = if (fragment.cores > 0) - fragment.usage / fragment.cores + fragment.usage / cores else 0.0 val deadline = timestamp + fragment.duration val duration = deadline - now val work = duration * usage / 1000 - return if (cpu.id < fragment.cores && work > 0.0) + return if (cpu.id < cores && work > 0.0) SimResourceCommand.Consume(work, usage, deadline) else SimResourceCommand.Idle(deadline) -- cgit v1.2.3 From 859ce303f0b9110c7110b918e5957c2156fa8b26 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 17 Sep 2021 17:48:02 +0200 Subject: refactor(capelin): Extract common code out of Capelin experiments This change creates a new module for doing simulations with virtual machine workloads. We have found that a lot of code in the Capelin experiments code is being re-used by non-experiment modules. --- gradle/libs.versions.toml | 1 + .../opendc-compute-workload/build.gradle.kts | 49 ++++ .../compute/workload/ComputeWorkloadRunner.kt | 222 ++++++++++++++++++ .../org/opendc/compute/workload/FailureModel.kt | 38 +++ .../org/opendc/compute/workload/FailureModels.kt | 69 ++++++ .../org/opendc/compute/workload/env/MachineDef.kt | 38 +++ .../workload/export/parquet/ParquetDataWriter.kt | 145 ++++++++++++ .../export/parquet/ParquetExportMonitor.kt | 67 ++++++ .../export/parquet/ParquetHostDataWriter.kt | 104 ++++++++ .../export/parquet/ParquetServerDataWriter.kt | 97 ++++++++ .../export/parquet/ParquetServiceDataWriter.kt | 66 ++++++ .../workload/trace/RawParquetTraceReader.kt | 139 +++++++++++ .../workload/trace/StreamingParquetTraceReader.kt | 261 +++++++++++++++++++++ .../compute/workload/trace/TraceConverter.kt | 260 ++++++++++++++++++++ .../opendc/compute/workload/trace/TraceEntry.kt | 42 ++++ .../opendc/compute/workload/trace/TraceReader.kt | 32 +++ .../trace/azure/AzureResourceStateTable.kt | 127 ++++++++++ .../trace/azure/AzureResourceStateTableReader.kt | 149 ++++++++++++ .../workload/trace/azure/AzureResourceTable.kt | 54 +++++ .../trace/azure/AzureResourceTableReader.kt | 168 +++++++++++++ .../compute/workload/trace/azure/AzureTrace.kt | 46 ++++ .../workload/trace/azure/AzureTraceFormat.kt | 56 +++++ .../workload/trace/bp/BPResourceStateTable.kt | 53 +++++ .../trace/bp/BPResourceStateTableReader.kt | 103 ++++++++ .../compute/workload/trace/bp/BPResourceTable.kt | 53 +++++ .../workload/trace/bp/BPResourceTableReader.kt | 103 ++++++++ .../opendc/compute/workload/trace/bp/BPTrace.kt | 49 ++++ .../compute/workload/trace/bp/BPTraceFormat.kt | 47 ++++ .../opendc/compute/workload/trace/bp/Schemas.kt | 55 +++++ .../workload/trace/sv/SvResourceStateTable.kt | 138 +++++++++++ .../trace/sv/SvResourceStateTableReader.kt | 212 +++++++++++++++++ .../opendc/compute/workload/trace/sv/SvTrace.kt | 45 ++++ .../compute/workload/trace/sv/SvTraceFormat.kt | 47 ++++ .../workload/util/PerformanceInterferenceReader.kt | 68 ++++++ .../util/PerformanceInterferenceReaderTest.kt | 45 ++++ .../src/test/resources/perf-interference.json | 22 ++ .../opendc-experiments-capelin/build.gradle.kts | 11 +- .../org/opendc/experiments/capelin/Portfolio.kt | 21 +- .../capelin/env/ClusterEnvironmentReader.kt | 1 + .../experiments/capelin/env/EnvironmentReader.kt | 1 + .../opendc/experiments/capelin/env/MachineDef.kt | 38 --- .../capelin/export/parquet/AvroUtils.kt | 44 ---- .../capelin/export/parquet/ParquetDataWriter.kt | 145 ------------ .../capelin/export/parquet/ParquetExportMonitor.kt | 67 ------ .../export/parquet/ParquetHostDataWriter.kt | 101 -------- .../export/parquet/ParquetServerDataWriter.kt | 95 -------- .../export/parquet/ParquetServiceDataWriter.kt | 65 ----- .../capelin/trace/ParquetTraceReader.kt | 10 +- .../capelin/trace/PerformanceInterferenceReader.kt | 60 ----- .../capelin/trace/RawParquetTraceReader.kt | 139 ----------- .../capelin/trace/StreamingParquetTraceReader.kt | 261 --------------------- .../experiments/capelin/trace/TraceConverter.kt | 260 -------------------- .../opendc/experiments/capelin/trace/TraceEntry.kt | 44 ---- .../experiments/capelin/trace/TraceReader.kt | 32 --- .../experiments/capelin/trace/VmPlacementReader.kt | 47 ---- .../experiments/capelin/trace/WorkloadSampler.kt | 3 +- .../capelin/trace/azure/AzureResourceStateTable.kt | 127 ---------- .../trace/azure/AzureResourceStateTableReader.kt | 149 ------------ .../capelin/trace/azure/AzureResourceTable.kt | 54 ----- .../trace/azure/AzureResourceTableReader.kt | 169 ------------- .../experiments/capelin/trace/azure/AzureTrace.kt | 46 ---- .../capelin/trace/azure/AzureTraceFormat.kt | 56 ----- .../capelin/trace/bp/BPResourceStateTable.kt | 53 ----- .../capelin/trace/bp/BPResourceStateTableReader.kt | 103 -------- .../capelin/trace/bp/BPResourceTable.kt | 53 ----- .../capelin/trace/bp/BPResourceTableReader.kt | 103 -------- .../opendc/experiments/capelin/trace/bp/BPTrace.kt | 49 ---- .../experiments/capelin/trace/bp/BPTraceFormat.kt | 47 ---- .../opendc/experiments/capelin/trace/bp/Schemas.kt | 55 ----- .../capelin/trace/sv/SvResourceStateTable.kt | 138 ----------- .../capelin/trace/sv/SvResourceStateTableReader.kt | 212 ----------------- .../opendc/experiments/capelin/trace/sv/SvTrace.kt | 45 ---- .../experiments/capelin/trace/sv/SvTraceFormat.kt | 47 ---- .../capelin/util/ComputeServiceSimulator.kt | 222 ------------------ .../experiments/capelin/util/FailureModel.kt | 38 --- .../experiments/capelin/util/FailureModels.kt | 97 -------- .../experiments/capelin/util/VmPlacementReader.kt | 47 ++++ .../src/main/resources/log4j2.xml | 2 +- .../experiments/capelin/CapelinIntegrationTest.kt | 17 +- .../trace/PerformanceInterferenceReaderTest.kt | 45 ---- .../org/opendc/trace/util/parquet/AvroUtils.kt | 44 ++++ .../src/main/kotlin/org/opendc/web/runner/Main.kt | 12 +- settings.gradle.kts | 1 + 83 files changed, 3408 insertions(+), 3338 deletions(-) create mode 100644 opendc-compute/opendc-compute-workload/build.gradle.kts create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetDataWriter.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServiceDataWriter.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/test/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReaderTest.kt create mode 100644 opendc-compute/opendc-compute-workload/src/test/resources/perf-interference.json delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/VmPlacementReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt create mode 100644 opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/AvroUtils.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3f0e180b..11580338 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -53,6 +53,7 @@ progressbar = { module = "me.tongfei:progressbar", version.ref = "progressbar" } # Format jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } jackson-dataformat-csv = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-csv", version.ref = "jackson" } diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts new file mode 100644 index 00000000..390c7455 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/build.gradle.kts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support library for simulating VM-based workloads with OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcCompute.opendcComputeSimulator) + + implementation(projects.opendcTrace.opendcTraceParquet) + implementation(projects.opendcTrace.opendcTraceBitbrains) + implementation(projects.opendcSimulator.opendcSimulatorCore) + implementation(projects.opendcSimulator.opendcSimulatorCompute) + implementation(projects.opendcTelemetry.opendcTelemetrySdk) + implementation(projects.opendcTelemetry.opendcTelemetryCompute) + implementation(libs.opentelemetry.semconv) + + implementation(libs.kotlin.logging) + implementation(libs.clikt) + implementation(libs.jackson.databind) + implementation(libs.jackson.module.kotlin) + implementation(libs.jackson.dataformat.csv) + implementation(kotlin("reflect")) +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt new file mode 100644 index 00000000..cc9f2705 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload + +import io.opentelemetry.sdk.metrics.SdkMeterProvider +import io.opentelemetry.sdk.metrics.export.MetricProducer +import io.opentelemetry.sdk.resources.Resource +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield +import org.opendc.compute.service.ComputeService +import org.opendc.compute.service.scheduler.ComputeScheduler +import org.opendc.compute.simulator.SimHost +import org.opendc.compute.workload.env.MachineDef +import org.opendc.compute.workload.trace.TraceReader +import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider +import org.opendc.simulator.compute.kernel.SimHypervisorProvider +import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel +import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.telemetry.compute.* +import org.opendc.telemetry.sdk.toOtelClock +import java.time.Clock +import kotlin.coroutines.CoroutineContext +import kotlin.math.max + +/** + * Helper class to simulated VM-based workloads in OpenDC. + */ +public class ComputeWorkloadRunner( + private val context: CoroutineContext, + private val clock: Clock, + scheduler: ComputeScheduler, + machines: List, + private val failureModel: FailureModel? = null, + interferenceModel: VmInterferenceModel? = null, + hypervisorProvider: SimHypervisorProvider = SimFairShareHypervisorProvider() +) : AutoCloseable { + /** + * The [ComputeService] that has been configured by the manager. + */ + public val service: ComputeService + + /** + * The [MetricProducer] that are used by the [ComputeService] and the simulated hosts. + */ + public val producers: List + get() = _metricProducers + private val _metricProducers = mutableListOf() + + /** + * The [SimResourceInterpreter] to simulate the hosts. + */ + private val interpreter = SimResourceInterpreter(context, clock) + + /** + * The hosts that belong to this class. + */ + private val hosts = mutableSetOf() + + init { + val (service, serviceMeterProvider) = createService(scheduler) + this._metricProducers.add(serviceMeterProvider) + this.service = service + + for (def in machines) { + val (host, hostMeterProvider) = createHost(def, hypervisorProvider, interferenceModel) + this._metricProducers.add(hostMeterProvider) + hosts.add(host) + this.service.addHost(host) + } + } + + /** + * Run a simulation of the [ComputeService] by replaying the workload trace given by [reader]. + */ + public suspend fun run(reader: TraceReader) { + val injector = failureModel?.createInjector(context, clock, service) + val client = service.newClient() + + // Create new image for the virtual machine + val image = client.newImage("vm-image") + + try { + coroutineScope { + // Start the fault injector + injector?.start() + + var offset = Long.MIN_VALUE + + while (reader.hasNext()) { + val entry = reader.next() + + if (offset < 0) { + offset = entry.start - clock.millis() + } + + // Make sure the trace entries are ordered by submission time + assert(entry.start - offset >= 0) { "Invalid trace order" } + delay(max(0, (entry.start - offset) - clock.millis())) + + launch { + val workloadOffset = -offset + 300001 + val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) + + val server = client.newServer( + entry.name, + image, + client.newFlavor( + entry.name, + entry.meta["cores"] as Int, + entry.meta["required-memory"] as Long + ), + meta = entry.meta + mapOf("workload" to workload) + ) + + // Wait for the server reach its end time + val endTime = entry.meta["end-time"] as Long + delay(endTime + workloadOffset - clock.millis() + 1) + + // Delete the server after reaching the end-time of the virtual machine + server.delete() + } + } + } + + yield() + } finally { + injector?.close() + reader.close() + client.close() + } + } + + override fun close() { + service.close() + + for (host in hosts) { + host.close() + } + + hosts.clear() + } + + /** + * Construct a [ComputeService] instance. + */ + private fun createService(scheduler: ComputeScheduler): Pair { + val resource = Resource.builder() + .put(ResourceAttributes.SERVICE_NAME, "opendc-compute") + .build() + + val meterProvider = SdkMeterProvider.builder() + .setClock(clock.toOtelClock()) + .setResource(resource) + .build() + + val service = ComputeService(context, clock, meterProvider, scheduler) + return service to meterProvider + } + + /** + * Construct a [SimHost] instance for the specified [MachineDef]. + */ + private fun createHost( + def: MachineDef, + hypervisorProvider: SimHypervisorProvider, + interferenceModel: VmInterferenceModel? = null + ): Pair { + val resource = Resource.builder() + .put(HOST_ID, def.uid.toString()) + .put(HOST_NAME, def.name) + .put(HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(HOST_NCPUS, def.model.cpus.size) + .put(HOST_MEM_CAPACITY, def.model.memory.sumOf { it.size }) + .build() + + val meterProvider = SdkMeterProvider.builder() + .setClock(clock.toOtelClock()) + .setResource(resource) + .build() + + val host = SimHost( + def.uid, + def.name, + def.model, + def.meta, + context, + interpreter, + meterProvider, + hypervisorProvider, + powerDriver = SimplePowerDriver(def.powerModel), + interferenceDomain = interferenceModel?.newDomain() + ) + + return host to meterProvider + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt new file mode 100644 index 00000000..43dd8321 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload + +import org.opendc.compute.service.ComputeService +import org.opendc.compute.simulator.failure.HostFaultInjector +import java.time.Clock +import kotlin.coroutines.CoroutineContext + +/** + * Factory interface for constructing [HostFaultInjector] for modeling failures of compute service hosts. + */ +public interface FailureModel { + /** + * Construct a [HostFaultInjector] for the specified [service]. + */ + public fun createInjector(context: CoroutineContext, clock: Clock, service: ComputeService): HostFaultInjector +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt new file mode 100644 index 00000000..55c61be1 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("FailureModels") +package org.opendc.compute.workload + +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.service.ComputeService +import org.opendc.compute.simulator.SimHost +import org.opendc.compute.simulator.failure.HostFaultInjector +import org.opendc.compute.simulator.failure.StartStopHostFault +import org.opendc.compute.simulator.failure.StochasticVictimSelector +import java.time.Clock +import java.time.Duration +import kotlin.coroutines.CoroutineContext +import kotlin.math.ln +import kotlin.random.Random + +/** + * Obtain a [FailureModel] based on the GRID'5000 failure trace. + * + * This fault injector uses parameters from the GRID'5000 failure trace as described in + * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. + */ +public fun grid5000(failureInterval: Duration, seed: Int): FailureModel { + return object : FailureModel { + override fun createInjector( + context: CoroutineContext, + clock: Clock, + service: ComputeService + ): HostFaultInjector { + val rng = Well19937c(seed) + val hosts = service.hosts.map { it as SimHost }.toSet() + + // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 + // GRID'5000 + return HostFaultInjector( + context, + clock, + hosts, + iat = LogNormalDistribution(rng, ln(failureInterval.toHours().toDouble()), 1.03), + selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), + fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) + ) + } + + override fun toString(): String = "Grid5000FailureModel" + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt new file mode 100644 index 00000000..c1695696 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.env + +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.power.PowerModel +import java.util.* + +/** + * A definition of a machine in a cluster. + */ +public data class MachineDef( + val uid: UUID, + val name: String, + val meta: Map, + val model: MachineModel, + val powerModel: PowerModel +) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetDataWriter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetDataWriter.kt new file mode 100644 index 00000000..4172d729 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetDataWriter.kt @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.export.parquet + +import mu.KotlinLogging +import org.apache.avro.Schema +import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetFileWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.trace.util.parquet.LocalOutputFile +import java.io.File +import java.util.concurrent.ArrayBlockingQueue +import java.util.concurrent.BlockingQueue +import kotlin.concurrent.thread + +/** + * A writer that writes data in Parquet format. + */ +public abstract class ParquetDataWriter( + path: File, + private val schema: Schema, + bufferSize: Int = 4096 +) : AutoCloseable { + /** + * The logging instance to use. + */ + private val logger = KotlinLogging.logger {} + + /** + * The queue of commands to process. + */ + private val queue: BlockingQueue = ArrayBlockingQueue(bufferSize) + + /** + * An exception to be propagated to the actual writer. + */ + private var exception: Throwable? = null + + /** + * The thread that is responsible for writing the Parquet records. + */ + private val writerThread = thread(start = false, name = this.toString()) { + val writer = let { + val builder = AvroParquetWriter.builder(LocalOutputFile(path)) + .withSchema(schema) + .withCompressionCodec(CompressionCodecName.ZSTD) + .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) + buildWriter(builder) + } + + val queue = queue + val buf = mutableListOf() + var shouldStop = false + + try { + while (!shouldStop) { + try { + process(writer, queue.take()) + } catch (e: InterruptedException) { + shouldStop = true + } + + if (queue.drainTo(buf) > 0) { + for (data in buf) { + process(writer, data) + } + buf.clear() + } + } + } catch (e: Throwable) { + logger.error(e) { "Failure in Parquet data writer" } + exception = e + } finally { + writer.close() + } + } + + /** + * Build the [ParquetWriter] used to write the Parquet files. + */ + protected open fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { + return builder.build() + } + + /** + * Convert the specified [data] into a Parquet record. + */ + protected abstract fun convert(builder: GenericRecordBuilder, data: T) + + /** + * Write the specified metrics to the database. + */ + public fun write(data: T) { + val exception = exception + if (exception != null) { + throw IllegalStateException("Writer thread failed", exception) + } + + queue.put(data) + } + + /** + * Signal the writer to stop. + */ + override fun close() { + writerThread.interrupt() + writerThread.join() + } + + init { + writerThread.start() + } + + /** + * Process the specified [data] to be written to the Parquet file. + */ + private fun process(writer: ParquetWriter, data: T) { + val builder = GenericRecordBuilder(schema) + convert(builder, data) + writer.write(builder.build()) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt new file mode 100644 index 00000000..f41a2241 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.export.parquet + +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServerData +import org.opendc.telemetry.compute.table.ServiceData +import java.io.File + +/** + * A [ComputeMonitor] that logs the events to a Parquet file. + */ +public class ParquetExportMonitor(base: File, partition: String, bufferSize: Int) : ComputeMonitor, AutoCloseable { + private val serverWriter = ParquetServerDataWriter( + File(base, "server/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + private val hostWriter = ParquetHostDataWriter( + File(base, "host/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + private val serviceWriter = ParquetServiceDataWriter( + File(base, "service/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + override fun record(data: ServerData) { + serverWriter.write(data) + } + + override fun record(data: HostData) { + hostWriter.write(data) + } + + override fun record(data: ServiceData) { + serviceWriter.write(data) + } + + override fun close() { + hostWriter.close() + serviceWriter.close() + serverWriter.close() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt new file mode 100644 index 00000000..37066a0d --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.export.parquet + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.opendc.telemetry.compute.table.HostData +import org.opendc.trace.util.parquet.TIMESTAMP_SCHEMA +import org.opendc.trace.util.parquet.UUID_SCHEMA +import org.opendc.trace.util.parquet.optional +import java.io.File + +/** + * A Parquet event writer for [HostData]s. + */ +public class ParquetHostDataWriter(path: File, bufferSize: Int) : + ParquetDataWriter(path, SCHEMA, bufferSize) { + + override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { + return builder + .withDictionaryEncoding("host_id", true) + .build() + } + + override fun convert(builder: GenericRecordBuilder, data: HostData) { + builder["timestamp"] = data.timestamp.toEpochMilli() + + builder["host_id"] = data.host.id + + builder["uptime"] = data.uptime + builder["downtime"] = data.downtime + val bootTime = data.bootTime + if (bootTime != null) { + builder["boot_time"] = bootTime.toEpochMilli() + } + + builder["cpu_count"] = data.host.cpuCount + builder["cpu_limit"] = data.cpuLimit + builder["cpu_time_active"] = data.cpuActiveTime + builder["cpu_time_idle"] = data.cpuIdleTime + builder["cpu_time_steal"] = data.cpuStealTime + builder["cpu_time_lost"] = data.cpuLostTime + + builder["mem_limit"] = data.host.memCapacity + + builder["power_total"] = data.powerTotal + + builder["guests_terminated"] = data.guestsTerminated + builder["guests_running"] = data.guestsRunning + builder["guests_error"] = data.guestsError + builder["guests_invalid"] = data.guestsInvalid + } + + override fun toString(): String = "host-writer" + + private companion object { + private val SCHEMA: Schema = SchemaBuilder + .record("host") + .namespace("org.opendc.telemetry.compute") + .fields() + .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() + .name("host_id").type(UUID_SCHEMA).noDefault() + .requiredLong("uptime") + .requiredLong("downtime") + .name("boot_time").type(TIMESTAMP_SCHEMA.optional()).noDefault() + .requiredInt("cpu_count") + .requiredDouble("cpu_limit") + .requiredLong("cpu_time_active") + .requiredLong("cpu_time_idle") + .requiredLong("cpu_time_steal") + .requiredLong("cpu_time_lost") + .requiredLong("mem_limit") + .requiredDouble("power_total") + .requiredInt("guests_terminated") + .requiredInt("guests_running") + .requiredInt("guests_error") + .requiredInt("guests_invalid") + .endRecord() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt new file mode 100644 index 00000000..bea23d32 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.export.parquet + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.opendc.telemetry.compute.table.ServerData +import org.opendc.trace.util.parquet.TIMESTAMP_SCHEMA +import org.opendc.trace.util.parquet.UUID_SCHEMA +import org.opendc.trace.util.parquet.optional +import java.io.File + +/** + * A Parquet event writer for [ServerData]s. + */ +public class ParquetServerDataWriter(path: File, bufferSize: Int) : + ParquetDataWriter(path, SCHEMA, bufferSize) { + + override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { + return builder + .withDictionaryEncoding("server_id", true) + .withDictionaryEncoding("host_id", true) + .build() + } + + override fun convert(builder: GenericRecordBuilder, data: ServerData) { + builder["timestamp"] = data.timestamp.toEpochMilli() + + builder["server_id"] = data.server.id + builder["host_id"] = data.host?.id + + builder["uptime"] = data.uptime + builder["downtime"] = data.downtime + val bootTime = data.bootTime + if (bootTime != null) { + builder["boot_time"] = bootTime.toEpochMilli() + } + builder["scheduling_latency"] = data.schedulingLatency + + builder["cpu_count"] = data.server.cpuCount + builder["cpu_limit"] = data.cpuLimit + builder["cpu_time_active"] = data.cpuActiveTime + builder["cpu_time_idle"] = data.cpuIdleTime + builder["cpu_time_steal"] = data.cpuStealTime + builder["cpu_time_lost"] = data.cpuLostTime + + builder["mem_limit"] = data.server.memCapacity + } + + override fun toString(): String = "server-writer" + + private companion object { + private val SCHEMA: Schema = SchemaBuilder + .record("server") + .namespace("org.opendc.telemetry.compute") + .fields() + .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() + .name("server_id").type(UUID_SCHEMA).noDefault() + .name("host_id").type(UUID_SCHEMA.optional()).noDefault() + .requiredLong("uptime") + .requiredLong("downtime") + .name("boot_time").type(TIMESTAMP_SCHEMA.optional()).noDefault() + .requiredLong("scheduling_latency") + .requiredInt("cpu_count") + .requiredDouble("cpu_limit") + .requiredLong("cpu_time_active") + .requiredLong("cpu_time_idle") + .requiredLong("cpu_time_steal") + .requiredLong("cpu_time_lost") + .requiredLong("mem_limit") + .endRecord() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServiceDataWriter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServiceDataWriter.kt new file mode 100644 index 00000000..47824b29 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServiceDataWriter.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.export.parquet + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericRecordBuilder +import org.opendc.telemetry.compute.table.ServiceData +import org.opendc.trace.util.parquet.TIMESTAMP_SCHEMA +import java.io.File + +/** + * A Parquet event writer for [ServiceData]s. + */ +public class ParquetServiceDataWriter(path: File, bufferSize: Int) : + ParquetDataWriter(path, SCHEMA, bufferSize) { + + override fun convert(builder: GenericRecordBuilder, data: ServiceData) { + builder["timestamp"] = data.timestamp.toEpochMilli() + builder["hosts_up"] = data.hostsUp + builder["hosts_down"] = data.hostsDown + builder["servers_pending"] = data.serversPending + builder["servers_active"] = data.serversActive + builder["attempts_success"] = data.attemptsSuccess + builder["attempts_failure"] = data.attemptsFailure + builder["attempts_error"] = data.attemptsError + } + + override fun toString(): String = "service-writer" + + private companion object { + private val SCHEMA: Schema = SchemaBuilder + .record("service") + .namespace("org.opendc.telemetry.compute") + .fields() + .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() + .requiredInt("hosts_up") + .requiredInt("hosts_down") + .requiredInt("servers_pending") + .requiredInt("servers_active") + .requiredInt("attempts_success") + .requiredInt("attempts_failure") + .requiredInt("attempts_error") + .endRecord() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt new file mode 100644 index 00000000..ae20482d --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace + +import org.opendc.compute.workload.trace.bp.BPTraceFormat +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.trace.* +import java.io.File +import java.util.UUID + +/** + * A [TraceReader] for the internal VM workload trace format. + * + * @param path The directory of the traces. + */ +public class RawParquetTraceReader(private val path: File) { + /** + * The [Trace] that represents this trace. + */ + private val trace = BPTraceFormat().open(path.toURI().toURL()) + + /** + * Read the fragments into memory. + */ + private fun parseFragments(): Map> { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + val fragments = mutableMapOf>() + + return try { + while (reader.nextRow()) { + val id = reader.get(RESOURCE_STATE_ID) + val time = reader.get(RESOURCE_STATE_TIMESTAMP) + val duration = reader.get(RESOURCE_STATE_DURATION) + val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) + + val fragment = SimTraceWorkload.Fragment( + time.toEpochMilli(), + duration.toMillis(), + cpuUsage, + cores + ) + + fragments.getOrPut(id) { mutableListOf() }.add(fragment) + } + + fragments + } finally { + reader.close() + } + } + + /** + * Read the metadata into a workload. + */ + private fun parseMeta(fragments: Map>): List> { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() + + var counter = 0 + val entries = mutableListOf>() + + return try { + while (reader.nextRow()) { + + val id = reader.get(RESOURCE_ID) + if (!fragments.containsKey(id)) { + continue + } + + val submissionTime = reader.get(RESOURCE_START_TIME) + val endTime = reader.get(RESOURCE_STOP_TIME) + val maxCores = reader.getInt(RESOURCE_NCPUS) + val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB + val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) + + val vmFragments = fragments.getValue(id).asSequence() + val totalLoad = vmFragments.sumOf { it.usage } * 5 * 60 // avg MHz * duration = MFLOPs + val workload = SimTraceWorkload(vmFragments) + entries.add( + TraceEntry( + uid, id, submissionTime.toEpochMilli(), workload, + mapOf( + "submit-time" to submissionTime.toEpochMilli(), + "end-time" to endTime.toEpochMilli(), + "total-load" to totalLoad, + "cores" to maxCores, + "required-memory" to requiredMemory.toLong(), + "workload" to workload + ) + ) + ) + } + + entries + } catch (e: Exception) { + e.printStackTrace() + throw e + } finally { + reader.close() + } + } + + /** + * The entries in the trace. + */ + private val entries: List> + + init { + val fragments = parseFragments() + entries = parseMeta(fragments) + } + + /** + * Read the entries in the trace. + */ + public fun read(): List> = entries +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt new file mode 100644 index 00000000..36cd0a7d --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace + +import mu.KotlinLogging +import org.apache.avro.generic.GenericData +import org.apache.parquet.avro.AvroParquetReader +import org.apache.parquet.filter2.compat.FilterCompat +import org.apache.parquet.filter2.predicate.FilterApi +import org.apache.parquet.filter2.predicate.Statistics +import org.apache.parquet.filter2.predicate.UserDefinedPredicate +import org.apache.parquet.io.api.Binary +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.trace.util.parquet.LocalInputFile +import java.io.File +import java.io.Serializable +import java.util.SortedSet +import java.util.TreeSet +import java.util.UUID +import java.util.concurrent.ArrayBlockingQueue +import kotlin.concurrent.thread + +/** + * A [TraceReader] for the internal VM workload trace format that streams workloads on the fly. + * + * @param traceFile The directory of the traces. + * @param selectedVms The list of VMs to read from the trace. + */ +public class StreamingParquetTraceReader(traceFile: File, selectedVms: List = emptyList()) : TraceReader { + private val logger = KotlinLogging.logger {} + + /** + * The internal iterator to use for this reader. + */ + private val iterator: Iterator> + + /** + * The intermediate buffer to store the read records in. + */ + private val queue = ArrayBlockingQueue>(1024) + + /** + * An optional filter for filtering the selected VMs + */ + private val filter = + if (selectedVms.isEmpty()) + null + else + FilterCompat.get( + FilterApi.userDefined( + FilterApi.binaryColumn("id"), + SelectedVmFilter( + TreeSet(selectedVms) + ) + ) + ) + + /** + * A poisonous fragment. + */ + private val poison = Pair("\u0000", SimTraceWorkload.Fragment(0L, 0, 0.0, 0)) + + /** + * The thread to read the records in. + */ + private val readerThread = thread(start = true, name = "sc20-reader") { + val reader = AvroParquetReader + .builder(LocalInputFile(File(traceFile, "trace.parquet"))) + .disableCompatibility() + .withFilter(filter) + .build() + + try { + while (true) { + val record = reader.read() + + if (record == null) { + queue.put(poison) + break + } + + val id = record["id"].toString() + val time = record["time"] as Long + val duration = record["duration"] as Long + val cores = record["cores"] as Int + val cpuUsage = record["cpuUsage"] as Double + + val fragment = SimTraceWorkload.Fragment( + time, + duration, + cpuUsage, + cores + ) + + queue.put(id to fragment) + } + } catch (e: InterruptedException) { + // Do not rethrow this + } finally { + reader.close() + } + } + + /** + * Fill the buffers with the VMs + */ + private fun pull(buffers: Map>>) { + if (!hasNext) { + return + } + + val fragments = mutableListOf>() + queue.drainTo(fragments) + + for ((id, fragment) in fragments) { + if (id == poison.first) { + hasNext = false + return + } + buffers[id]?.forEach { it.add(fragment) } + } + } + + /** + * A flag to indicate whether the reader has more entries. + */ + private var hasNext: Boolean = true + + /** + * Initialize the reader. + */ + init { + val takenIds = mutableSetOf() + val entries = mutableMapOf() + val buffers = mutableMapOf>>() + + val metaReader = AvroParquetReader + .builder(LocalInputFile(File(traceFile, "meta.parquet"))) + .disableCompatibility() + .withFilter(filter) + .build() + + while (true) { + val record = metaReader.read() ?: break + val id = record["id"].toString() + entries[id] = record + } + + metaReader.close() + + val selection = selectedVms.ifEmpty { entries.keys } + + // Create the entry iterator + iterator = selection.asSequence() + .mapNotNull { entries[it] } + .mapIndexed { index, record -> + val id = record["id"].toString() + val submissionTime = record["submissionTime"] as Long + val endTime = record["endTime"] as Long + val maxCores = record["maxCores"] as Int + val requiredMemory = record["requiredMemory"] as Long + val uid = UUID.nameUUIDFromBytes("$id-$index".toByteArray()) + + assert(uid !in takenIds) + takenIds += uid + + logger.info { "Processing VM $id" } + + val internalBuffer = mutableListOf() + val externalBuffer = mutableListOf() + buffers.getOrPut(id) { mutableListOf() }.add(externalBuffer) + val fragments = sequence { + var time = submissionTime + repeat@ while (true) { + if (externalBuffer.isEmpty()) { + if (hasNext) { + pull(buffers) + continue + } else { + break + } + } + + internalBuffer.addAll(externalBuffer) + externalBuffer.clear() + + for (fragment in internalBuffer) { + yield(fragment) + + time += fragment.duration + if (time >= endTime) { + break@repeat + } + } + + internalBuffer.clear() + } + + buffers.remove(id) + } + val workload = SimTraceWorkload(fragments) + val meta = mapOf( + "cores" to maxCores, + "required-memory" to requiredMemory, + "workload" to workload + ) + + TraceEntry(uid, id, submissionTime, workload, meta) + } + .sortedBy { it.start } + .toList() + .iterator() + } + + override fun hasNext(): Boolean = iterator.hasNext() + + override fun next(): TraceEntry = iterator.next() + + override fun close() { + readerThread.interrupt() + } + + private class SelectedVmFilter(val selectedVms: SortedSet) : UserDefinedPredicate(), Serializable { + override fun keep(value: Binary?): Boolean = value != null && selectedVms.contains(value.toStringUsingUTF8()) + + override fun canDrop(statistics: Statistics): Boolean { + val min = statistics.min + val max = statistics.max + + return selectedVms.subSet(min.toStringUsingUTF8(), max.toStringUsingUTF8() + "\u0000").isEmpty() + } + + override fun inverseCanDrop(statistics: Statistics): Boolean { + val min = statistics.min + val max = statistics.max + + return selectedVms.subSet(min.toStringUsingUTF8(), max.toStringUsingUTF8() + "\u0000").isNotEmpty() + } + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt new file mode 100644 index 00000000..bae7cb22 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.workload.vm.trace + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.groups.OptionGroup +import com.github.ajalt.clikt.parameters.groups.cooccurring +import com.github.ajalt.clikt.parameters.options.* +import com.github.ajalt.clikt.parameters.types.* +import mu.KotlinLogging +import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.compute.workload.trace.azure.AzureTraceFormat +import org.opendc.compute.workload.trace.bp.BP_RESOURCES_SCHEMA +import org.opendc.compute.workload.trace.bp.BP_RESOURCE_STATES_SCHEMA +import org.opendc.compute.workload.trace.sv.SvTraceFormat +import org.opendc.trace.* +import org.opendc.trace.bitbrains.BitbrainsTraceFormat +import org.opendc.trace.util.parquet.LocalOutputFile +import java.io.File +import java.util.* +import kotlin.math.max +import kotlin.math.min +import kotlin.math.roundToLong + +/** + * A script to convert a trace in text format into a Parquet trace. + */ +public fun main(args: Array): Unit = TraceConverterCli().main(args) + +/** + * Represents the command for converting traces + */ +internal class TraceConverterCli : CliktCommand(name = "trace-converter") { + /** + * The logger instance for the converter. + */ + private val logger = KotlinLogging.logger {} + + /** + * The directory where the trace should be stored. + */ + private val output by option("-O", "--output", help = "path to store the trace") + .file(canBeFile = false, mustExist = false) + .defaultLazy { File("output") } + + /** + * The directory where the input trace is located. + */ + private val input by argument("input", help = "path to the input trace") + .file(canBeFile = false) + + /** + * The input format of the trace. + */ + private val format by option("-f", "--format", help = "input format of trace") + .choice( + "solvinity" to SvTraceFormat(), + "bitbrains" to BitbrainsTraceFormat(), + "azure" to AzureTraceFormat() + ) + .required() + + /** + * The sampling options. + */ + private val samplingOptions by SamplingOptions().cooccurring() + + override fun run() { + val metaParquet = File(output, "meta.parquet") + val traceParquet = File(output, "trace.parquet") + + if (metaParquet.exists()) { + metaParquet.delete() + } + if (traceParquet.exists()) { + traceParquet.delete() + } + + val trace = format.open(input.toURI().toURL()) + + logger.info { "Building resources table" } + + val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) + .withSchema(BP_RESOURCES_SCHEMA) + .withCompressionCodec(CompressionCodecName.ZSTD) + .enablePageWriteChecksum() + .build() + + val selectedVms = metaWriter.use { convertResources(trace, it) } + + logger.info { "Wrote ${selectedVms.size} rows" } + logger.info { "Building resource states table" } + + val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) + .withSchema(BP_RESOURCE_STATES_SCHEMA) + .withCompressionCodec(CompressionCodecName.ZSTD) + .enableDictionaryEncoding() + .enablePageWriteChecksum() + .withBloomFilterEnabled("id", true) + .withBloomFilterNDV("id", selectedVms.size.toLong()) + .build() + + val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } + logger.info { "Wrote $statesCount rows" } + } + + /** + * Convert the resources table for the trace. + */ + private fun convertResources(trace: Trace, writer: ParquetWriter): Set { + val random = samplingOptions?.let { Random(it.seed) } + val samplingFraction = samplingOptions?.fraction ?: 1.0 + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + var hasNextRow = reader.nextRow() + val selectedVms = mutableSetOf() + + while (hasNextRow) { + var id: String + var numCpus = Int.MIN_VALUE + var memCapacity = Double.MIN_VALUE + var memUsage = Double.MIN_VALUE + var startTime = Long.MAX_VALUE + var stopTime = Long.MIN_VALUE + + do { + id = reader.get(RESOURCE_STATE_ID) + + val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + startTime = min(startTime, timestamp) + stopTime = max(stopTime, timestamp) + + numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_NCPUS)) + + memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) + if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { + memUsage = max(memUsage, reader.getDouble(RESOURCE_STATE_MEM_USAGE)) + } + + hasNextRow = reader.nextRow() + } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) + + // Sample only a fraction of the VMs + if (random != null && random.nextDouble() > samplingFraction) { + continue + } + + val builder = GenericRecordBuilder(BP_RESOURCES_SCHEMA) + + builder["id"] = id + builder["submissionTime"] = startTime + builder["endTime"] = stopTime + builder["maxCores"] = numCpus + builder["requiredMemory"] = max(memCapacity, memUsage).roundToLong() + + logger.info { "Selecting VM $id" } + + writer.write(builder.build()) + selectedVms.add(id) + } + + return selectedVms + } + + /** + * Convert the resource states table for the trace. + */ + private fun convertResourceStates(trace: Trace, writer: ParquetWriter, selectedVms: Set): Int { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + var hasNextRow = reader.nextRow() + var count = 0 + + while (hasNextRow) { + var lastTimestamp = Long.MIN_VALUE + + do { + val id = reader.get(RESOURCE_STATE_ID) + + if (id !in selectedVms) { + hasNextRow = reader.nextRow() + continue + } + + val builder = GenericRecordBuilder(BP_RESOURCE_STATES_SCHEMA) + builder["id"] = id + + val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + if (lastTimestamp < 0) { + lastTimestamp = timestamp - 5 * 60 * 1000L + } + + val duration = timestamp - lastTimestamp + val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) + val flops = (cpuUsage * duration / 1000.0).roundToLong() + + builder["time"] = timestamp + builder["duration"] = duration + builder["cores"] = cores + builder["cpuUsage"] = cpuUsage + builder["flops"] = flops + + writer.write(builder.build()) + + lastTimestamp = timestamp + hasNextRow = reader.nextRow() + } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) + + count++ + } + + return count + } + + /** + * Options for sampling the workload trace. + */ + private class SamplingOptions : OptionGroup() { + /** + * The fraction of VMs to sample + */ + val fraction by option("--sampling-fraction", help = "fraction of the workload to sample") + .double() + .restrictTo(0.0001, 1.0) + .required() + + /** + * The seed for sampling the trace. + */ + val seed by option("--sampling-seed", help = "seed for sampling the workload") + .long() + .default(0) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt new file mode 100644 index 00000000..bfa2d051 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace + +import java.util.UUID + +/** + * An entry in a workload trace. + * + * @param uid The unique identifier of the entry. + * @param name The name of the entry. + * @param start The start time of the workload. + * @param workload The workload of the entry. + * @param meta The meta-data associated with the workload. + */ +public data class TraceEntry( + val uid: UUID, + val name: String, + val start: Long, + val workload: T, + val meta: Map +) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt new file mode 100644 index 00000000..b0795d61 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace + +/** + * An interface for reading workloads into memory. + * + * This interface must guarantee that the entries are delivered in order of submission time. + * + * @param T The shape of the workloads supported by this reader. + */ +public interface TraceReader : Iterator>, AutoCloseable diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt new file mode 100644 index 00000000..32843595 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] for the Azure v1 VM traces. + */ +internal class AzureResourceStateTable(private val factory: CsvFactory, path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_CPU_USAGE_PCT + ) + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (_, path) = it.next() + return AzureResourceStateTableReader(factory.createParser(path.toFile())) + } else { + null + } + } + + override fun toString(): String = "AzureCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + return AzureResourceStateTableReader(factory.createParser(path.toFile())) + } + + override fun toString(): String = "AzureResourceStateTable" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt new file mode 100644 index 00000000..ded9d4d6 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.azure + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Azure v1 VM resource state table. + */ +internal class AzureResourceStateTableReader(private val parser: CsvParser) : TableReader { + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "timestamp" -> timestamp = Instant.ofEpochSecond(parser.longValue) + "vm id" -> id = parser.text + "avg cpu" -> cpuUsagePct = parser.doubleValue + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> id + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + throw IllegalArgumentException("Invalid column") + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var timestamp: Instant? = null + private var cpuUsagePct = Double.NaN + + /** + * Reset the state. + */ + private fun reset() { + id = null + timestamp = null + cpuUsagePct = Double.NaN + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("timestamp", CsvSchema.ColumnType.NUMBER) + .addColumn("vm id", CsvSchema.ColumnType.STRING) + .addColumn("CPU min cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU max cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU avg cpu", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .build() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt new file mode 100644 index 00000000..2bed7725 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * The resource [Table] for the Azure v1 VM traces. + */ +internal class AzureResourceTable(private val factory: CsvFactory, private val path: Path) : Table { + override val name: String = TABLE_RESOURCES + + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_NCPUS, + RESOURCE_MEM_CAPACITY + ) + + override fun newReader(): TableReader { + return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("No partition $partition") + } + + override fun toString(): String = "AzureResourceTable" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt new file mode 100644 index 00000000..108ce4ed --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.azure + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Azure v1 VM resources table. + */ +internal class AzureResourceTableReader(private val parser: CsvParser) : TableReader { + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "vm id" -> id = parser.text + "vm created" -> startTime = Instant.ofEpochSecond(parser.longValue) + "vm deleted" -> stopTime = Instant.ofEpochSecond(parser.longValue) + "vm virtual core count" -> cpuCores = parser.intValue + "vm memory" -> memCapacity = parser.doubleValue * 1e6 // GB to KB + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_STOP_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_ID -> id + RESOURCE_START_TIME -> startTime + RESOURCE_STOP_TIME -> stopTime + RESOURCE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_NCPUS -> cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_MEM_CAPACITY -> memCapacity + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var startTime: Instant? = null + private var stopTime: Instant? = null + private var cpuCores = -1 + private var memCapacity = Double.NaN + + /** + * Reset the state. + */ + fun reset() { + id = null + startTime = null + stopTime = null + cpuCores = -1 + memCapacity = Double.NaN + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("vm id", CsvSchema.ColumnType.NUMBER) + .addColumn("subscription id", CsvSchema.ColumnType.STRING) + .addColumn("deployment id", CsvSchema.ColumnType.NUMBER) + .addColumn("timestamp vm created", CsvSchema.ColumnType.NUMBER) + .addColumn("timestamp vm deleted", CsvSchema.ColumnType.NUMBER) + .addColumn("max cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("avg cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("p95 cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("vm category", CsvSchema.ColumnType.NUMBER) + .addColumn("vm virtual core count", CsvSchema.ColumnType.NUMBER) + .addColumn("vm memory", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .build() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt new file mode 100644 index 00000000..93c2210b --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the Azure v1 VM traces. + */ +public class AzureTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = name in tables + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_RESOURCES -> AzureResourceTable(factory, path) + TABLE_RESOURCE_STATES -> AzureResourceStateTable(factory, path) + else -> null + } + } + + override fun toString(): String = "AzureTrace[$path]" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt new file mode 100644 index 00000000..d400e1da --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the Azure v1 format. + */ +public class AzureTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "azure-v1" + + /** + * The [CsvFactory] used to create the parser. + */ + private val factory = CsvFactory() + .enable(CsvParser.Feature.ALLOW_COMMENTS) + .enable(CsvParser.Feature.TRIM_SPACES) + + /** + * Open the trace file. + */ + override fun open(url: URL): AzureTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return AzureTrace(factory, path) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt new file mode 100644 index 00000000..958ed49d --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * The resource state [Table] in the Bitbrains Parquet format. + */ +internal class BPResourceStateTable(private val path: Path) : Table { + override val name: String = TABLE_RESOURCE_STATES + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_DURATION, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_USAGE, + ) + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("trace.parquet")) + return BPResourceStateTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt new file mode 100644 index 00000000..655da2b6 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Duration +import java.time.Instant + +/** + * A [TableReader] implementation for the Bitbrains Parquet format. + */ +internal class BPResourceStateTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_DURATION -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_USAGE -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + RESOURCE_STATE_ID -> record["id"].toString() + RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record["time"] as Long) + RESOURCE_STATE_DURATION -> Duration.ofMillis(record["duration"] as Long) + RESOURCE_STATE_NCPUS -> record["cores"] + RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_STATE_NCPUS -> record["cores"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + val record = checkNotNull(record) { "Reader in invalid state" } + return when (column) { + RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + override fun toString(): String = "BPResourceStateTableReader" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt new file mode 100644 index 00000000..75782486 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * The resource [Table] in the Bitbrains Parquet format. + */ +internal class BPResourceTable(private val path: Path) : Table { + override val name: String = TABLE_RESOURCES + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_NCPUS, + RESOURCE_MEM_CAPACITY + ) + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("meta.parquet")) + return BPResourceTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt new file mode 100644 index 00000000..323ee9d0 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Instant + +/** + * A [TableReader] implementation for the Bitbrains Parquet format. + */ +internal class BPResourceTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_STOP_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + RESOURCE_ID -> record["id"].toString() + RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) + RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) + RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_NCPUS -> record["maxCores"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() * 1000.0 // MB to KB + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + override fun toString(): String = "BPResourceTableReader" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt new file mode 100644 index 00000000..b4e64fab --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.opendc.trace.TABLE_RESOURCES +import org.opendc.trace.TABLE_RESOURCE_STATES +import org.opendc.trace.Table +import org.opendc.trace.Trace +import java.nio.file.Path + +/** + * A [Trace] in the Bitbrains Parquet format. + */ +public class BPTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = + name == TABLE_RESOURCES || name == TABLE_RESOURCE_STATES + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_RESOURCES -> BPResourceTable(path) + TABLE_RESOURCE_STATES -> BPResourceStateTable(path) + else -> null + } + } + + override fun toString(): String = "BPTrace[$path]" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt new file mode 100644 index 00000000..9662476d --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the GWF trace format. + */ +public class BPTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "bitbrains-parquet" + + /** + * Open a Bitbrains Parquet trace. + */ + override fun open(url: URL): BPTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return BPTrace(path) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt new file mode 100644 index 00000000..4f6dbce3 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.bp + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder + +/** + * Schema for the resources table in the trace. + */ +public val BP_RESOURCES_SCHEMA: Schema = SchemaBuilder + .record("meta") + .namespace("org.opendc.trace.capelin") + .fields() + .requiredString("id") + .requiredLong("submissionTime") + .requiredLong("endTime") + .requiredInt("maxCores") + .requiredLong("requiredMemory") + .endRecord() + +/** + * Schema for the resource states table in the trace. + */ +public val BP_RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder + .record("meta") + .namespace("org.opendc.trace.capelin") + .fields() + .requiredString("id") + .requiredLong("time") + .requiredLong("duration") + .requiredInt("cores") + .requiredDouble("cpuUsage") + .requiredLong("flops") + .endRecord() diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt new file mode 100644 index 00000000..3ff69d36 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.sv + +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.bufferedReader +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] in the extended Bitbrains format. + */ +internal class SvResourceStateTable(path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "txt" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_CLUSTER_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT, + RESOURCE_STATE_CPU_DEMAND, + RESOURCE_STATE_CPU_READY_PCT, + RESOURCE_STATE_MEM_CAPACITY, + RESOURCE_STATE_DISK_READ, + RESOURCE_STATE_DISK_WRITE, + ) + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (_, path) = it.next() + val reader = path.bufferedReader() + return SvResourceStateTableReader(reader) + } else { + null + } + } + + override fun toString(): String = "SvCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + val reader = path.bufferedReader() + return SvResourceStateTableReader(reader) + } + + override fun toString(): String = "SvResourceStateTable" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt new file mode 100644 index 00000000..487be950 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.sv + +import org.opendc.trace.* +import java.io.BufferedReader +import java.time.Instant + +/** + * A [TableReader] for the Bitbrains resource state table. + */ +internal class SvResourceStateTableReader(private val reader: BufferedReader) : TableReader { + override fun nextRow(): Boolean { + reset() + + var line: String + var num = 0 + + while (true) { + line = reader.readLine() ?: return false + num++ + + if (line[0] == '#' || line.isBlank()) { + // Ignore empty lines or comments + continue + } + + break + } + + line = line.trim() + + val length = line.length + var col = 0 + var start: Int + var end = 0 + + while (end < length) { + // Trim all whitespace before the field + start = end + while (start < length && line[start].isWhitespace()) { + start++ + } + + end = line.indexOf(' ', start) + + if (end < 0) { + end = length + } + + val field = line.subSequence(start, end) as String + when (col++) { + COL_TIMESTAMP -> timestamp = Instant.ofEpochSecond(field.toLong(10)) + COL_CPU_USAGE -> cpuUsage = field.toDouble() + COL_CPU_DEMAND -> cpuDemand = field.toDouble() + COL_DISK_READ -> diskRead = field.toDouble() + COL_DISK_WRITE -> diskWrite = field.toDouble() + COL_CLUSTER_ID -> cluster = field.trim() + COL_NCPUS -> cpuCores = field.toInt(10) + COL_CPU_READY_PCT -> cpuReadyPct = field.toDouble() + COL_POWERED_ON -> poweredOn = field.toInt(10) == 1 + COL_CPU_CAPACITY -> cpuCapacity = field.toDouble() + COL_ID -> id = field.trim() + COL_MEM_CAPACITY -> memCapacity = field.toDouble() + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_CLUSTER_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_STATE_CPU_USAGE -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + RESOURCE_STATE_CPU_DEMAND -> true + RESOURCE_STATE_CPU_READY_PCT -> true + RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_STATE_DISK_READ -> true + RESOURCE_STATE_DISK_WRITE -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> id + RESOURCE_STATE_CLUSTER_ID -> cluster + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) + RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) + RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) + RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) + RESOURCE_STATE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) + RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) + RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + return when (column) { + RESOURCE_STATE_POWERED_ON -> poweredOn + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_STATE_NCPUS -> cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_STATE_CPU_USAGE -> cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity + RESOURCE_STATE_CPU_DEMAND -> cpuDemand + RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_STATE_DISK_READ -> diskRead + RESOURCE_STATE_DISK_WRITE -> diskWrite + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var cluster: String? = null + private var timestamp: Instant? = null + private var cpuCores = -1 + private var cpuCapacity = Double.NaN + private var cpuUsage = Double.NaN + private var cpuDemand = Double.NaN + private var cpuReadyPct = Double.NaN + private var memCapacity = Double.NaN + private var diskRead = Double.NaN + private var diskWrite = Double.NaN + private var poweredOn: Boolean = false + + /** + * Reset the state of the reader. + */ + private fun reset() { + id = null + timestamp = null + cluster = null + cpuCores = -1 + cpuCapacity = Double.NaN + cpuUsage = Double.NaN + cpuDemand = Double.NaN + cpuReadyPct = Double.NaN + memCapacity = Double.NaN + diskRead = Double.NaN + diskWrite = Double.NaN + poweredOn = false + } + + /** + * Default column indices for the extended Bitbrains format. + */ + private val COL_TIMESTAMP = 0 + private val COL_CPU_USAGE = 1 + private val COL_CPU_DEMAND = 2 + private val COL_DISK_READ = 4 + private val COL_DISK_WRITE = 6 + private val COL_CLUSTER_ID = 10 + private val COL_NCPUS = 12 + private val COL_CPU_READY_PCT = 13 + private val COL_POWERED_ON = 14 + private val COL_CPU_CAPACITY = 18 + private val COL_ID = 19 + private val COL_MEM_CAPACITY = 20 +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt new file mode 100644 index 00000000..932c73ab --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.sv + +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the extended Bitbrains format. + */ +public class SvTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + + return SvResourceStateTable(path) + } + + override fun toString(): String = "SvTrace[$path]" +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt new file mode 100644 index 00000000..ba673b5f --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.trace.sv + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the extended Bitbrains trace format. + */ +public class SvTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "sv" + + /** + * Open the trace file. + */ + override fun open(url: URL): SvTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return SvTrace(path) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReader.kt new file mode 100644 index 00000000..67f9626c --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReader.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.util + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import org.opendc.simulator.compute.kernel.interference.VmInterferenceGroup +import java.io.File +import java.io.InputStream + +/** + * A parser for the JSON performance interference setup files used for the TPDS article on Capelin. + */ +public class PerformanceInterferenceReader { + /** + * The [ObjectMapper] to use. + */ + private val mapper = jacksonObjectMapper() + + init { + mapper.addMixIn(VmInterferenceGroup::class.java, GroupMixin::class.java) + } + + /** + * Read the performance interface model from [file]. + */ + public fun read(file: File): List { + return mapper.readValue(file) + } + + /** + * Read the performance interface model from the input. + */ + public fun read(input: InputStream): List { + return mapper.readValue(input) + } + + private data class GroupMixin( + @JsonProperty("minServerLoad") + val targetLoad: Double, + @JsonProperty("performanceScore") + val score: Double, + @JsonProperty("vms") + val members: Set, + ) +} diff --git a/opendc-compute/opendc-compute-workload/src/test/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReaderTest.kt b/opendc-compute/opendc-compute-workload/src/test/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReaderTest.kt new file mode 100644 index 00000000..c79f0584 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/test/kotlin/org/opendc/compute/workload/util/PerformanceInterferenceReaderTest.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.util + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll + +/** + * Test suite for the [PerformanceInterferenceReader] class. + */ +class PerformanceInterferenceReaderTest { + @Test + fun testSmoke() { + val input = checkNotNull(PerformanceInterferenceReader::class.java.getResourceAsStream("/perf-interference.json")) + val result = PerformanceInterferenceReader().read(input) + + assertAll( + { assertEquals(2, result.size) }, + { assertEquals(setOf("vm_a", "vm_c", "vm_x", "vm_y"), result[0].members) }, + { assertEquals(0.0, result[0].targetLoad, 0.001) }, + { assertEquals(0.8830158730158756, result[0].score, 0.001) } + ) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/test/resources/perf-interference.json b/opendc-compute/opendc-compute-workload/src/test/resources/perf-interference.json new file mode 100644 index 00000000..1be5852b --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/test/resources/perf-interference.json @@ -0,0 +1,22 @@ +[ + { + "vms": [ + "vm_a", + "vm_c", + "vm_x", + "vm_y" + ], + "minServerLoad": 0.0, + "performanceScore": 0.8830158730158756 + }, + { + "vms": [ + "vm_a", + "vm_b", + "vm_c", + "vm_d" + ], + "minServerLoad": 0.0, + "performanceScore": 0.7133055555552751 + } +] diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 7dadd14d..010d18b0 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -31,6 +31,8 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcHarness.opendcHarnessApi) + api(projects.opendcCompute.opendcComputeWorkload) + implementation(projects.opendcTrace.opendcTraceParquet) implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) @@ -38,16 +40,13 @@ dependencies { implementation(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTelemetry.opendcTelemetrySdk) implementation(projects.opendcTelemetry.opendcTelemetryCompute) - implementation(libs.opentelemetry.semconv) - implementation(libs.kotlin.logging) implementation(libs.config) - implementation(libs.progressbar) - implementation(libs.clikt) + implementation(libs.kotlin.logging) + implementation(libs.jackson.databind) implementation(libs.jackson.module.kotlin) - implementation(libs.jackson.dataformat.csv) implementation(kotlin("reflect")) + implementation(libs.opentelemetry.semconv) - implementation(libs.parquet) testImplementation(libs.log4j.slf4j) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 6261ebbf..06db5569 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -24,16 +24,17 @@ package org.opendc.experiments.capelin import com.typesafe.config.ConfigFactory import mu.KotlinLogging +import org.opendc.compute.workload.ComputeWorkloadRunner +import org.opendc.compute.workload.export.parquet.ParquetExportMonitor +import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.trace.RawParquetTraceReader +import org.opendc.compute.workload.util.PerformanceInterferenceReader import org.opendc.experiments.capelin.env.ClusterEnvironmentReader -import org.opendc.experiments.capelin.export.parquet.ParquetExportMonitor import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader -import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader -import org.opendc.experiments.capelin.trace.RawParquetTraceReader -import org.opendc.experiments.capelin.util.ComputeServiceSimulator import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf @@ -43,7 +44,6 @@ import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.collectServiceMetrics import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.io.File -import java.io.FileInputStream import java.time.Duration import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -100,7 +100,12 @@ abstract class Portfolio(name: String) : Experiment(name) { */ override fun doRun(repeat: Int): Unit = runBlockingSimulation { val seeder = Random(repeat.toLong()) - val environment = ClusterEnvironmentReader(File(config.getString("env-path"), "${topology.name}.txt")) + val environment = ClusterEnvironmentReader( + File( + config.getString("env-path"), + "${topology.name}.txt" + ) + ) val workload = workload val workloadNames = if (workload is CompositeWorkload) { @@ -117,7 +122,7 @@ abstract class Portfolio(name: String) : Experiment(name) { val trace = ParquetTraceReader(rawReaders, workload, seeder.nextInt()) val performanceInterferenceModel = if (operationalPhenomena.hasInterference) PerformanceInterferenceReader() - .read(FileInputStream(config.getString("interference-model"))) + .read(File(config.getString("interference-model"))) .let { VmInterferenceModel(it, Random(seeder.nextLong())) } else null @@ -128,7 +133,7 @@ abstract class Portfolio(name: String) : Experiment(name) { grid5000(Duration.ofSeconds((operationalPhenomena.failureFrequency * 60).roundToLong()), seeder.nextInt()) else null - val simulator = ComputeServiceSimulator( + val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt index babd8ada..8d9b24f4 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt @@ -22,6 +22,7 @@ package org.opendc.experiments.capelin.env +import org.opendc.compute.workload.env.MachineDef import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt index a968b043..8d61c530 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt @@ -22,6 +22,7 @@ package org.opendc.experiments.capelin.env +import org.opendc.compute.workload.env.MachineDef import java.io.Closeable /** diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt deleted file mode 100644 index b0c0318f..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/MachineDef.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.env - -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.power.PowerModel -import java.util.* - -/** - * A definition of a machine in a cluster. - */ -public data class MachineDef( - val uid: UUID, - val name: String, - val meta: Map, - val model: MachineModel, - val powerModel: PowerModel -) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt deleted file mode 100644 index a4676f31..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/AvroUtils.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@file:JvmName("AvroUtils") -package org.opendc.experiments.capelin.export.parquet - -import org.apache.avro.LogicalTypes -import org.apache.avro.Schema - -/** - * Schema for UUID type. - */ -internal val UUID_SCHEMA = LogicalTypes.uuid().addToSchema(Schema.create(Schema.Type.STRING)) - -/** - * Schema for timestamp type. - */ -internal val TIMESTAMP_SCHEMA = LogicalTypes.timestampMillis().addToSchema(Schema.create(Schema.Type.LONG)) - -/** - * Helper function to make a [Schema] field optional. - */ -internal fun Schema.optional(): Schema { - return Schema.createUnion(Schema.create(Schema.Type.NULL), this) -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt deleted file mode 100644 index e3d15c3b..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetDataWriter.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.export.parquet - -import mu.KotlinLogging -import org.apache.avro.Schema -import org.apache.avro.generic.GenericData -import org.apache.avro.generic.GenericRecordBuilder -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetFileWriter -import org.apache.parquet.hadoop.ParquetWriter -import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.trace.util.parquet.LocalOutputFile -import java.io.File -import java.util.concurrent.ArrayBlockingQueue -import java.util.concurrent.BlockingQueue -import kotlin.concurrent.thread - -/** - * A writer that writes data in Parquet format. - */ -abstract class ParquetDataWriter( - path: File, - private val schema: Schema, - bufferSize: Int = 4096 -) : AutoCloseable { - /** - * The logging instance to use. - */ - private val logger = KotlinLogging.logger {} - - /** - * The queue of commands to process. - */ - private val queue: BlockingQueue = ArrayBlockingQueue(bufferSize) - - /** - * An exception to be propagated to the actual writer. - */ - private var exception: Throwable? = null - - /** - * The thread that is responsible for writing the Parquet records. - */ - private val writerThread = thread(start = false, name = this.toString()) { - val writer = let { - val builder = AvroParquetWriter.builder(LocalOutputFile(path)) - .withSchema(schema) - .withCompressionCodec(CompressionCodecName.ZSTD) - .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) - buildWriter(builder) - } - - val queue = queue - val buf = mutableListOf() - var shouldStop = false - - try { - while (!shouldStop) { - try { - process(writer, queue.take()) - } catch (e: InterruptedException) { - shouldStop = true - } - - if (queue.drainTo(buf) > 0) { - for (data in buf) { - process(writer, data) - } - buf.clear() - } - } - } catch (e: Throwable) { - logger.error(e) { "Failure in Parquet data writer" } - exception = e - } finally { - writer.close() - } - } - - /** - * Build the [ParquetWriter] used to write the Parquet files. - */ - protected open fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { - return builder.build() - } - - /** - * Convert the specified [data] into a Parquet record. - */ - protected abstract fun convert(builder: GenericRecordBuilder, data: T) - - /** - * Write the specified metrics to the database. - */ - fun write(data: T) { - val exception = exception - if (exception != null) { - throw IllegalStateException("Writer thread failed", exception) - } - - queue.put(data) - } - - /** - * Signal the writer to stop. - */ - override fun close() { - writerThread.interrupt() - writerThread.join() - } - - init { - writerThread.start() - } - - /** - * Process the specified [data] to be written to the Parquet file. - */ - private fun process(writer: ParquetWriter, data: T) { - val builder = GenericRecordBuilder(schema) - convert(builder, data) - writer.write(builder.build()) - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt deleted file mode 100644 index b057e932..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetExportMonitor.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.export.parquet - -import org.opendc.telemetry.compute.ComputeMonitor -import org.opendc.telemetry.compute.table.HostData -import org.opendc.telemetry.compute.table.ServerData -import org.opendc.telemetry.compute.table.ServiceData -import java.io.File - -/** - * A [ComputeMonitor] that logs the events to a Parquet file. - */ -class ParquetExportMonitor(base: File, partition: String, bufferSize: Int) : ComputeMonitor, AutoCloseable { - private val serverWriter = ParquetServerDataWriter( - File(base, "server/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - private val hostWriter = ParquetHostDataWriter( - File(base, "host/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - private val serviceWriter = ParquetServiceDataWriter( - File(base, "service/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - override fun record(data: ServerData) { - serverWriter.write(data) - } - - override fun record(data: HostData) { - hostWriter.write(data) - } - - override fun record(data: ServiceData) { - serviceWriter.write(data) - } - - override fun close() { - hostWriter.close() - serviceWriter.close() - serverWriter.close() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt deleted file mode 100644 index 58388cb1..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetHostDataWriter.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.export.parquet - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData -import org.apache.avro.generic.GenericRecordBuilder -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetWriter -import org.opendc.telemetry.compute.table.HostData -import java.io.File - -/** - * A Parquet event writer for [HostData]s. - */ -public class ParquetHostDataWriter(path: File, bufferSize: Int) : - ParquetDataWriter(path, SCHEMA, bufferSize) { - - override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { - return builder - .withDictionaryEncoding("host_id", true) - .build() - } - - override fun convert(builder: GenericRecordBuilder, data: HostData) { - builder["timestamp"] = data.timestamp.toEpochMilli() - - builder["host_id"] = data.host.id - - builder["uptime"] = data.uptime - builder["downtime"] = data.downtime - val bootTime = data.bootTime - if (bootTime != null) { - builder["boot_time"] = bootTime.toEpochMilli() - } - - builder["cpu_count"] = data.host.cpuCount - builder["cpu_limit"] = data.cpuLimit - builder["cpu_time_active"] = data.cpuActiveTime - builder["cpu_time_idle"] = data.cpuIdleTime - builder["cpu_time_steal"] = data.cpuStealTime - builder["cpu_time_lost"] = data.cpuLostTime - - builder["mem_limit"] = data.host.memCapacity - - builder["power_total"] = data.powerTotal - - builder["guests_terminated"] = data.guestsTerminated - builder["guests_running"] = data.guestsRunning - builder["guests_error"] = data.guestsError - builder["guests_invalid"] = data.guestsInvalid - } - - override fun toString(): String = "host-writer" - - companion object { - private val SCHEMA: Schema = SchemaBuilder - .record("host") - .namespace("org.opendc.telemetry.compute") - .fields() - .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() - .name("host_id").type(UUID_SCHEMA).noDefault() - .requiredLong("uptime") - .requiredLong("downtime") - .name("boot_time").type(TIMESTAMP_SCHEMA.optional()).noDefault() - .requiredInt("cpu_count") - .requiredDouble("cpu_limit") - .requiredLong("cpu_time_active") - .requiredLong("cpu_time_idle") - .requiredLong("cpu_time_steal") - .requiredLong("cpu_time_lost") - .requiredLong("mem_limit") - .requiredDouble("power_total") - .requiredInt("guests_terminated") - .requiredInt("guests_running") - .requiredInt("guests_error") - .requiredInt("guests_invalid") - .endRecord() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt deleted file mode 100644 index 43b5f469..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServerDataWriter.kt +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.export.parquet - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericData -import org.apache.avro.generic.GenericRecordBuilder -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetWriter -import org.opendc.telemetry.compute.table.ServerData -import java.io.File -import java.util.* - -/** - * A Parquet event writer for [ServerData]s. - */ -public class ParquetServerDataWriter(path: File, bufferSize: Int) : - ParquetDataWriter(path, SCHEMA, bufferSize) { - - override fun buildWriter(builder: AvroParquetWriter.Builder): ParquetWriter { - return builder - .withDictionaryEncoding("server_id", true) - .withDictionaryEncoding("host_id", true) - .build() - } - - override fun convert(builder: GenericRecordBuilder, data: ServerData) { - builder["timestamp"] = data.timestamp.toEpochMilli() - - builder["server_id"] = data.server.id - builder["host_id"] = data.host?.id - - builder["uptime"] = data.uptime - builder["downtime"] = data.downtime - val bootTime = data.bootTime - if (bootTime != null) { - builder["boot_time"] = bootTime.toEpochMilli() - } - builder["scheduling_latency"] = data.schedulingLatency - - builder["cpu_count"] = data.server.cpuCount - builder["cpu_limit"] = data.cpuLimit - builder["cpu_time_active"] = data.cpuActiveTime - builder["cpu_time_idle"] = data.cpuIdleTime - builder["cpu_time_steal"] = data.cpuStealTime - builder["cpu_time_lost"] = data.cpuLostTime - - builder["mem_limit"] = data.server.memCapacity - } - - override fun toString(): String = "server-writer" - - companion object { - private val SCHEMA: Schema = SchemaBuilder - .record("server") - .namespace("org.opendc.telemetry.compute") - .fields() - .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() - .name("server_id").type(UUID_SCHEMA).noDefault() - .name("host_id").type(UUID_SCHEMA.optional()).noDefault() - .requiredLong("uptime") - .requiredLong("downtime") - .name("boot_time").type(TIMESTAMP_SCHEMA.optional()).noDefault() - .requiredLong("scheduling_latency") - .requiredInt("cpu_count") - .requiredDouble("cpu_limit") - .requiredLong("cpu_time_active") - .requiredLong("cpu_time_idle") - .requiredLong("cpu_time_steal") - .requiredLong("cpu_time_lost") - .requiredLong("mem_limit") - .endRecord() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt deleted file mode 100644 index 2928f445..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/export/parquet/ParquetServiceDataWriter.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.export.parquet - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder -import org.apache.avro.generic.GenericRecordBuilder -import org.opendc.telemetry.compute.table.ServiceData -import java.io.File - -/** - * A Parquet event writer for [ServiceData]s. - */ -public class ParquetServiceDataWriter(path: File, bufferSize: Int) : - ParquetDataWriter(path, SCHEMA, bufferSize) { - - override fun convert(builder: GenericRecordBuilder, data: ServiceData) { - builder["timestamp"] = data.timestamp.toEpochMilli() - builder["hosts_up"] = data.hostsUp - builder["hosts_down"] = data.hostsDown - builder["servers_pending"] = data.serversPending - builder["servers_active"] = data.serversActive - builder["attempts_success"] = data.attemptsSuccess - builder["attempts_failure"] = data.attemptsFailure - builder["attempts_error"] = data.attemptsError - } - - override fun toString(): String = "service-writer" - - companion object { - private val SCHEMA: Schema = SchemaBuilder - .record("service") - .namespace("org.opendc.telemetry.compute") - .fields() - .name("timestamp").type(TIMESTAMP_SCHEMA).noDefault() - .requiredInt("hosts_up") - .requiredInt("hosts_down") - .requiredInt("servers_pending") - .requiredInt("servers_active") - .requiredInt("attempts_success") - .requiredInt("attempts_failure") - .requiredInt("attempts_error") - .endRecord() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt index 0bf4ada6..498636ba 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 AtLarge Research + * Copyright (c) 2021 AtLarge Research * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,6 +22,9 @@ package org.opendc.experiments.capelin.trace +import org.opendc.compute.workload.trace.RawParquetTraceReader +import org.opendc.compute.workload.trace.TraceEntry +import org.opendc.compute.workload.trace.TraceReader import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.Workload import org.opendc.simulator.compute.workload.SimWorkload @@ -51,7 +54,10 @@ public class ParquetTraceReader( this.zip(listOf(workload)) } } - .flatMap { sampleWorkload(it.first, workload, it.second, seed).sortedBy(TraceEntry::start) } + .flatMap { + sampleWorkload(it.first, workload, it.second, seed) + .sortedBy(TraceEntry::start) + } .iterator() override fun hasNext(): Boolean = iterator.hasNext() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt deleted file mode 100644 index 9549af42..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReader.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import org.opendc.simulator.compute.kernel.interference.VmInterferenceGroup -import java.io.InputStream - -/** - * A parser for the JSON performance interference setup files used for the TPDS article on Capelin. - */ -class PerformanceInterferenceReader { - /** - * The [ObjectMapper] to use. - */ - private val mapper = jacksonObjectMapper() - - init { - mapper.addMixIn(VmInterferenceGroup::class.java, GroupMixin::class.java) - } - - /** - * Read the performance interface model from the input. - */ - fun read(input: InputStream): List { - return input.use { mapper.readValue(input) } - } - - private data class GroupMixin( - @JsonProperty("minServerLoad") - val targetLoad: Double, - @JsonProperty("performanceScore") - val score: Double, - @JsonProperty("vms") - val members: Set, - ) -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt deleted file mode 100644 index ca937328..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/RawParquetTraceReader.kt +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import org.opendc.experiments.capelin.trace.bp.BPTraceFormat -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.trace.* -import java.io.File -import java.util.UUID - -/** - * A [TraceReader] for the internal VM workload trace format. - * - * @param path The directory of the traces. - */ -class RawParquetTraceReader(private val path: File) { - /** - * The [Trace] that represents this trace. - */ - private val trace = BPTraceFormat().open(path.toURI().toURL()) - - /** - * Read the fragments into memory. - */ - private fun parseFragments(): Map> { - val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - - val fragments = mutableMapOf>() - - return try { - while (reader.nextRow()) { - val id = reader.get(RESOURCE_STATE_ID) - val time = reader.get(RESOURCE_STATE_TIMESTAMP) - val duration = reader.get(RESOURCE_STATE_DURATION) - val cores = reader.getInt(RESOURCE_STATE_NCPUS) - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - - val fragment = SimTraceWorkload.Fragment( - time.toEpochMilli(), - duration.toMillis(), - cpuUsage, - cores - ) - - fragments.getOrPut(id) { mutableListOf() }.add(fragment) - } - - fragments - } finally { - reader.close() - } - } - - /** - * Read the metadata into a workload. - */ - private fun parseMeta(fragments: Map>): List> { - val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() - - var counter = 0 - val entries = mutableListOf>() - - return try { - while (reader.nextRow()) { - - val id = reader.get(RESOURCE_ID) - if (!fragments.containsKey(id)) { - continue - } - - val submissionTime = reader.get(RESOURCE_START_TIME) - val endTime = reader.get(RESOURCE_STOP_TIME) - val maxCores = reader.getInt(RESOURCE_NCPUS) - val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB - val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) - - val vmFragments = fragments.getValue(id).asSequence() - val totalLoad = vmFragments.sumOf { it.usage } * 5 * 60 // avg MHz * duration = MFLOPs - val workload = SimTraceWorkload(vmFragments) - entries.add( - TraceEntry( - uid, id, submissionTime.toEpochMilli(), workload, - mapOf( - "submit-time" to submissionTime.toEpochMilli(), - "end-time" to endTime.toEpochMilli(), - "total-load" to totalLoad, - "cores" to maxCores, - "required-memory" to requiredMemory.toLong(), - "workload" to workload - ) - ) - ) - } - - entries - } catch (e: Exception) { - e.printStackTrace() - throw e - } finally { - reader.close() - } - } - - /** - * The entries in the trace. - */ - private val entries: List> - - init { - val fragments = parseFragments() - entries = parseMeta(fragments) - } - - /** - * Read the entries in the trace. - */ - fun read(): List> = entries -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt deleted file mode 100644 index ed82217d..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/StreamingParquetTraceReader.kt +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import mu.KotlinLogging -import org.apache.avro.generic.GenericData -import org.apache.parquet.avro.AvroParquetReader -import org.apache.parquet.filter2.compat.FilterCompat -import org.apache.parquet.filter2.predicate.FilterApi -import org.apache.parquet.filter2.predicate.Statistics -import org.apache.parquet.filter2.predicate.UserDefinedPredicate -import org.apache.parquet.io.api.Binary -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.trace.util.parquet.LocalInputFile -import java.io.File -import java.io.Serializable -import java.util.SortedSet -import java.util.TreeSet -import java.util.UUID -import java.util.concurrent.ArrayBlockingQueue -import kotlin.concurrent.thread - -/** - * A [TraceReader] for the internal VM workload trace format that streams workloads on the fly. - * - * @param traceFile The directory of the traces. - * @param selectedVms The list of VMs to read from the trace. - */ -class StreamingParquetTraceReader(traceFile: File, selectedVms: List = emptyList()) : TraceReader { - private val logger = KotlinLogging.logger {} - - /** - * The internal iterator to use for this reader. - */ - private val iterator: Iterator> - - /** - * The intermediate buffer to store the read records in. - */ - private val queue = ArrayBlockingQueue>(1024) - - /** - * An optional filter for filtering the selected VMs - */ - private val filter = - if (selectedVms.isEmpty()) - null - else - FilterCompat.get( - FilterApi.userDefined( - FilterApi.binaryColumn("id"), - SelectedVmFilter( - TreeSet(selectedVms) - ) - ) - ) - - /** - * A poisonous fragment. - */ - private val poison = Pair("\u0000", SimTraceWorkload.Fragment(0L, 0, 0.0, 0)) - - /** - * The thread to read the records in. - */ - private val readerThread = thread(start = true, name = "sc20-reader") { - val reader = AvroParquetReader - .builder(LocalInputFile(File(traceFile, "trace.parquet"))) - .disableCompatibility() - .withFilter(filter) - .build() - - try { - while (true) { - val record = reader.read() - - if (record == null) { - queue.put(poison) - break - } - - val id = record["id"].toString() - val time = record["time"] as Long - val duration = record["duration"] as Long - val cores = record["cores"] as Int - val cpuUsage = record["cpuUsage"] as Double - - val fragment = SimTraceWorkload.Fragment( - time, - duration, - cpuUsage, - cores - ) - - queue.put(id to fragment) - } - } catch (e: InterruptedException) { - // Do not rethrow this - } finally { - reader.close() - } - } - - /** - * Fill the buffers with the VMs - */ - private fun pull(buffers: Map>>) { - if (!hasNext) { - return - } - - val fragments = mutableListOf>() - queue.drainTo(fragments) - - for ((id, fragment) in fragments) { - if (id == poison.first) { - hasNext = false - return - } - buffers[id]?.forEach { it.add(fragment) } - } - } - - /** - * A flag to indicate whether the reader has more entries. - */ - private var hasNext: Boolean = true - - /** - * Initialize the reader. - */ - init { - val takenIds = mutableSetOf() - val entries = mutableMapOf() - val buffers = mutableMapOf>>() - - val metaReader = AvroParquetReader - .builder(LocalInputFile(File(traceFile, "meta.parquet"))) - .disableCompatibility() - .withFilter(filter) - .build() - - while (true) { - val record = metaReader.read() ?: break - val id = record["id"].toString() - entries[id] = record - } - - metaReader.close() - - val selection = selectedVms.ifEmpty { entries.keys } - - // Create the entry iterator - iterator = selection.asSequence() - .mapNotNull { entries[it] } - .mapIndexed { index, record -> - val id = record["id"].toString() - val submissionTime = record["submissionTime"] as Long - val endTime = record["endTime"] as Long - val maxCores = record["maxCores"] as Int - val requiredMemory = record["requiredMemory"] as Long - val uid = UUID.nameUUIDFromBytes("$id-$index".toByteArray()) - - assert(uid !in takenIds) - takenIds += uid - - logger.info { "Processing VM $id" } - - val internalBuffer = mutableListOf() - val externalBuffer = mutableListOf() - buffers.getOrPut(id) { mutableListOf() }.add(externalBuffer) - val fragments = sequence { - var time = submissionTime - repeat@ while (true) { - if (externalBuffer.isEmpty()) { - if (hasNext) { - pull(buffers) - continue - } else { - break - } - } - - internalBuffer.addAll(externalBuffer) - externalBuffer.clear() - - for (fragment in internalBuffer) { - yield(fragment) - - time += fragment.duration - if (time >= endTime) { - break@repeat - } - } - - internalBuffer.clear() - } - - buffers.remove(id) - } - val workload = SimTraceWorkload(fragments) - val meta = mapOf( - "cores" to maxCores, - "required-memory" to requiredMemory, - "workload" to workload - ) - - TraceEntry(uid, id, submissionTime, workload, meta) - } - .sortedBy { it.start } - .toList() - .iterator() - } - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() { - readerThread.interrupt() - } - - private class SelectedVmFilter(val selectedVms: SortedSet) : UserDefinedPredicate(), Serializable { - override fun keep(value: Binary?): Boolean = value != null && selectedVms.contains(value.toStringUsingUTF8()) - - override fun canDrop(statistics: Statistics): Boolean { - val min = statistics.min - val max = statistics.max - - return selectedVms.subSet(min.toStringUsingUTF8(), max.toStringUsingUTF8() + "\u0000").isEmpty() - } - - override fun inverseCanDrop(statistics: Statistics): Boolean { - val min = statistics.min - val max = statistics.max - - return selectedVms.subSet(min.toStringUsingUTF8(), max.toStringUsingUTF8() + "\u0000").isNotEmpty() - } - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt deleted file mode 100644 index 1f3878eb..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceConverter.kt +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2020 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import com.github.ajalt.clikt.core.CliktCommand -import com.github.ajalt.clikt.parameters.arguments.argument -import com.github.ajalt.clikt.parameters.groups.OptionGroup -import com.github.ajalt.clikt.parameters.groups.cooccurring -import com.github.ajalt.clikt.parameters.options.* -import com.github.ajalt.clikt.parameters.types.* -import mu.KotlinLogging -import org.apache.avro.generic.GenericData -import org.apache.avro.generic.GenericRecordBuilder -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetWriter -import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.experiments.capelin.trace.azure.AzureTraceFormat -import org.opendc.experiments.capelin.trace.bp.BP_RESOURCES_SCHEMA -import org.opendc.experiments.capelin.trace.bp.BP_RESOURCE_STATES_SCHEMA -import org.opendc.experiments.capelin.trace.sv.SvTraceFormat -import org.opendc.trace.* -import org.opendc.trace.bitbrains.BitbrainsTraceFormat -import org.opendc.trace.util.parquet.LocalOutputFile -import java.io.File -import java.util.* -import kotlin.math.max -import kotlin.math.min -import kotlin.math.roundToLong - -/** - * A script to convert a trace in text format into a Parquet trace. - */ -fun main(args: Array): Unit = TraceConverterCli().main(args) - -/** - * Represents the command for converting traces - */ -class TraceConverterCli : CliktCommand(name = "trace-converter") { - /** - * The logger instance for the converter. - */ - private val logger = KotlinLogging.logger {} - - /** - * The directory where the trace should be stored. - */ - private val output by option("-O", "--output", help = "path to store the trace") - .file(canBeFile = false, mustExist = false) - .defaultLazy { File("output") } - - /** - * The directory where the input trace is located. - */ - private val input by argument("input", help = "path to the input trace") - .file(canBeFile = false) - - /** - * The input format of the trace. - */ - private val format by option("-f", "--format", help = "input format of trace") - .choice( - "solvinity" to SvTraceFormat(), - "bitbrains" to BitbrainsTraceFormat(), - "azure" to AzureTraceFormat() - ) - .required() - - /** - * The sampling options. - */ - private val samplingOptions by SamplingOptions().cooccurring() - - override fun run() { - val metaParquet = File(output, "meta.parquet") - val traceParquet = File(output, "trace.parquet") - - if (metaParquet.exists()) { - metaParquet.delete() - } - if (traceParquet.exists()) { - traceParquet.delete() - } - - val trace = format.open(input.toURI().toURL()) - - logger.info { "Building resources table" } - - val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) - .withSchema(BP_RESOURCES_SCHEMA) - .withCompressionCodec(CompressionCodecName.ZSTD) - .enablePageWriteChecksum() - .build() - - val selectedVms = metaWriter.use { convertResources(trace, it) } - - logger.info { "Wrote ${selectedVms.size} rows" } - logger.info { "Building resource states table" } - - val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) - .withSchema(BP_RESOURCE_STATES_SCHEMA) - .withCompressionCodec(CompressionCodecName.ZSTD) - .enableDictionaryEncoding() - .enablePageWriteChecksum() - .withBloomFilterEnabled("id", true) - .withBloomFilterNDV("id", selectedVms.size.toLong()) - .build() - - val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } - logger.info { "Wrote $statesCount rows" } - } - - /** - * Convert the resources table for the trace. - */ - private fun convertResources(trace: Trace, writer: ParquetWriter): Set { - val random = samplingOptions?.let { Random(it.seed) } - val samplingFraction = samplingOptions?.fraction ?: 1.0 - val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - - var hasNextRow = reader.nextRow() - val selectedVms = mutableSetOf() - - while (hasNextRow) { - var id: String - var numCpus = Int.MIN_VALUE - var memCapacity = Double.MIN_VALUE - var memUsage = Double.MIN_VALUE - var startTime = Long.MAX_VALUE - var stopTime = Long.MIN_VALUE - - do { - id = reader.get(RESOURCE_STATE_ID) - - val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() - startTime = min(startTime, timestamp) - stopTime = max(stopTime, timestamp) - - numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_NCPUS)) - - memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) - if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { - memUsage = max(memUsage, reader.getDouble(RESOURCE_STATE_MEM_USAGE)) - } - - hasNextRow = reader.nextRow() - } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) - - // Sample only a fraction of the VMs - if (random != null && random.nextDouble() > samplingFraction) { - continue - } - - val builder = GenericRecordBuilder(BP_RESOURCES_SCHEMA) - - builder["id"] = id - builder["submissionTime"] = startTime - builder["endTime"] = stopTime - builder["maxCores"] = numCpus - builder["requiredMemory"] = max(memCapacity, memUsage).roundToLong() - - logger.info { "Selecting VM $id" } - - writer.write(builder.build()) - selectedVms.add(id) - } - - return selectedVms - } - - /** - * Convert the resource states table for the trace. - */ - private fun convertResourceStates(trace: Trace, writer: ParquetWriter, selectedVms: Set): Int { - val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - - var hasNextRow = reader.nextRow() - var count = 0 - - while (hasNextRow) { - var lastTimestamp = Long.MIN_VALUE - - do { - val id = reader.get(RESOURCE_STATE_ID) - - if (id !in selectedVms) { - hasNextRow = reader.nextRow() - continue - } - - val builder = GenericRecordBuilder(BP_RESOURCE_STATES_SCHEMA) - builder["id"] = id - - val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() - if (lastTimestamp < 0) { - lastTimestamp = timestamp - 5 * 60 * 1000L - } - - val duration = timestamp - lastTimestamp - val cores = reader.getInt(RESOURCE_STATE_NCPUS) - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - val flops = (cpuUsage * duration / 1000.0).roundToLong() - - builder["time"] = timestamp - builder["duration"] = duration - builder["cores"] = cores - builder["cpuUsage"] = cpuUsage - builder["flops"] = flops - - writer.write(builder.build()) - - lastTimestamp = timestamp - hasNextRow = reader.nextRow() - } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) - - count++ - } - - return count - } - - /** - * Options for sampling the workload trace. - */ - private class SamplingOptions : OptionGroup() { - /** - * The fraction of VMs to sample - */ - val fraction by option("--sampling-fraction", help = "fraction of the workload to sample") - .double() - .restrictTo(0.0001, 1.0) - .required() - - /** - * The seed for sampling the trace. - */ - val seed by option("--sampling-seed", help = "seed for sampling the workload") - .long() - .default(0) - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt deleted file mode 100644 index 303a6a8c..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceEntry.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2019 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import java.util.UUID - -/** - * An entry in a workload trace. - * - * @param uid The unique identifier of the entry. - * @param name The name of the entry. - * @param start The start time of the workload. - * @param workload The workload of the entry. - * @param meta The meta-data associated with the workload. - */ -public data class TraceEntry( - val uid: UUID, - val name: String, - val start: Long, - val workload: T, - val meta: Map -) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt deleted file mode 100644 index 08304edc..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/TraceReader.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -/** - * An interface for reading workloads into memory. - * - * This interface must guarantee that the entries are delivered in order of submission time. - * - * @param T The shape of the workloads supported by this reader. - */ -public interface TraceReader : Iterator>, AutoCloseable diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt deleted file mode 100644 index b55bd577..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/VmPlacementReader.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import java.io.InputStream - -/** - * A parser for the JSON VM placement data files used for the TPDS article on Capelin. - */ -class VmPlacementReader { - /** - * The [ObjectMapper] to parse the placement. - */ - private val mapper = jacksonObjectMapper() - - /** - * Read the VM placements from the input. - */ - fun read(input: InputStream): Map { - return mapper.readValue>(input) - .mapKeys { "vm__workload__${it.key}.txt" } - .mapValues { it.value.split("/")[1] } // Clusters have format XX0 / X00 - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt index cb32ce88..b42951df 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 AtLarge Research + * Copyright (c) 2021 AtLarge Research * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.opendc.experiments.capelin.trace import mu.KotlinLogging +import org.opendc.compute.workload.trace.TraceEntry import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.SamplingStrategy import org.opendc.experiments.capelin.model.Workload diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt deleted file mode 100644 index f98f4b2c..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTable.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] for the Azure v1 VM traces. - */ -internal class AzureResourceStateTable(private val factory: CsvFactory, path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_CPU_USAGE_PCT - ) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - } - - this.delegate = delegate - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { - return if (it.hasNext()) { - val (_, path) = it.next() - return AzureResourceStateTableReader(factory.createParser(path.toFile())) - } else { - null - } - } - - override fun toString(): String = "AzureCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - return AzureResourceStateTableReader(factory.createParser(path.toFile())) - } - - override fun toString(): String = "AzureResourceStateTable" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt deleted file mode 100644 index f80c0e82..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceStateTableReader.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.azure - -import com.fasterxml.jackson.core.JsonToken -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import org.opendc.trace.* -import java.time.Instant - -/** - * A [TableReader] for the Azure v1 VM resource state table. - */ -internal class AzureResourceStateTableReader(private val parser: CsvParser) : TableReader { - init { - parser.schema = schema - } - - override fun nextRow(): Boolean { - reset() - - if (!nextStart()) { - return false - } - - while (true) { - val token = parser.nextValue() - - if (token == null || token == JsonToken.END_OBJECT) { - break - } - - when (parser.currentName) { - "timestamp" -> timestamp = Instant.ofEpochSecond(parser.longValue) - "vm id" -> id = parser.text - "avg cpu" -> cpuUsagePct = parser.doubleValue - } - } - - return true - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_STATE_ID -> id - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - throw IllegalArgumentException("Invalid column") - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - parser.close() - } - - /** - * Advance the parser until the next object start. - */ - private fun nextStart(): Boolean { - var token = parser.nextValue() - - while (token != null && token != JsonToken.START_OBJECT) { - token = parser.nextValue() - } - - return token != null - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var timestamp: Instant? = null - private var cpuUsagePct = Double.NaN - - /** - * Reset the state. - */ - private fun reset() { - id = null - timestamp = null - cpuUsagePct = Double.NaN - } - - companion object { - /** - * The [CsvSchema] that is used to parse the trace. - */ - private val schema = CsvSchema.builder() - .addColumn("timestamp", CsvSchema.ColumnType.NUMBER) - .addColumn("vm id", CsvSchema.ColumnType.STRING) - .addColumn("CPU min cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU max cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU avg cpu", CsvSchema.ColumnType.NUMBER) - .setAllowComments(true) - .build() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt deleted file mode 100644 index c9d4f7eb..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTable.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * The resource [Table] for the Azure v1 VM traces. - */ -internal class AzureResourceTable(private val factory: CsvFactory, private val path: Path) : Table { - override val name: String = TABLE_RESOURCES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_START_TIME, - RESOURCE_STOP_TIME, - RESOURCE_NCPUS, - RESOURCE_MEM_CAPACITY - ) - - override fun newReader(): TableReader { - return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("No partition $partition") - } - - override fun toString(): String = "AzureResourceTable" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt deleted file mode 100644 index b712b854..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureResourceTableReader.kt +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.azure - -import com.fasterxml.jackson.core.JsonToken -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import org.apache.parquet.example.Paper.schema -import org.opendc.trace.* -import java.time.Instant - -/** - * A [TableReader] for the Azure v1 VM resources table. - */ -internal class AzureResourceTableReader(private val parser: CsvParser) : TableReader { - init { - parser.schema = schema - } - - override fun nextRow(): Boolean { - reset() - - if (!nextStart()) { - return false - } - - while (true) { - val token = parser.nextValue() - - if (token == null || token == JsonToken.END_OBJECT) { - break - } - - when (parser.currentName) { - "vm id" -> id = parser.text - "vm created" -> startTime = Instant.ofEpochSecond(parser.longValue) - "vm deleted" -> stopTime = Instant.ofEpochSecond(parser.longValue) - "vm virtual core count" -> cpuCores = parser.intValue - "vm memory" -> memCapacity = parser.doubleValue * 1e6 // GB to KB - } - } - - return true - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> id - RESOURCE_START_TIME -> startTime - RESOURCE_STOP_TIME -> stopTime - RESOURCE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_NCPUS -> cpuCores - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_MEM_CAPACITY -> memCapacity - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - parser.close() - } - - /** - * Advance the parser until the next object start. - */ - private fun nextStart(): Boolean { - var token = parser.nextValue() - - while (token != null && token != JsonToken.START_OBJECT) { - token = parser.nextValue() - } - - return token != null - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var startTime: Instant? = null - private var stopTime: Instant? = null - private var cpuCores = -1 - private var memCapacity = Double.NaN - - /** - * Reset the state. - */ - fun reset() { - id = null - startTime = null - stopTime = null - cpuCores = -1 - memCapacity = Double.NaN - } - - companion object { - /** - * The [CsvSchema] that is used to parse the trace. - */ - private val schema = CsvSchema.builder() - .addColumn("vm id", CsvSchema.ColumnType.NUMBER) - .addColumn("subscription id", CsvSchema.ColumnType.STRING) - .addColumn("deployment id", CsvSchema.ColumnType.NUMBER) - .addColumn("timestamp vm created", CsvSchema.ColumnType.NUMBER) - .addColumn("timestamp vm deleted", CsvSchema.ColumnType.NUMBER) - .addColumn("max cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("avg cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("p95 cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("vm category", CsvSchema.ColumnType.NUMBER) - .addColumn("vm virtual core count", CsvSchema.ColumnType.NUMBER) - .addColumn("vm memory", CsvSchema.ColumnType.NUMBER) - .setAllowComments(true) - .build() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt deleted file mode 100644 index 24c60bab..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTrace.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the Azure v1 VM traces. - */ -class AzureTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = name in tables - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> AzureResourceTable(factory, path) - TABLE_RESOURCE_STATES -> AzureResourceStateTable(factory, path) - else -> null - } - } - - override fun toString(): String = "AzureTrace[$path]" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt deleted file mode 100644 index 744e43a0..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/azure/AzureTraceFormat.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import com.fasterxml.jackson.dataformat.csv.CsvParser -import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists - -/** - * A format implementation for the Azure v1 format. - */ -class AzureTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "azure-v1" - - /** - * The [CsvFactory] used to create the parser. - */ - private val factory = CsvFactory() - .enable(CsvParser.Feature.ALLOW_COMMENTS) - .enable(CsvParser.Feature.TRIM_SPACES) - - /** - * Open the trace file. - */ - override fun open(url: URL): AzureTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return AzureTrace(factory, path) - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt deleted file mode 100644 index f051bf88..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTable.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * The resource state [Table] in the Bitbrains Parquet format. - */ -internal class BPResourceStateTable(private val path: Path) : Table { - override val name: String = TABLE_RESOURCE_STATES - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_DURATION, - RESOURCE_STATE_NCPUS, - RESOURCE_STATE_CPU_USAGE, - ) - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("trace.parquet")) - return BPResourceStateTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt deleted file mode 100644 index 0e7ee555..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceStateTableReader.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.time.Duration -import java.time.Instant - -/** - * A [TableReader] implementation for the Bitbrains Parquet format. - */ -internal class BPResourceStateTableReader(private val reader: LocalParquetReader) : TableReader { - /** - * The current record. - */ - private var record: GenericRecord? = null - - override fun nextRow(): Boolean { - record = reader.read() - return record != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_DURATION -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_USAGE -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val record = checkNotNull(record) { "Reader in invalid state" } - - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - RESOURCE_STATE_ID -> record["id"].toString() - RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record["time"] as Long) - RESOURCE_STATE_DURATION -> Duration.ofMillis(record["duration"] as Long) - RESOURCE_STATE_NCPUS -> record["cores"] - RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - RESOURCE_STATE_NCPUS -> record["cores"] as Int - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - reader.close() - } - - override fun toString(): String = "BPResourceStateTableReader" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt deleted file mode 100644 index 5b0f013f..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTable.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * The resource [Table] in the Bitbrains Parquet format. - */ -internal class BPResourceTable(private val path: Path) : Table { - override val name: String = TABLE_RESOURCES - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_START_TIME, - RESOURCE_STOP_TIME, - RESOURCE_NCPUS, - RESOURCE_MEM_CAPACITY - ) - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("meta.parquet")) - return BPResourceTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt deleted file mode 100644 index 4416aae8..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPResourceTableReader.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.time.Instant - -/** - * A [TableReader] implementation for the Bitbrains Parquet format. - */ -internal class BPResourceTableReader(private val reader: LocalParquetReader) : TableReader { - /** - * The current record. - */ - private var record: GenericRecord? = null - - override fun nextRow(): Boolean { - record = reader.read() - return record != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val record = checkNotNull(record) { "Reader in invalid state" } - - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - RESOURCE_ID -> record["id"].toString() - RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) - RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) - RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - RESOURCE_NCPUS -> record["maxCores"] as Int - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() * 1000.0 // MB to KB - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - reader.close() - } - - override fun toString(): String = "BPResourceTableReader" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt deleted file mode 100644 index 486587b1..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTrace.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.opendc.trace.TABLE_RESOURCES -import org.opendc.trace.TABLE_RESOURCE_STATES -import org.opendc.trace.Table -import org.opendc.trace.Trace -import java.nio.file.Path - -/** - * A [Trace] in the Bitbrains Parquet format. - */ -public class BPTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = - name == TABLE_RESOURCES || name == TABLE_RESOURCE_STATES - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> BPResourceTable(path) - TABLE_RESOURCE_STATES -> BPResourceStateTable(path) - else -> null - } - } - - override fun toString(): String = "BPTrace[$path]" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt deleted file mode 100644 index 49d5b4c5..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/BPTraceFormat.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists - -/** - * A format implementation for the GWF trace format. - */ -public class BPTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "bitbrains-parquet" - - /** - * Open a Bitbrains Parquet trace. - */ - override fun open(url: URL): BPTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return BPTrace(path) - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt deleted file mode 100644 index 7dd8161d..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/bp/Schemas.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.bp - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder - -/** - * Schema for the resources table in the trace. - */ -val BP_RESOURCES_SCHEMA: Schema = SchemaBuilder - .record("meta") - .namespace("org.opendc.trace.capelin") - .fields() - .requiredString("id") - .requiredLong("submissionTime") - .requiredLong("endTime") - .requiredInt("maxCores") - .requiredLong("requiredMemory") - .endRecord() - -/** - * Schema for the resource states table in the trace. - */ -val BP_RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder - .record("meta") - .namespace("org.opendc.trace.capelin") - .fields() - .requiredString("id") - .requiredLong("time") - .requiredLong("duration") - .requiredInt("cores") - .requiredDouble("cpuUsage") - .requiredLong("flops") - .endRecord() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt deleted file mode 100644 index 67140fe9..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTable.kt +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.sv - -import org.opendc.trace.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.bufferedReader -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] in the extended Bitbrains format. - */ -internal class SvResourceStateTable(path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "txt" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_CLUSTER_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_NCPUS, - RESOURCE_STATE_CPU_CAPACITY, - RESOURCE_STATE_CPU_USAGE, - RESOURCE_STATE_CPU_USAGE_PCT, - RESOURCE_STATE_CPU_DEMAND, - RESOURCE_STATE_CPU_READY_PCT, - RESOURCE_STATE_MEM_CAPACITY, - RESOURCE_STATE_DISK_READ, - RESOURCE_STATE_DISK_WRITE, - ) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - } - - this.delegate = delegate - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { - return if (it.hasNext()) { - val (_, path) = it.next() - val reader = path.bufferedReader() - return SvResourceStateTableReader(reader) - } else { - null - } - } - - override fun toString(): String = "SvCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - val reader = path.bufferedReader() - return SvResourceStateTableReader(reader) - } - - override fun toString(): String = "SvResourceStateTable" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt deleted file mode 100644 index 6ea403fe..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvResourceStateTableReader.kt +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.sv - -import org.opendc.trace.* -import java.io.BufferedReader -import java.time.Instant - -/** - * A [TableReader] for the Bitbrains resource state table. - */ -internal class SvResourceStateTableReader(private val reader: BufferedReader) : TableReader { - override fun nextRow(): Boolean { - reset() - - var line: String - var num = 0 - - while (true) { - line = reader.readLine() ?: return false - num++ - - if (line[0] == '#' || line.isBlank()) { - // Ignore empty lines or comments - continue - } - - break - } - - line = line.trim() - - val length = line.length - var col = 0 - var start: Int - var end = 0 - - while (end < length) { - // Trim all whitespace before the field - start = end - while (start < length && line[start].isWhitespace()) { - start++ - } - - end = line.indexOf(' ', start) - - if (end < 0) { - end = length - } - - val field = line.subSequence(start, end) as String - when (col++) { - COL_TIMESTAMP -> timestamp = Instant.ofEpochSecond(field.toLong(10)) - COL_CPU_USAGE -> cpuUsage = field.toDouble() - COL_CPU_DEMAND -> cpuDemand = field.toDouble() - COL_DISK_READ -> diskRead = field.toDouble() - COL_DISK_WRITE -> diskWrite = field.toDouble() - COL_CLUSTER_ID -> cluster = field.trim() - COL_NCPUS -> cpuCores = field.toInt(10) - COL_CPU_READY_PCT -> cpuReadyPct = field.toDouble() - COL_POWERED_ON -> poweredOn = field.toInt(10) == 1 - COL_CPU_CAPACITY -> cpuCapacity = field.toDouble() - COL_ID -> id = field.trim() - COL_MEM_CAPACITY -> memCapacity = field.toDouble() - } - } - - return true - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_CLUSTER_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_CAPACITY -> true - RESOURCE_STATE_CPU_USAGE -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_STATE_CPU_DEMAND -> true - RESOURCE_STATE_CPU_READY_PCT -> true - RESOURCE_STATE_MEM_CAPACITY -> true - RESOURCE_STATE_DISK_READ -> true - RESOURCE_STATE_DISK_WRITE -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_STATE_ID -> id - RESOURCE_STATE_CLUSTER_ID -> cluster - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) - RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) - RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) - RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) - RESOURCE_STATE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) - RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) - RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - return when (column) { - RESOURCE_STATE_POWERED_ON -> poweredOn - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_STATE_NCPUS -> cpuCores - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity - RESOURCE_STATE_CPU_USAGE -> cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity - RESOURCE_STATE_CPU_DEMAND -> cpuDemand - RESOURCE_STATE_MEM_CAPACITY -> memCapacity - RESOURCE_STATE_DISK_READ -> diskRead - RESOURCE_STATE_DISK_WRITE -> diskWrite - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - reader.close() - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var cluster: String? = null - private var timestamp: Instant? = null - private var cpuCores = -1 - private var cpuCapacity = Double.NaN - private var cpuUsage = Double.NaN - private var cpuDemand = Double.NaN - private var cpuReadyPct = Double.NaN - private var memCapacity = Double.NaN - private var diskRead = Double.NaN - private var diskWrite = Double.NaN - private var poweredOn: Boolean = false - - /** - * Reset the state of the reader. - */ - private fun reset() { - id = null - timestamp = null - cluster = null - cpuCores = -1 - cpuCapacity = Double.NaN - cpuUsage = Double.NaN - cpuDemand = Double.NaN - cpuReadyPct = Double.NaN - memCapacity = Double.NaN - diskRead = Double.NaN - diskWrite = Double.NaN - poweredOn = false - } - - /** - * Default column indices for the extended Bitbrains format. - */ - private val COL_TIMESTAMP = 0 - private val COL_CPU_USAGE = 1 - private val COL_CPU_DEMAND = 2 - private val COL_DISK_READ = 4 - private val COL_DISK_WRITE = 6 - private val COL_CLUSTER_ID = 10 - private val COL_NCPUS = 12 - private val COL_CPU_READY_PCT = 13 - private val COL_POWERED_ON = 14 - private val COL_CPU_CAPACITY = 18 - private val COL_ID = 19 - private val COL_MEM_CAPACITY = 20 -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt deleted file mode 100644 index dbd63de5..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTrace.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.sv - -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the extended Bitbrains format. - */ -public class SvTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name - - override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null - } - - return SvResourceStateTable(path) - } - - override fun toString(): String = "SvTrace[$path]" -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt deleted file mode 100644 index 0cce8559..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/sv/SvTraceFormat.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace.sv - -import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists - -/** - * A format implementation for the extended Bitbrains trace format. - */ -public class SvTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "sv" - - /** - * Open the trace file. - */ - override fun open(url: URL): SvTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return SvTrace(path) - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt deleted file mode 100644 index 065a8c93..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeServiceSimulator.kt +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.util - -import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.metrics.export.MetricProducer -import io.opentelemetry.sdk.resources.Resource -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.yield -import org.opendc.compute.service.ComputeService -import org.opendc.compute.service.scheduler.ComputeScheduler -import org.opendc.compute.simulator.SimHost -import org.opendc.experiments.capelin.env.MachineDef -import org.opendc.experiments.capelin.trace.TraceReader -import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider -import org.opendc.simulator.compute.kernel.SimHypervisorProvider -import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel -import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.telemetry.compute.* -import org.opendc.telemetry.sdk.toOtelClock -import java.time.Clock -import kotlin.coroutines.CoroutineContext -import kotlin.math.max - -/** - * Helper class to manage a [ComputeService] simulation. - */ -class ComputeServiceSimulator( - private val context: CoroutineContext, - private val clock: Clock, - scheduler: ComputeScheduler, - machines: List, - private val failureModel: FailureModel? = null, - interferenceModel: VmInterferenceModel? = null, - hypervisorProvider: SimHypervisorProvider = SimFairShareHypervisorProvider() -) : AutoCloseable { - /** - * The [ComputeService] that has been configured by the manager. - */ - val service: ComputeService - - /** - * The [MetricProducer] that are used by the [ComputeService] and the simulated hosts. - */ - val producers: List - get() = _metricProducers - private val _metricProducers = mutableListOf() - - /** - * The [SimResourceInterpreter] to simulate the hosts. - */ - private val interpreter = SimResourceInterpreter(context, clock) - - /** - * The hosts that belong to this class. - */ - private val hosts = mutableSetOf() - - init { - val (service, serviceMeterProvider) = createService(scheduler) - this._metricProducers.add(serviceMeterProvider) - this.service = service - - for (def in machines) { - val (host, hostMeterProvider) = createHost(def, hypervisorProvider, interferenceModel) - this._metricProducers.add(hostMeterProvider) - hosts.add(host) - this.service.addHost(host) - } - } - - /** - * Run a simulation of the [ComputeService] by replaying the workload trace given by [reader]. - */ - suspend fun run(reader: TraceReader) { - val injector = failureModel?.createInjector(context, clock, service) - val client = service.newClient() - - // Create new image for the virtual machine - val image = client.newImage("vm-image") - - try { - coroutineScope { - // Start the fault injector - injector?.start() - - var offset = Long.MIN_VALUE - - while (reader.hasNext()) { - val entry = reader.next() - - if (offset < 0) { - offset = entry.start - clock.millis() - } - - // Make sure the trace entries are ordered by submission time - assert(entry.start - offset >= 0) { "Invalid trace order" } - delay(max(0, (entry.start - offset) - clock.millis())) - - launch { - val workloadOffset = -offset + 300001 - val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) - - val server = client.newServer( - entry.name, - image, - client.newFlavor( - entry.name, - entry.meta["cores"] as Int, - entry.meta["required-memory"] as Long - ), - meta = entry.meta + mapOf("workload" to workload) - ) - - // Wait for the server reach its end time - val endTime = entry.meta["end-time"] as Long - delay(endTime + workloadOffset - clock.millis() + 1) - - // Delete the server after reaching the end-time of the virtual machine - server.delete() - } - } - } - - yield() - } finally { - injector?.close() - reader.close() - client.close() - } - } - - override fun close() { - service.close() - - for (host in hosts) { - host.close() - } - - hosts.clear() - } - - /** - * Construct a [ComputeService] instance. - */ - private fun createService(scheduler: ComputeScheduler): Pair { - val resource = Resource.builder() - .put(ResourceAttributes.SERVICE_NAME, "opendc-compute") - .build() - - val meterProvider = SdkMeterProvider.builder() - .setClock(clock.toOtelClock()) - .setResource(resource) - .build() - - val service = ComputeService(context, clock, meterProvider, scheduler) - return service to meterProvider - } - - /** - * Construct a [SimHost] instance for the specified [MachineDef]. - */ - private fun createHost( - def: MachineDef, - hypervisorProvider: SimHypervisorProvider, - interferenceModel: VmInterferenceModel? = null - ): Pair { - val resource = Resource.builder() - .put(HOST_ID, def.uid.toString()) - .put(HOST_NAME, def.name) - .put(HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) - .put(HOST_NCPUS, def.model.cpus.size) - .put(HOST_MEM_CAPACITY, def.model.memory.sumOf { it.size }) - .build() - - val meterProvider = SdkMeterProvider.builder() - .setClock(clock.toOtelClock()) - .setResource(resource) - .build() - - val host = SimHost( - def.uid, - def.name, - def.model, - def.meta, - context, - interpreter, - meterProvider, - hypervisorProvider, - powerDriver = SimplePowerDriver(def.powerModel), - interferenceDomain = interferenceModel?.newDomain() - ) - - return host to meterProvider - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt deleted file mode 100644 index 83393896..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModel.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.util - -import org.opendc.compute.service.ComputeService -import org.opendc.compute.simulator.failure.HostFaultInjector -import java.time.Clock -import kotlin.coroutines.CoroutineContext - -/** - * Factory interface for constructing [HostFaultInjector] for modeling failures of compute service hosts. - */ -interface FailureModel { - /** - * Construct a [HostFaultInjector] for the specified [service]. - */ - fun createInjector(context: CoroutineContext, clock: Clock, service: ComputeService): HostFaultInjector -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt deleted file mode 100644 index 89b4a31c..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/FailureModels.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@file:JvmName("FailureModels") -package org.opendc.experiments.capelin - -import org.apache.commons.math3.distribution.LogNormalDistribution -import org.apache.commons.math3.random.Well19937c -import org.opendc.compute.service.ComputeService -import org.opendc.compute.simulator.SimHost -import org.opendc.compute.simulator.failure.HostFaultInjector -import org.opendc.compute.simulator.failure.StartStopHostFault -import org.opendc.compute.simulator.failure.StochasticVictimSelector -import org.opendc.experiments.capelin.util.FailureModel -import java.time.Clock -import java.time.Duration -import kotlin.coroutines.CoroutineContext -import kotlin.math.ln -import kotlin.random.Random - -/** - * Obtain a [FailureModel] based on the GRID'5000 failure trace. - * - * This fault injector uses parameters from the GRID'5000 failure trace as described in - * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. - */ -fun grid5000(failureInterval: Duration, seed: Int): FailureModel { - return object : FailureModel { - override fun createInjector( - context: CoroutineContext, - clock: Clock, - service: ComputeService - ): HostFaultInjector { - val rng = Well19937c(seed) - val hosts = service.hosts.map { it as SimHost }.toSet() - - // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 - // GRID'5000 - return HostFaultInjector( - context, - clock, - hosts, - iat = LogNormalDistribution(rng, ln(failureInterval.toHours().toDouble()), 1.03), - selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), - fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) - ) - } - - override fun toString(): String = "Grid5000FailureModel" - } -} - -/** - * Obtain the [HostFaultInjector] to use for the experiments. - * - * This fault injector uses parameters from the GRID'5000 failure trace as described in - * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. - */ -fun createFaultInjector( - context: CoroutineContext, - clock: Clock, - hosts: Set, - seed: Int, - failureInterval: Double -): HostFaultInjector { - val rng = Well19937c(seed) - - // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 - // GRID'5000 - return HostFaultInjector( - context, - clock, - hosts, - iat = LogNormalDistribution(rng, ln(failureInterval), 1.03), - selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), - fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) - ) -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/VmPlacementReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/VmPlacementReader.kt new file mode 100644 index 00000000..67de2777 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/VmPlacementReader.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.util + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import java.io.InputStream + +/** + * A parser for the JSON VM placement data files used for the TPDS article on Capelin. + */ +class VmPlacementReader { + /** + * The [ObjectMapper] to parse the placement. + */ + private val mapper = jacksonObjectMapper() + + /** + * Read the VM placements from the input. + */ + fun read(input: InputStream): Map { + return mapper.readValue>(input) + .mapKeys { "vm__workload__${it.key}.txt" } + .mapValues { it.value.split("/")[1] } // Clusters have format XX0 / X00 + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/resources/log4j2.xml b/opendc-experiments/opendc-experiments-capelin/src/main/resources/log4j2.xml index d1c01b8e..d46b50c3 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/resources/log4j2.xml +++ b/opendc-experiments/opendc-experiments-capelin/src/main/resources/log4j2.xml @@ -36,7 +36,7 @@ - + diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 727530e3..b0f86346 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -31,14 +31,15 @@ import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.filters.RamFilter import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.workload.ComputeWorkloadRunner +import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.trace.RawParquetTraceReader +import org.opendc.compute.workload.trace.TraceReader +import org.opendc.compute.workload.util.PerformanceInterferenceReader import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader -import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader -import org.opendc.experiments.capelin.trace.RawParquetTraceReader -import org.opendc.experiments.capelin.trace.TraceReader -import org.opendc.experiments.capelin.util.ComputeServiceSimulator import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation @@ -85,7 +86,7 @@ class CapelinIntegrationTest { val traceReader = createTestTraceReader() val environmentReader = createTestEnvironmentReader() - val simulator = ComputeServiceSimulator( + val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, @@ -134,7 +135,7 @@ class CapelinIntegrationTest { val traceReader = createTestTraceReader(0.25, seed) val environmentReader = createTestEnvironmentReader("single") - val simulator = ComputeServiceSimulator( + val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, @@ -184,7 +185,7 @@ class CapelinIntegrationTest { .read(perfInterferenceInput) .let { VmInterferenceModel(it, Random(seed.toLong())) } - val simulator = ComputeServiceSimulator( + val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, @@ -229,7 +230,7 @@ class CapelinIntegrationTest { val traceReader = createTestTraceReader(0.25, seed) val environmentReader = createTestEnvironmentReader("single") - val simulator = ComputeServiceSimulator( + val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt deleted file mode 100644 index fbc39b87..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/trace/PerformanceInterferenceReaderTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll - -/** - * Test suite for the [PerformanceInterferenceReader] class. - */ -class PerformanceInterferenceReaderTest { - @Test - fun testSmoke() { - val input = checkNotNull(PerformanceInterferenceReader::class.java.getResourceAsStream("/perf-interference.json")) - val result = PerformanceInterferenceReader().read(input) - - assertAll( - { assertEquals(2, result.size) }, - { assertEquals(setOf("vm_a", "vm_c", "vm_x", "vm_y"), result[0].members) }, - { assertEquals(0.0, result[0].targetLoad, 0.001) }, - { assertEquals(0.8830158730158756, result[0].score, 0.001) } - ) - } -} diff --git a/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/AvroUtils.kt b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/AvroUtils.kt new file mode 100644 index 00000000..086b900b --- /dev/null +++ b/opendc-trace/opendc-trace-parquet/src/main/kotlin/org/opendc/trace/util/parquet/AvroUtils.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("AvroUtils") +package org.opendc.trace.util.parquet + +import org.apache.avro.LogicalTypes +import org.apache.avro.Schema + +/** + * Schema for UUID type. + */ +public val UUID_SCHEMA: Schema = LogicalTypes.uuid().addToSchema(Schema.create(Schema.Type.STRING)) + +/** + * Schema for timestamp type. + */ +public val TIMESTAMP_SCHEMA: Schema = LogicalTypes.timestampMillis().addToSchema(Schema.create(Schema.Type.LONG)) + +/** + * Helper function to make a [Schema] field optional. + */ +public fun Schema.optional(): Schema { + return Schema.createUnion(Schema.create(Schema.Type.NULL), this) +} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 483558e1..497a7281 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -28,14 +28,14 @@ import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.long import kotlinx.coroutines.* import mu.KotlinLogging -import org.opendc.experiments.capelin.* +import org.opendc.compute.workload.ComputeWorkloadRunner +import org.opendc.compute.workload.env.MachineDef +import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.trace.RawParquetTraceReader +import org.opendc.compute.workload.util.PerformanceInterferenceReader import org.opendc.experiments.capelin.env.EnvironmentReader -import org.opendc.experiments.capelin.env.MachineDef import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader -import org.opendc.experiments.capelin.trace.PerformanceInterferenceReader -import org.opendc.experiments.capelin.trace.RawParquetTraceReader -import org.opendc.experiments.capelin.util.ComputeServiceSimulator import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.model.MachineModel @@ -198,7 +198,7 @@ class RunnerCli : CliktCommand(name = "runner") { else null - val simulator = ComputeServiceSimulator( + val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, diff --git a/settings.gradle.kts b/settings.gradle.kts index 933febe0..7bfc8fc6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -25,6 +25,7 @@ include(":opendc-platform") include(":opendc-compute:opendc-compute-api") include(":opendc-compute:opendc-compute-service") include(":opendc-compute:opendc-compute-simulator") +include(":opendc-compute:opendc-compute-workload") include(":opendc-workflow:opendc-workflow-api") include(":opendc-workflow:opendc-workflow-service") include(":opendc-faas:opendc-faas-api") -- cgit v1.2.3 From b0ece0533825f5cd7983752330847071f4e438c4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 15 Sep 2021 23:06:08 +0200 Subject: refactor(capelin): Support flexible topology creation This change adds support for creating flexible topologies by creating a TopologyFactory interface that is responsible for configuring the hosts of a compute service. --- .../compute/workload/ComputeWorkloadRunner.kt | 99 ++++++++--------- .../org/opendc/compute/workload/env/MachineDef.kt | 38 ------- .../opendc/compute/workload/topology/HostSpec.kt | 48 ++++++++ .../opendc/compute/workload/topology/Topology.kt | 33 ++++++ .../compute/workload/topology/TopologyHelpers.kt | 36 ++++++ .../opendc-experiments-capelin/build.gradle.kts | 1 + .../org/opendc/experiments/capelin/Portfolio.kt | 25 ++--- .../capelin/env/ClusterEnvironmentReader.kt | 121 --------------------- .../experiments/capelin/env/EnvironmentReader.kt | 36 ------ .../experiments/capelin/topology/ClusterSpec.kt | 46 ++++++++ .../capelin/topology/ClusterSpecReader.kt | 121 +++++++++++++++++++++ .../capelin/topology/TopologyFactories.kt | 103 ++++++++++++++++++ .../experiments/capelin/CapelinIntegrationTest.kt | 39 +++---- .../src/test/resources/perf-interference.json | 22 ---- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 116 +++++++++++--------- 15 files changed, 528 insertions(+), 356 deletions(-) delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/HostSpec.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/Topology.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpec.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpecReader.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/TopologyFactories.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/resources/perf-interference.json diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt index cc9f2705..29d84a9a 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt @@ -33,12 +33,9 @@ import kotlinx.coroutines.yield import org.opendc.compute.service.ComputeService import org.opendc.compute.service.scheduler.ComputeScheduler import org.opendc.compute.simulator.SimHost -import org.opendc.compute.workload.env.MachineDef +import org.opendc.compute.workload.topology.HostSpec import org.opendc.compute.workload.trace.TraceReader -import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider -import org.opendc.simulator.compute.kernel.SimHypervisorProvider import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel -import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.resources.SimResourceInterpreter @@ -50,15 +47,19 @@ import kotlin.math.max /** * Helper class to simulated VM-based workloads in OpenDC. + * + * @param context [CoroutineContext] to run the simulation in. + * @param clock [Clock] instance tracking simulation time. + * @param scheduler [ComputeScheduler] implementation to use for the service. + * @param failureModel A failure model to use for injecting failures. + * @param interferenceModel The model to use for performance interference. */ public class ComputeWorkloadRunner( private val context: CoroutineContext, private val clock: Clock, scheduler: ComputeScheduler, - machines: List, private val failureModel: FailureModel? = null, - interferenceModel: VmInterferenceModel? = null, - hypervisorProvider: SimHypervisorProvider = SimFairShareHypervisorProvider() + private val interferenceModel: VmInterferenceModel? = null, ) : AutoCloseable { /** * The [ComputeService] that has been configured by the manager. @@ -86,13 +87,6 @@ public class ComputeWorkloadRunner( val (service, serviceMeterProvider) = createService(scheduler) this._metricProducers.add(serviceMeterProvider) this.service = service - - for (def in machines) { - val (host, hostMeterProvider) = createHost(def, hypervisorProvider, interferenceModel) - this._metricProducers.add(hostMeterProvider) - hosts.add(host) - this.service.addHost(host) - } } /** @@ -156,6 +150,46 @@ public class ComputeWorkloadRunner( } } + /** + * Register a host for this simulation. + * + * @param spec The definition of the host. + * @return The [SimHost] that has been constructed by the runner. + */ + public fun registerHost(spec: HostSpec): SimHost { + val resource = Resource.builder() + .put(HOST_ID, spec.uid.toString()) + .put(HOST_NAME, spec.name) + .put(HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(HOST_NCPUS, spec.model.cpus.size) + .put(HOST_MEM_CAPACITY, spec.model.memory.sumOf { it.size }) + .build() + + val meterProvider = SdkMeterProvider.builder() + .setClock(clock.toOtelClock()) + .setResource(resource) + .build() + _metricProducers.add(meterProvider) + + val host = SimHost( + spec.uid, + spec.name, + spec.model, + spec.meta, + context, + interpreter, + meterProvider, + spec.hypervisor, + powerDriver = spec.powerDriver, + interferenceDomain = interferenceModel?.newDomain(), + ) + + hosts.add(host) + service.addHost(host) + + return host + } + override fun close() { service.close() @@ -182,41 +216,4 @@ public class ComputeWorkloadRunner( val service = ComputeService(context, clock, meterProvider, scheduler) return service to meterProvider } - - /** - * Construct a [SimHost] instance for the specified [MachineDef]. - */ - private fun createHost( - def: MachineDef, - hypervisorProvider: SimHypervisorProvider, - interferenceModel: VmInterferenceModel? = null - ): Pair { - val resource = Resource.builder() - .put(HOST_ID, def.uid.toString()) - .put(HOST_NAME, def.name) - .put(HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) - .put(HOST_NCPUS, def.model.cpus.size) - .put(HOST_MEM_CAPACITY, def.model.memory.sumOf { it.size }) - .build() - - val meterProvider = SdkMeterProvider.builder() - .setClock(clock.toOtelClock()) - .setResource(resource) - .build() - - val host = SimHost( - def.uid, - def.name, - def.model, - def.meta, - context, - interpreter, - meterProvider, - hypervisorProvider, - powerDriver = SimplePowerDriver(def.powerModel), - interferenceDomain = interferenceModel?.newDomain() - ) - - return host to meterProvider - } } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt deleted file mode 100644 index c1695696..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/env/MachineDef.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.env - -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.power.PowerModel -import java.util.* - -/** - * A definition of a machine in a cluster. - */ -public data class MachineDef( - val uid: UUID, - val name: String, - val meta: Map, - val model: MachineModel, - val powerModel: PowerModel -) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/HostSpec.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/HostSpec.kt new file mode 100644 index 00000000..f3dc1e9e --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/HostSpec.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.topology + +import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider +import org.opendc.simulator.compute.kernel.SimHypervisorProvider +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.power.PowerDriver +import java.util.* + +/** + * Description of a physical host that will be simulated by OpenDC and host the virtual machines. + * + * @param uid Unique identifier of the host. + * @param name The name of the host. + * @param meta The metadata of the host. + * @param model The physical model of the machine. + * @param powerDriver The [PowerDriver] to model the power consumption of the machine. + * @param hypervisor The hypervisor implementation to use. + */ +public data class HostSpec( + val uid: UUID, + val name: String, + val meta: Map, + val model: MachineModel, + val powerDriver: PowerDriver, + val hypervisor: SimHypervisorProvider = SimFairShareHypervisorProvider() +) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/Topology.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/Topology.kt new file mode 100644 index 00000000..3b8dc918 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/Topology.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.topology + +/** + * Representation of the environment of the compute service, describing the physical details of every host. + */ +public interface Topology { + /** + * Resolve the [Topology] into a list of [HostSpec]s. + */ + public fun resolve(): List +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt new file mode 100644 index 00000000..09159a93 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("TopologyHelpers") +package org.opendc.compute.workload.topology + +import org.opendc.compute.workload.ComputeWorkloadRunner + +/** + * Apply the specified [topology] to the given [ComputeWorkloadRunner]. + */ +public fun ComputeWorkloadRunner.apply(topology: Topology) { + val hosts = topology.resolve() + for (spec in hosts) { + registerHost(spec) + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 010d18b0..4bcbaf61 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { implementation(libs.kotlin.logging) implementation(libs.jackson.databind) implementation(libs.jackson.module.kotlin) + implementation(libs.jackson.dataformat.csv) implementation(kotlin("reflect")) implementation(libs.opentelemetry.semconv) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 06db5569..02811d83 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -27,13 +27,14 @@ import mu.KotlinLogging import org.opendc.compute.workload.ComputeWorkloadRunner import org.opendc.compute.workload.export.parquet.ParquetExportMonitor import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.topology.apply import org.opendc.compute.workload.trace.RawParquetTraceReader import org.opendc.compute.workload.util.PerformanceInterferenceReader -import org.opendc.experiments.capelin.env.ClusterEnvironmentReader import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload +import org.opendc.experiments.capelin.topology.clusterTopology import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.harness.dsl.Experiment @@ -100,12 +101,6 @@ abstract class Portfolio(name: String) : Experiment(name) { */ override fun doRun(repeat: Int): Unit = runBlockingSimulation { val seeder = Random(repeat.toLong()) - val environment = ClusterEnvironmentReader( - File( - config.getString("env-path"), - "${topology.name}.txt" - ) - ) val workload = workload val workloadNames = if (workload is CompositeWorkload) { @@ -133,11 +128,10 @@ abstract class Portfolio(name: String) : Experiment(name) { grid5000(Duration.ofSeconds((operationalPhenomena.failureFrequency * 60).roundToLong()), seeder.nextInt()) else null - val simulator = ComputeWorkloadRunner( + val runner = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, - environment.read(), failureModel, performanceInterferenceModel ) @@ -147,17 +141,22 @@ abstract class Portfolio(name: String) : Experiment(name) { "portfolio_id=$name/scenario_id=$id/run_id=$repeat", 4096 ) - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, runner.producers, ComputeMetricExporter(clock, monitor)) + val topology = clusterTopology(File(config.getString("env-path"), "${topology.name}.txt")) try { - simulator.run(trace) + // Instantiate the desired topology + runner.apply(topology) + + // Run the workload trace + runner.run(trace) } finally { - simulator.close() + runner.close() metricReader.close() monitor.close() } - val monitorResults = collectServiceMetrics(clock.instant(), simulator.producers[0]) + val monitorResults = collectServiceMetrics(clock.instant(), runner.producers[0]) logger.debug { "Scheduler " + "Success=${monitorResults.attemptsSuccess} " + diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt deleted file mode 100644 index 8d9b24f4..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/ClusterEnvironmentReader.kt +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.env - -import org.opendc.compute.workload.env.MachineDef -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.compute.power.LinearPowerModel -import java.io.File -import java.io.FileInputStream -import java.io.InputStream -import java.util.* - -/** - * A [EnvironmentReader] for the internal environment format. - * - * @param input The input stream describing the physical cluster. - */ -class ClusterEnvironmentReader(private val input: InputStream) : EnvironmentReader { - /** - * Construct a [ClusterEnvironmentReader] for the specified [file]. - */ - constructor(file: File) : this(FileInputStream(file)) - - override fun read(): List { - var clusterIdCol = 0 - var speedCol = 0 - var numberOfHostsCol = 0 - var memoryPerHostCol = 0 - var coresPerHostCol = 0 - - var clusterIdx = 0 - var clusterId: String - var speed: Double - var numberOfHosts: Int - var memoryPerHost: Long - var coresPerHost: Int - - val nodes = mutableListOf() - val random = Random(0) - - input.bufferedReader().use { reader -> - reader.lineSequence() - .filter { line -> - // Ignore comments in the file - !line.startsWith("#") && line.isNotBlank() - } - .forEachIndexed { idx, line -> - val values = line.split(";") - - if (idx == 0) { - val header = values.mapIndexed { col, name -> Pair(name.trim(), col) }.toMap() - clusterIdCol = header["ClusterID"]!! - speedCol = header["Speed"]!! - numberOfHostsCol = header["numberOfHosts"]!! - memoryPerHostCol = header["memoryCapacityPerHost"]!! - coresPerHostCol = header["coreCountPerHost"]!! - return@forEachIndexed - } - - clusterIdx++ - clusterId = values[clusterIdCol].trim() - speed = values[speedCol].trim().toDouble() * 1000.0 - numberOfHosts = values[numberOfHostsCol].trim().toInt() - memoryPerHost = values[memoryPerHostCol].trim().toLong() * 1000L - coresPerHost = values[coresPerHostCol].trim().toInt() - - val unknownProcessingNode = ProcessingNode("unknown", "unknown", "unknown", coresPerHost) - val unknownMemoryUnit = MemoryUnit("unknown", "unknown", -1.0, memoryPerHost) - - repeat(numberOfHosts) { - nodes.add( - MachineDef( - UUID(random.nextLong(), random.nextLong()), - "node-$clusterId-$it", - mapOf("cluster" to clusterId), - MachineModel( - List(coresPerHost) { coreId -> - ProcessingUnit(unknownProcessingNode, coreId, speed) - }, - listOf(unknownMemoryUnit) - ), - // For now we assume a simple linear load model with an idle draw of ~200W and a maximum - // power draw of 350W. - // Source: https://stackoverflow.com/questions/6128960 - LinearPowerModel(350.0, idlePower = 200.0) - ) - ) - } - } - } - - return nodes - } - - override fun close() { - input.close() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt deleted file mode 100644 index 8d61c530..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/env/EnvironmentReader.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.env - -import org.opendc.compute.workload.env.MachineDef -import java.io.Closeable - -/** - * An interface for reading descriptions of topology environments into memory. - */ -public interface EnvironmentReader : Closeable { - /** - * Read the environment into a list. - */ - public fun read(): List -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpec.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpec.kt new file mode 100644 index 00000000..b8b65d28 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpec.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.topology + +/** + * Definition of a compute cluster modeled in the simulation. + * + * @param id A unique identifier representing the compute cluster. + * @param name The name of the cluster. + * @param cpuCount The total number of CPUs in the cluster. + * @param cpuSpeed The speed of a CPU in the cluster in MHz. + * @param memCapacity The total memory capacity of the cluster (in MiB). + * @param hostCount The number of hosts in the cluster. + * @param memCapacityPerHost The memory capacity per host in the cluster (MiB). + * @param cpuCountPerHost The number of CPUs per host in the cluster. + */ +public data class ClusterSpec( + val id: String, + val name: String, + val cpuCount: Int, + val cpuSpeed: Double, + val memCapacity: Double, + val hostCount: Int, + val memCapacityPerHost: Double, + val cpuCountPerHost: Int +) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpecReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpecReader.kt new file mode 100644 index 00000000..5a175f2c --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/ClusterSpecReader.kt @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin.topology + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.MappingIterator +import com.fasterxml.jackson.databind.ObjectReader +import com.fasterxml.jackson.dataformat.csv.CsvMapper +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import java.io.File +import java.io.InputStream + +/** + * A helper class for reading a cluster specification file. + */ +class ClusterSpecReader { + /** + * The [CsvMapper] to map the environment file to an object. + */ + private val mapper = CsvMapper() + + /** + * The [ObjectReader] to convert the lines into objects. + */ + private val reader: ObjectReader = mapper.readerFor(Entry::class.java).with(schema) + + /** + * Read the specified [file]. + */ + fun read(file: File): List { + return reader.readValues(file).use { read(it) } + } + + /** + * Read the specified [input]. + */ + fun read(input: InputStream): List { + return reader.readValues(input).use { read(it) } + } + + /** + * Convert the specified [MappingIterator] into a list of [ClusterSpec]s. + */ + private fun read(it: MappingIterator): List { + val result = mutableListOf() + + for (entry in it) { + val def = ClusterSpec( + entry.id, + entry.name, + entry.cpuCount, + entry.cpuSpeed * 1000, // Convert to MHz + entry.memCapacity * 1000, // Convert to MiB + entry.hostCount, + entry.memCapacityPerHost * 1000, + entry.cpuCountPerHost + ) + result.add(def) + } + + return result + } + + private open class Entry( + @JsonProperty("ClusterID") + val id: String, + @JsonProperty("ClusterName") + val name: String, + @JsonProperty("Cores") + val cpuCount: Int, + @JsonProperty("Speed") + val cpuSpeed: Double, + @JsonProperty("Memory") + val memCapacity: Double, + @JsonProperty("numberOfHosts") + val hostCount: Int, + @JsonProperty("memoryCapacityPerHost") + val memCapacityPerHost: Double, + @JsonProperty("coreCountPerHost") + val cpuCountPerHost: Int + ) + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("ClusterID", CsvSchema.ColumnType.STRING) + .addColumn("ClusterName", CsvSchema.ColumnType.STRING) + .addColumn("Cores", CsvSchema.ColumnType.NUMBER) + .addColumn("Speed", CsvSchema.ColumnType.NUMBER) + .addColumn("Memory", CsvSchema.ColumnType.NUMBER) + .addColumn("numberOfHosts", CsvSchema.ColumnType.NUMBER) + .addColumn("memoryCapacityPerHost", CsvSchema.ColumnType.NUMBER) + .addColumn("coreCountPerHost", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .setColumnSeparator(';') + .setUseHeader(true) + .build() + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/TopologyFactories.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/TopologyFactories.kt new file mode 100644 index 00000000..5ab4261a --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/topology/TopologyFactories.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("TopologyFactories") +package org.opendc.experiments.capelin.topology + +import org.opendc.compute.workload.topology.HostSpec +import org.opendc.compute.workload.topology.Topology +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.model.MemoryUnit +import org.opendc.simulator.compute.model.ProcessingNode +import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.compute.power.LinearPowerModel +import org.opendc.simulator.compute.power.PowerModel +import org.opendc.simulator.compute.power.SimplePowerDriver +import java.io.File +import java.io.InputStream +import java.util.* +import kotlin.math.roundToLong + +/** + * A [ClusterSpecReader] that is used to read the cluster definition file. + */ +private val reader = ClusterSpecReader() + +/** + * Construct a [Topology] from the specified [file]. + */ +fun clusterTopology( + file: File, + powerModel: PowerModel = LinearPowerModel(350.0, idlePower = 200.0), + random: Random = Random(0) +): Topology = clusterTopology(reader.read(file), powerModel, random) + +/** + * Construct a [Topology] from the specified [input]. + */ +fun clusterTopology( + input: InputStream, + powerModel: PowerModel = LinearPowerModel(350.0, idlePower = 200.0), + random: Random = Random(0) +): Topology = clusterTopology(reader.read(input), powerModel, random) + +/** + * Construct a [Topology] from the given list of [clusters]. + */ +fun clusterTopology( + clusters: List, + powerModel: PowerModel, + random: Random = Random(0) +): Topology { + return object : Topology { + override fun resolve(): List { + val hosts = mutableListOf() + for (cluster in clusters) { + val cpuSpeed = cluster.cpuSpeed + val memoryPerHost = cluster.memCapacityPerHost.roundToLong() + + val unknownProcessingNode = ProcessingNode("unknown", "unknown", "unknown", cluster.cpuCountPerHost) + val unknownMemoryUnit = MemoryUnit("unknown", "unknown", -1.0, memoryPerHost) + val machineModel = MachineModel( + List(cluster.cpuCountPerHost) { coreId -> ProcessingUnit(unknownProcessingNode, coreId, cpuSpeed) }, + listOf(unknownMemoryUnit) + ) + + repeat(cluster.hostCount) { + val spec = HostSpec( + UUID(random.nextLong(), it.toLong()), + "node-${cluster.name}-$it", + mapOf("cluster" to cluster.id), + machineModel, + SimplePowerDriver(powerModel) + ) + + hosts += spec + } + } + + return hosts + } + + override fun toString(): String = "ClusterSpecTopology" + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index b0f86346..c1386bfe 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -33,12 +33,13 @@ import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.service.scheduler.weights.CoreRamWeigher import org.opendc.compute.workload.ComputeWorkloadRunner import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.topology.Topology +import org.opendc.compute.workload.topology.apply import org.opendc.compute.workload.trace.RawParquetTraceReader import org.opendc.compute.workload.trace.TraceReader import org.opendc.compute.workload.util.PerformanceInterferenceReader -import org.opendc.experiments.capelin.env.ClusterEnvironmentReader -import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload +import org.opendc.experiments.capelin.topology.clusterTopology import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimWorkload @@ -84,18 +85,16 @@ class CapelinIntegrationTest { @Test fun testLarge() = runBlockingSimulation { val traceReader = createTestTraceReader() - val environmentReader = createTestEnvironmentReader() - val simulator = ComputeWorkloadRunner( coroutineContext, clock, - computeScheduler, - environmentReader.read(), + computeScheduler ) - + val topology = createTopology() val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) try { + simulator.apply(topology) simulator.run(traceReader) } finally { simulator.close() @@ -133,18 +132,17 @@ class CapelinIntegrationTest { fun testSmall() = runBlockingSimulation { val seed = 1 val traceReader = createTestTraceReader(0.25, seed) - val environmentReader = createTestEnvironmentReader("single") val simulator = ComputeWorkloadRunner( coroutineContext, clock, - computeScheduler, - environmentReader.read(), + computeScheduler ) - + val topology = createTopology("single") val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) try { + simulator.apply(topology) simulator.run(traceReader) } finally { simulator.close() @@ -177,7 +175,6 @@ class CapelinIntegrationTest { fun testInterference() = runBlockingSimulation { val seed = 1 val traceReader = createTestTraceReader(0.25, seed) - val environmentReader = createTestEnvironmentReader("single") val perfInterferenceInput = checkNotNull(CapelinIntegrationTest::class.java.getResourceAsStream("/bitbrains-perf-interference.json")) val performanceInterferenceModel = @@ -189,13 +186,13 @@ class CapelinIntegrationTest { coroutineContext, clock, computeScheduler, - environmentReader.read(), interferenceModel = performanceInterferenceModel ) - + val topology = createTopology("single") val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) try { + simulator.apply(topology) simulator.run(traceReader) } finally { simulator.close() @@ -227,20 +224,18 @@ class CapelinIntegrationTest { @Test fun testFailures() = runBlockingSimulation { val seed = 1 - val traceReader = createTestTraceReader(0.25, seed) - val environmentReader = createTestEnvironmentReader("single") - val simulator = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler, - environmentReader.read(), grid5000(Duration.ofDays(7), seed) ) - + val topology = createTopology("single") + val traceReader = createTestTraceReader(0.25, seed) val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) try { + simulator.apply(topology) simulator.run(traceReader) } finally { simulator.close() @@ -279,11 +274,11 @@ class CapelinIntegrationTest { } /** - * Obtain the environment reader for the test. + * Obtain the topology factory for the test. */ - private fun createTestEnvironmentReader(name: String = "topology"): EnvironmentReader { + private fun createTopology(name: String = "topology"): Topology { val stream = checkNotNull(object {}.javaClass.getResourceAsStream("/env/$name.txt")) - return ClusterEnvironmentReader(stream) + return stream.use { clusterTopology(stream) } } class TestExperimentReporter : ComputeMonitor { diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/perf-interference.json b/opendc-experiments/opendc-experiments-capelin/src/test/resources/perf-interference.json deleted file mode 100644 index 1be5852b..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/test/resources/perf-interference.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "vms": [ - "vm_a", - "vm_c", - "vm_x", - "vm_y" - ], - "minServerLoad": 0.0, - "performanceScore": 0.8830158730158756 - }, - { - "vms": [ - "vm_a", - "vm_b", - "vm_c", - "vm_d" - ], - "minServerLoad": 0.0, - "performanceScore": 0.7133055555552751 - } -] diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 497a7281..48183d71 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -29,11 +29,12 @@ import com.github.ajalt.clikt.parameters.types.long import kotlinx.coroutines.* import mu.KotlinLogging import org.opendc.compute.workload.ComputeWorkloadRunner -import org.opendc.compute.workload.env.MachineDef import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.topology.HostSpec +import org.opendc.compute.workload.topology.Topology +import org.opendc.compute.workload.topology.apply import org.opendc.compute.workload.trace.RawParquetTraceReader import org.opendc.compute.workload.util.PerformanceInterferenceReader -import org.opendc.experiments.capelin.env.EnvironmentReader import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.util.createComputeScheduler @@ -43,6 +44,7 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.LinearPowerModel +import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.collectServiceMetrics @@ -50,12 +52,12 @@ import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import org.opendc.web.client.ApiClient import org.opendc.web.client.AuthConfiguration import org.opendc.web.client.model.Scenario -import org.opendc.web.client.model.Topology import java.io.File import java.net.URI import java.time.Duration import java.util.* import org.opendc.web.client.model.Portfolio as ClientPortfolio +import org.opendc.web.client.model.Topology as ClientTopology private val logger = KotlinLogging.logger {} @@ -129,7 +131,7 @@ class RunnerCli : CliktCommand(name = "runner") { /** * Run a single scenario. */ - private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, environment: EnvironmentReader): List { + private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, topology: Topology): List { val id = scenario.id logger.info { "Constructing performance interference model" } @@ -156,7 +158,7 @@ class RunnerCli : CliktCommand(name = "runner") { logger.info { "Starting repeat $repeat" } withTimeout(runTimeout * 1000) { val interferenceModel = interferenceGroups?.let { VmInterferenceModel(it, Random(repeat.toLong())) } - runRepeat(scenario, repeat, environment, traceReader, interferenceModel) + runRepeat(scenario, repeat, topology, traceReader, interferenceModel) } } @@ -171,7 +173,7 @@ class RunnerCli : CliktCommand(name = "runner") { private suspend fun runRepeat( scenario: Scenario, repeat: Int, - environment: EnvironmentReader, + topology: Topology, traceReader: RawParquetTraceReader, interferenceModel: VmInterferenceModel? ): WebComputeMonitor.Result { @@ -202,7 +204,6 @@ class RunnerCli : CliktCommand(name = "runner") { coroutineContext, clock, computeScheduler, - environment.read(), failureModel, interferenceModel.takeIf { operational.performanceInterferenceEnabled } ) @@ -210,6 +211,9 @@ class RunnerCli : CliktCommand(name = "runner") { val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor), exportInterval = Duration.ofHours(1)) try { + // Instantiate the topology onto the simulator + simulator.apply(topology) + // Run workload trace simulator.run(trace) } finally { simulator.close() @@ -292,56 +296,62 @@ class RunnerCli : CliktCommand(name = "runner") { } /** - * Convert the specified [topology] into an [EnvironmentReader] understood by Capelin. + * Convert the specified [topology] into an [Topology] understood by OpenDC. */ - private fun convert(topology: Topology): EnvironmentReader { - val nodes = mutableListOf() - val random = Random(0) - - val machines = topology.rooms.asSequence() - .flatMap { room -> - room.tiles.flatMap { tile -> - tile.rack?.machines?.map { machine -> tile.rack to machine } ?: emptyList() - } - } - for ((rack, machine) in machines) { - val clusterId = rack.id - val position = machine.position - - val processors = machine.cpus.flatMap { cpu -> - val cores = cpu.numberOfCores - val speed = cpu.clockRateMhz - // TODO Remove hard coding of vendor - val node = ProcessingNode("Intel", "amd64", cpu.name, cores) - List(cores) { coreId -> - ProcessingUnit(node, coreId, speed) - } - } - val memoryUnits = machine.memory.map { memory -> - MemoryUnit( - "Samsung", - memory.name, - memory.speedMbPerS, - memory.sizeMb.toLong() - ) - } + private fun convert(topology: ClientTopology): Topology { + return object : Topology { + + override fun resolve(): List { + val res = mutableListOf() + val random = Random(0) + + val machines = topology.rooms.asSequence() + .flatMap { room -> + room.tiles.flatMap { tile -> + tile.rack?.machines?.map { machine -> tile.rack to machine } ?: emptyList() + } + } + for ((rack, machine) in machines) { + val clusterId = rack.id + val position = machine.position + + val processors = machine.cpus.flatMap { cpu -> + val cores = cpu.numberOfCores + val speed = cpu.clockRateMhz + // TODO Remove hard coding of vendor + val node = ProcessingNode("Intel", "amd64", cpu.name, cores) + List(cores) { coreId -> + ProcessingUnit(node, coreId, speed) + } + } + val memoryUnits = machine.memory.map { memory -> + MemoryUnit( + "Samsung", + memory.name, + memory.speedMbPerS, + memory.sizeMb.toLong() + ) + } - val energyConsumptionW = machine.cpus.sumOf { it.energyConsumptionW } + val energyConsumptionW = machine.cpus.sumOf { it.energyConsumptionW } + val powerModel = LinearPowerModel(2 * energyConsumptionW, energyConsumptionW * 0.5) + val powerDriver = SimplePowerDriver(powerModel) - nodes.add( - MachineDef( - UUID(random.nextLong(), random.nextLong()), - "node-$clusterId-$position", - mapOf("cluster" to clusterId), - MachineModel(processors, memoryUnits), - LinearPowerModel(2 * energyConsumptionW, energyConsumptionW * 0.5) - ) - ) - } + val spec = HostSpec( + UUID(random.nextLong(), random.nextLong()), + "node-$clusterId-$position", + mapOf("cluster" to clusterId), + MachineModel(processors, memoryUnits), + powerDriver + ) + + res += spec + } + + return res + } - return object : EnvironmentReader { - override fun read(): List = nodes - override fun close() {} + override fun toString(): String = "WebRunnerTopologyFactory" } } } -- cgit v1.2.3 From 3d68aaf17fc8836f7b2bde0d874929cb58c9a8ca Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 13 Sep 2021 14:35:29 +0200 Subject: perf(compute): Add option for optimizing SimHost simulation This change adds an option for optimizing SimHost simulation by combining all the CPUs of a machine into a single large CPU. For most workloads, this does not significantly affect the simulation results, but does improve the simulation time by a lot. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 793db907..ff55c585 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -68,7 +68,8 @@ public class SimHost( scalingGovernor: ScalingGovernor = PerformanceScalingGovernor(), powerDriver: PowerDriver = SimplePowerDriver(ConstantPowerModel(0.0)), private val mapper: SimWorkloadMapper = SimMetaWorkloadMapper(), - interferenceDomain: VmInterferenceDomain? = null + interferenceDomain: VmInterferenceDomain? = null, + private val optimize: Boolean = false ) : Host, AutoCloseable { /** * The [CoroutineScope] of the host bounded by the lifecycle of the host. @@ -98,7 +99,7 @@ public class SimHost( /** * The machine to run on. */ - public val machine: SimBareMetalMachine = SimBareMetalMachine(interpreter, model, powerDriver) + public val machine: SimBareMetalMachine = SimBareMetalMachine(interpreter, model.optimize(), powerDriver) /** * The hypervisor to run multiple workloads. @@ -319,6 +320,25 @@ public class SimHost( val processingUnits = (0 until cpuCount).map { originalCpu.copy(id = it, node = processingNode) } val memoryUnits = listOf(MemoryUnit("Generic", "Generic", 3200.0, memorySize)) + return MachineModel(processingUnits, memoryUnits).optimize() + } + + /** + * Optimize the [MachineModel] for simulation. + */ + private fun MachineModel.optimize(): MachineModel { + if (!optimize) { + return this + } + + val originalCpu = cpus[0] + val freq = cpus.sumOf { it.frequency } + val processingNode = originalCpu.node.copy(coreCount = 1) + val processingUnits = listOf(originalCpu.copy(frequency = freq, node = processingNode)) + + val memorySize = memory.sumOf { it.size } + val memoryUnits = listOf(MemoryUnit("Generic", "Generic", 3200.0, memorySize)) + return MachineModel(processingUnits, memoryUnits) } -- cgit v1.2.3 From 29e52ae17bd567070b52e0bcd3c254ee7491189a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 17 Sep 2021 16:08:41 +0200 Subject: feat(capelin): Support creating CPU-optimized topology This change adds support for creating a topology that is CPU-optimized for simulation. This means that all the CPU resources of a machine are merged into a single large CPU in order to reduce simulation time. --- .../main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt | 4 +++- .../kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt index 29d84a9a..6da0f49a 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt @@ -154,9 +154,10 @@ public class ComputeWorkloadRunner( * Register a host for this simulation. * * @param spec The definition of the host. + * @param optimize Merge the CPU resources of the host into a single CPU resource. * @return The [SimHost] that has been constructed by the runner. */ - public fun registerHost(spec: HostSpec): SimHost { + public fun registerHost(spec: HostSpec, optimize: Boolean = false): SimHost { val resource = Resource.builder() .put(HOST_ID, spec.uid.toString()) .put(HOST_NAME, spec.name) @@ -182,6 +183,7 @@ public class ComputeWorkloadRunner( spec.hypervisor, powerDriver = spec.powerDriver, interferenceDomain = interferenceModel?.newDomain(), + optimize = optimize ) hosts.add(host) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt index 09159a93..74f9a1f8 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/topology/TopologyHelpers.kt @@ -28,9 +28,9 @@ import org.opendc.compute.workload.ComputeWorkloadRunner /** * Apply the specified [topology] to the given [ComputeWorkloadRunner]. */ -public fun ComputeWorkloadRunner.apply(topology: Topology) { +public fun ComputeWorkloadRunner.apply(topology: Topology, optimize: Boolean = false) { val hosts = topology.resolve() for (spec in hosts) { - registerHost(spec) + registerHost(spec, optimize) } } -- cgit v1.2.3 From b14df2a0924774c5aed15cedeb1027abf8ee5361 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 16 Sep 2021 16:52:00 +0200 Subject: refactor(capelin): Make workload sampling model extensible This change updates the workload sampling implementation to be more flexible in the way the workload is constructed. Users can now sample multiple workloads at the same time using multiple samplers and use them as a single workload to simulate. --- .../simulator/failure/StochasticVictimSelector.kt | 2 +- .../org/opendc/compute/workload/ComputeWorkload.kt | 35 +++ .../compute/workload/ComputeWorkloadLoader.kt | 160 +++++++++++++ .../compute/workload/ComputeWorkloadRunner.kt | 34 +-- .../opendc/compute/workload/ComputeWorkloads.kt | 62 +++++ .../org/opendc/compute/workload/FailureModel.kt | 3 +- .../org/opendc/compute/workload/FailureModels.kt | 11 +- .../org/opendc/compute/workload/VirtualMachine.kt | 49 ++++ .../workload/internal/CompositeComputeWorkload.kt | 66 ++++++ .../workload/internal/HpcSampledComputeWorkload.kt | 143 +++++++++++ .../internal/LoadSampledComputeWorkload.kt | 61 +++++ .../workload/internal/TraceComputeWorkload.kt | 37 +++ .../workload/trace/RawParquetTraceReader.kt | 139 ----------- .../workload/trace/StreamingParquetTraceReader.kt | 261 --------------------- .../opendc/compute/workload/trace/TraceEntry.kt | 42 ---- .../opendc/compute/workload/trace/TraceReader.kt | 32 --- .../capelin/CompositeWorkloadPortfolio.kt | 28 +-- .../opendc/experiments/capelin/HorVerPortfolio.kt | 10 +- .../opendc/experiments/capelin/MoreHpcPortfolio.kt | 18 +- .../experiments/capelin/MoreVelocityPortfolio.kt | 10 +- .../capelin/OperationalPhenomenaPortfolio.kt | 10 +- .../org/opendc/experiments/capelin/Portfolio.kt | 26 +- .../opendc/experiments/capelin/ReplayPortfolio.kt | 3 +- .../opendc/experiments/capelin/TestPortfolio.kt | 3 +- .../opendc/experiments/capelin/model/Workload.kt | 23 +- .../capelin/trace/ParquetTraceReader.kt | 68 ------ .../experiments/capelin/trace/WorkloadSampler.kt | 199 ---------------- .../experiments/capelin/CapelinIntegrationTest.kt | 84 ++++--- .../resources/trace/bitbrains-small/meta.parquet | Bin 0 -> 2081 bytes .../resources/trace/bitbrains-small/trace.parquet | Bin 0 -> 1647189 bytes .../src/test/resources/trace/meta.parquet | Bin 2081 -> 0 bytes .../src/test/resources/trace/trace.parquet | Bin 1647189 -> 0 bytes .../opendc-experiments-radice/build.gradle.kts | 47 ---- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 27 +-- 34 files changed, 742 insertions(+), 951 deletions(-) create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet create mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet delete mode 100644 opendc-experiments/opendc-experiments-radice/build.gradle.kts diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt index 87903623..fcd9dd7e 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt @@ -24,8 +24,8 @@ package org.opendc.compute.simulator.failure import org.apache.commons.math3.distribution.RealDistribution import org.opendc.compute.simulator.SimHost +import java.util.* import kotlin.math.roundToInt -import kotlin.random.Random /** * A [VictimSelector] that stochastically selects a set of hosts to be failed. diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt new file mode 100644 index 00000000..78002c2f --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload + +import java.util.* + +/** + * An interface that describes how a workload is resolved. + */ +public interface ComputeWorkload { + /** + * Resolve the workload into a list of [VirtualMachine]s to simulate. + */ + public fun resolve(loader: ComputeWorkloadLoader, random: Random): List +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt new file mode 100644 index 00000000..46176609 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload + +import mu.KotlinLogging +import org.opendc.compute.workload.trace.bp.BPTraceFormat +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.trace.* +import java.io.File +import java.util.* +import java.util.concurrent.ConcurrentHashMap +import kotlin.math.roundToLong + +/** + * A helper class for loading compute workload traces into memory. + * + * @param baseDir The directory containing the traces. + */ +public class ComputeWorkloadLoader(private val baseDir: File) { + /** + * The logger for this instance. + */ + private val logger = KotlinLogging.logger {} + + /** + * The [BPTraceFormat] instance to load the traces + */ + private val format = BPTraceFormat() + + /** + * The cache of workloads. + */ + private val cache = ConcurrentHashMap>() + + /** + * Read the fragments into memory. + */ + private fun parseFragments(trace: Trace): Map> { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + val fragments = mutableMapOf>() + + return try { + while (reader.nextRow()) { + val id = reader.get(RESOURCE_STATE_ID) + val time = reader.get(RESOURCE_STATE_TIMESTAMP) + val duration = reader.get(RESOURCE_STATE_DURATION) + val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) + + val fragment = SimTraceWorkload.Fragment( + time.toEpochMilli(), + duration.toMillis(), + cpuUsage, + cores + ) + + fragments.getOrPut(id) { mutableListOf() }.add(fragment) + } + + fragments + } finally { + reader.close() + } + } + + /** + * Read the metadata into a workload. + */ + private fun parseMeta(trace: Trace, fragments: Map>): List { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() + + var counter = 0 + val entries = mutableListOf() + + return try { + while (reader.nextRow()) { + + val id = reader.get(RESOURCE_ID) + if (!fragments.containsKey(id)) { + continue + } + + val submissionTime = reader.get(RESOURCE_START_TIME) + val endTime = reader.get(RESOURCE_STOP_TIME) + val maxCores = reader.getInt(RESOURCE_NCPUS) + val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB + val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) + + val vmFragments = fragments.getValue(id).asSequence() + val totalLoad = vmFragments.sumOf { (it.usage * it.duration) / 1000.0 } // avg MHz * duration = MFLOPs + + entries.add( + VirtualMachine( + uid, + id, + maxCores, + requiredMemory.roundToLong(), + totalLoad, + submissionTime, + endTime, + vmFragments + ) + ) + } + + // Make sure the virtual machines are ordered by start time + entries.sortBy { it.startTime } + + entries + } catch (e: Exception) { + e.printStackTrace() + throw e + } finally { + reader.close() + } + } + + /** + * Load the trace with the specified [name]. + */ + public fun get(name: String): List { + return cache.computeIfAbsent(name) { + val path = baseDir.resolve(it) + + logger.info { "Loading trace $it at $path" } + + val trace = format.open(path.toURI().toURL()) + val fragments = parseFragments(trace) + parseMeta(trace, fragments) + } + } + + /** + * Clear the workload cache. + */ + public fun reset() { + cache.clear() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt index 6da0f49a..ed45bd8a 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt @@ -34,14 +34,13 @@ import org.opendc.compute.service.ComputeService import org.opendc.compute.service.scheduler.ComputeScheduler import org.opendc.compute.simulator.SimHost import org.opendc.compute.workload.topology.HostSpec -import org.opendc.compute.workload.trace.TraceReader import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.compute.* import org.opendc.telemetry.sdk.toOtelClock import java.time.Clock +import java.util.* import kotlin.coroutines.CoroutineContext import kotlin.math.max @@ -90,10 +89,11 @@ public class ComputeWorkloadRunner( } /** - * Run a simulation of the [ComputeService] by replaying the workload trace given by [reader]. + * Run a simulation of the [ComputeService] by replaying the workload trace given by [trace]. */ - public suspend fun run(reader: TraceReader) { - val injector = failureModel?.createInjector(context, clock, service) + public suspend fun run(trace: List, seed: Long) { + val random = Random(seed) + val injector = failureModel?.createInjector(context, clock, service, random) val client = service.newClient() // Create new image for the virtual machine @@ -106,35 +106,36 @@ public class ComputeWorkloadRunner( var offset = Long.MIN_VALUE - while (reader.hasNext()) { - val entry = reader.next() + for (entry in trace.sortedBy { it.startTime }) { + val now = clock.millis() + val start = entry.startTime.toEpochMilli() if (offset < 0) { - offset = entry.start - clock.millis() + offset = start - now } // Make sure the trace entries are ordered by submission time - assert(entry.start - offset >= 0) { "Invalid trace order" } - delay(max(0, (entry.start - offset) - clock.millis())) + assert(start - offset >= 0) { "Invalid trace order" } + delay(max(0, (start - offset) - now)) launch { val workloadOffset = -offset + 300001 - val workload = SimTraceWorkload((entry.meta["workload"] as SimTraceWorkload).trace, workloadOffset) + val workload = SimTraceWorkload(entry.trace, workloadOffset) val server = client.newServer( entry.name, image, client.newFlavor( entry.name, - entry.meta["cores"] as Int, - entry.meta["required-memory"] as Long + entry.cpuCount, + entry.memCapacity ), - meta = entry.meta + mapOf("workload" to workload) + meta = mapOf("workload" to workload) ) // Wait for the server reach its end time - val endTime = entry.meta["end-time"] as Long - delay(endTime + workloadOffset - clock.millis() + 1) + val endTime = entry.stopTime.toEpochMilli() + delay(endTime + workloadOffset - clock.millis() + 5 * 60 * 1000) // Delete the server after reaching the end-time of the virtual machine server.delete() @@ -145,7 +146,6 @@ public class ComputeWorkloadRunner( yield() } finally { injector?.close() - reader.close() client.close() } } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt new file mode 100644 index 00000000..f58ce587 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("ComputeWorkloads") +package org.opendc.compute.workload + +import org.opendc.compute.workload.internal.CompositeComputeWorkload +import org.opendc.compute.workload.internal.HpcSampledComputeWorkload +import org.opendc.compute.workload.internal.LoadSampledComputeWorkload +import org.opendc.compute.workload.internal.TraceComputeWorkload + +/** + * Construct a workload from a trace. + */ +public fun trace(name: String): ComputeWorkload = TraceComputeWorkload(name) + +/** + * Construct a composite workload with the specified fractions. + */ +public fun composite(vararg pairs: Pair): ComputeWorkload { + return CompositeComputeWorkload(pairs.toMap()) +} + +/** + * Sample a workload by a [fraction] of the total load. + */ +public fun ComputeWorkload.sampleByLoad(fraction: Double): ComputeWorkload { + return LoadSampledComputeWorkload(this, fraction) +} + +/** + * Sample a workload by a [fraction] of the HPC VMs (count) + */ +public fun ComputeWorkload.sampleByHpc(fraction: Double): ComputeWorkload { + return HpcSampledComputeWorkload(this, fraction) +} + +/** + * Sample a workload by a [fraction] of the HPC load + */ +public fun ComputeWorkload.sampleByHpcLoad(fraction: Double): ComputeWorkload { + return HpcSampledComputeWorkload(this, fraction, sampleLoad = true) +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt index 43dd8321..4d9ef15d 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModel.kt @@ -25,6 +25,7 @@ package org.opendc.compute.workload import org.opendc.compute.service.ComputeService import org.opendc.compute.simulator.failure.HostFaultInjector import java.time.Clock +import java.util.* import kotlin.coroutines.CoroutineContext /** @@ -34,5 +35,5 @@ public interface FailureModel { /** * Construct a [HostFaultInjector] for the specified [service]. */ - public fun createInjector(context: CoroutineContext, clock: Clock, service: ComputeService): HostFaultInjector + public fun createInjector(context: CoroutineContext, clock: Clock, service: ComputeService, random: Random): HostFaultInjector } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt index 55c61be1..be7120b9 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/FailureModels.kt @@ -32,9 +32,9 @@ import org.opendc.compute.simulator.failure.StartStopHostFault import org.opendc.compute.simulator.failure.StochasticVictimSelector import java.time.Clock import java.time.Duration +import java.util.* import kotlin.coroutines.CoroutineContext import kotlin.math.ln -import kotlin.random.Random /** * Obtain a [FailureModel] based on the GRID'5000 failure trace. @@ -42,14 +42,15 @@ import kotlin.random.Random * This fault injector uses parameters from the GRID'5000 failure trace as described in * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. */ -public fun grid5000(failureInterval: Duration, seed: Int): FailureModel { +public fun grid5000(failureInterval: Duration): FailureModel { return object : FailureModel { override fun createInjector( context: CoroutineContext, clock: Clock, - service: ComputeService + service: ComputeService, + random: Random ): HostFaultInjector { - val rng = Well19937c(seed) + val rng = Well19937c(random.nextLong()) val hosts = service.hosts.map { it as SimHost }.toSet() // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 @@ -59,7 +60,7 @@ public fun grid5000(failureInterval: Duration, seed: Int): FailureModel { clock, hosts, iat = LogNormalDistribution(rng, ln(failureInterval.toHours().toDouble()), 1.03), - selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), Random(seed)), + selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), random), fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) ) } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt new file mode 100644 index 00000000..40484b68 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload + +import org.opendc.simulator.compute.workload.SimTraceWorkload +import java.time.Instant +import java.util.* + +/** + * A virtual machine workload. + * + * @param uid The unique identifier of the virtual machine. + * @param name The name of the virtual machine. + * @param cpuCount The number of vCPUs in the VM. + * @param memCapacity The provisioned memory for the VM. + * @param startTime The start time of the VM. + * @param stopTime The stop time of the VM. + * @param trace The trace fragments that belong to this VM. + */ +public data class VirtualMachine( + val uid: UUID, + val name: String, + val cpuCount: Int, + val memCapacity: Long, + val totalLoad: Double, + val startTime: Instant, + val stopTime: Instant, + val trace: Sequence, +) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt new file mode 100644 index 00000000..9b2bec55 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.internal + +import mu.KotlinLogging +import org.opendc.compute.workload.ComputeWorkload +import org.opendc.compute.workload.ComputeWorkloadLoader +import org.opendc.compute.workload.VirtualMachine +import java.util.* + +/** + * A [ComputeWorkload] that samples multiple workloads based on the total load of all workloads. + */ +internal class CompositeComputeWorkload(val sources: Map) : ComputeWorkload { + /** + * The logging instance of this class. + */ + private val logger = KotlinLogging.logger {} + + override fun resolve(loader: ComputeWorkloadLoader, random: Random): List { + val traces = sources.map { (source, fraction) -> fraction to source.resolve(loader, random) } + + val totalLoad = traces.sumOf { (_, vms) -> vms.sumOf { it.totalLoad } } + + val res = mutableListOf() + + for ((fraction, vms) in traces) { + var currentLoad = 0.0 + + for (entry in vms) { + val entryLoad = entry.totalLoad + if ((currentLoad + entryLoad) / totalLoad > fraction) { + break + } + + currentLoad += entryLoad + res += entry + } + } + + val vmCount = traces.sumOf { (_, vms) -> vms.size } + logger.info { "Sampled $vmCount VMs into subset of ${res.size} VMs" } + + return res + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt new file mode 100644 index 00000000..52f4c672 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.internal + +import mu.KotlinLogging +import org.opendc.compute.workload.ComputeWorkload +import org.opendc.compute.workload.ComputeWorkloadLoader +import org.opendc.compute.workload.VirtualMachine +import java.util.* + +/** + * A [ComputeWorkload] that samples HPC VMs in the workload. + * + * @param fraction The fraction of load/virtual machines to sample + * @param sampleLoad A flag to indicate that the sampling should be based on the total load or on the number of VMs. + */ +internal class HpcSampledComputeWorkload(val source: ComputeWorkload, val fraction: Double, val sampleLoad: Boolean = false) : ComputeWorkload { + /** + * The logging instance of this class. + */ + private val logger = KotlinLogging.logger {} + + /** + * The pattern to match compute nodes in the workload. + */ + private val pattern = Regex("^(ComputeNode|cn).*") + + override fun resolve(loader: ComputeWorkloadLoader, random: Random): List { + val vms = source.resolve(loader, random) + + val (hpc, nonHpc) = vms.partition { entry -> + val name = entry.name + name.matches(pattern) + } + + val hpcSequence = generateSequence(0) { it + 1 } + .map { index -> + val res = mutableListOf() + hpc.mapTo(res) { sample(it, index) } + res.shuffle(random) + res + } + .flatten() + + val nonHpcSequence = generateSequence(0) { it + 1 } + .map { index -> + val res = mutableListOf() + nonHpc.mapTo(res) { sample(it, index) } + res.shuffle(random) + res + } + .flatten() + + logger.debug { "Found ${hpc.size} HPC workloads and ${nonHpc.size} non-HPC workloads" } + + val totalLoad = vms.sumOf { it.totalLoad } + + logger.debug { "Total trace load: $totalLoad" } + var hpcCount = 0 + var hpcLoad = 0.0 + var nonHpcCount = 0 + var nonHpcLoad = 0.0 + + val res = mutableListOf() + + if (sampleLoad) { + var currentLoad = 0.0 + for (entry in hpcSequence) { + val entryLoad = entry.totalLoad + if ((currentLoad + entryLoad) / totalLoad > fraction) { + break + } + + hpcLoad += entryLoad + hpcCount += 1 + currentLoad += entryLoad + res += entry + } + + for (entry in nonHpcSequence) { + val entryLoad = entry.totalLoad + if ((currentLoad + entryLoad) / totalLoad > 1) { + break + } + + nonHpcLoad += entryLoad + nonHpcCount += 1 + currentLoad += entryLoad + res += entry + } + } else { + hpcSequence + .take((fraction * vms.size).toInt()) + .forEach { entry -> + hpcLoad += entry.totalLoad + hpcCount += 1 + res.add(entry) + } + + nonHpcSequence + .take(((1 - fraction) * vms.size).toInt()) + .forEach { entry -> + nonHpcLoad += entry.totalLoad + nonHpcCount += 1 + res.add(entry) + } + } + + logger.debug { "HPC $hpcCount (load $hpcLoad) and non-HPC $nonHpcCount (load $nonHpcLoad)" } + logger.debug { "Total sampled load: ${hpcLoad + nonHpcLoad}" } + logger.info { "Sampled ${vms.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } + + return res + } + + /** + * Sample a random trace entry. + */ + private fun sample(entry: VirtualMachine, i: Int): VirtualMachine { + val uid = UUID.nameUUIDFromBytes("${entry.uid}-$i".toByteArray()) + return entry.copy(uid = uid) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt new file mode 100644 index 00000000..ef6de729 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.internal + +import mu.KotlinLogging +import org.opendc.compute.workload.ComputeWorkload +import org.opendc.compute.workload.ComputeWorkloadLoader +import org.opendc.compute.workload.VirtualMachine +import java.util.* + +/** + * A [ComputeWorkload] that is sampled based on total load. + */ +internal class LoadSampledComputeWorkload(val source: ComputeWorkload, val fraction: Double) : ComputeWorkload { + /** + * The logging instance of this class. + */ + private val logger = KotlinLogging.logger {} + + override fun resolve(loader: ComputeWorkloadLoader, random: Random): List { + val vms = source.resolve(loader, random) + val res = mutableListOf() + + val totalLoad = vms.sumOf { it.totalLoad } + var currentLoad = 0.0 + + for (entry in vms) { + val entryLoad = entry.totalLoad + if ((currentLoad + entryLoad) / totalLoad > fraction) { + break + } + + currentLoad += entryLoad + res += entry + } + + logger.info { "Sampled ${vms.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } + + return res + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt new file mode 100644 index 00000000..d657ff01 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.internal + +import org.opendc.compute.workload.ComputeWorkload +import org.opendc.compute.workload.ComputeWorkloadLoader +import org.opendc.compute.workload.VirtualMachine +import java.util.* + +/** + * A [ComputeWorkload] from a trace. + */ +internal class TraceComputeWorkload(val name: String) : ComputeWorkload { + override fun resolve(loader: ComputeWorkloadLoader, random: Random): List { + return loader.get(name) + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt deleted file mode 100644 index ae20482d..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/RawParquetTraceReader.kt +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace - -import org.opendc.compute.workload.trace.bp.BPTraceFormat -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.trace.* -import java.io.File -import java.util.UUID - -/** - * A [TraceReader] for the internal VM workload trace format. - * - * @param path The directory of the traces. - */ -public class RawParquetTraceReader(private val path: File) { - /** - * The [Trace] that represents this trace. - */ - private val trace = BPTraceFormat().open(path.toURI().toURL()) - - /** - * Read the fragments into memory. - */ - private fun parseFragments(): Map> { - val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - - val fragments = mutableMapOf>() - - return try { - while (reader.nextRow()) { - val id = reader.get(RESOURCE_STATE_ID) - val time = reader.get(RESOURCE_STATE_TIMESTAMP) - val duration = reader.get(RESOURCE_STATE_DURATION) - val cores = reader.getInt(RESOURCE_STATE_NCPUS) - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - - val fragment = SimTraceWorkload.Fragment( - time.toEpochMilli(), - duration.toMillis(), - cpuUsage, - cores - ) - - fragments.getOrPut(id) { mutableListOf() }.add(fragment) - } - - fragments - } finally { - reader.close() - } - } - - /** - * Read the metadata into a workload. - */ - private fun parseMeta(fragments: Map>): List> { - val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() - - var counter = 0 - val entries = mutableListOf>() - - return try { - while (reader.nextRow()) { - - val id = reader.get(RESOURCE_ID) - if (!fragments.containsKey(id)) { - continue - } - - val submissionTime = reader.get(RESOURCE_START_TIME) - val endTime = reader.get(RESOURCE_STOP_TIME) - val maxCores = reader.getInt(RESOURCE_NCPUS) - val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB - val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) - - val vmFragments = fragments.getValue(id).asSequence() - val totalLoad = vmFragments.sumOf { it.usage } * 5 * 60 // avg MHz * duration = MFLOPs - val workload = SimTraceWorkload(vmFragments) - entries.add( - TraceEntry( - uid, id, submissionTime.toEpochMilli(), workload, - mapOf( - "submit-time" to submissionTime.toEpochMilli(), - "end-time" to endTime.toEpochMilli(), - "total-load" to totalLoad, - "cores" to maxCores, - "required-memory" to requiredMemory.toLong(), - "workload" to workload - ) - ) - ) - } - - entries - } catch (e: Exception) { - e.printStackTrace() - throw e - } finally { - reader.close() - } - } - - /** - * The entries in the trace. - */ - private val entries: List> - - init { - val fragments = parseFragments() - entries = parseMeta(fragments) - } - - /** - * Read the entries in the trace. - */ - public fun read(): List> = entries -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt deleted file mode 100644 index 36cd0a7d..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/StreamingParquetTraceReader.kt +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace - -import mu.KotlinLogging -import org.apache.avro.generic.GenericData -import org.apache.parquet.avro.AvroParquetReader -import org.apache.parquet.filter2.compat.FilterCompat -import org.apache.parquet.filter2.predicate.FilterApi -import org.apache.parquet.filter2.predicate.Statistics -import org.apache.parquet.filter2.predicate.UserDefinedPredicate -import org.apache.parquet.io.api.Binary -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.trace.util.parquet.LocalInputFile -import java.io.File -import java.io.Serializable -import java.util.SortedSet -import java.util.TreeSet -import java.util.UUID -import java.util.concurrent.ArrayBlockingQueue -import kotlin.concurrent.thread - -/** - * A [TraceReader] for the internal VM workload trace format that streams workloads on the fly. - * - * @param traceFile The directory of the traces. - * @param selectedVms The list of VMs to read from the trace. - */ -public class StreamingParquetTraceReader(traceFile: File, selectedVms: List = emptyList()) : TraceReader { - private val logger = KotlinLogging.logger {} - - /** - * The internal iterator to use for this reader. - */ - private val iterator: Iterator> - - /** - * The intermediate buffer to store the read records in. - */ - private val queue = ArrayBlockingQueue>(1024) - - /** - * An optional filter for filtering the selected VMs - */ - private val filter = - if (selectedVms.isEmpty()) - null - else - FilterCompat.get( - FilterApi.userDefined( - FilterApi.binaryColumn("id"), - SelectedVmFilter( - TreeSet(selectedVms) - ) - ) - ) - - /** - * A poisonous fragment. - */ - private val poison = Pair("\u0000", SimTraceWorkload.Fragment(0L, 0, 0.0, 0)) - - /** - * The thread to read the records in. - */ - private val readerThread = thread(start = true, name = "sc20-reader") { - val reader = AvroParquetReader - .builder(LocalInputFile(File(traceFile, "trace.parquet"))) - .disableCompatibility() - .withFilter(filter) - .build() - - try { - while (true) { - val record = reader.read() - - if (record == null) { - queue.put(poison) - break - } - - val id = record["id"].toString() - val time = record["time"] as Long - val duration = record["duration"] as Long - val cores = record["cores"] as Int - val cpuUsage = record["cpuUsage"] as Double - - val fragment = SimTraceWorkload.Fragment( - time, - duration, - cpuUsage, - cores - ) - - queue.put(id to fragment) - } - } catch (e: InterruptedException) { - // Do not rethrow this - } finally { - reader.close() - } - } - - /** - * Fill the buffers with the VMs - */ - private fun pull(buffers: Map>>) { - if (!hasNext) { - return - } - - val fragments = mutableListOf>() - queue.drainTo(fragments) - - for ((id, fragment) in fragments) { - if (id == poison.first) { - hasNext = false - return - } - buffers[id]?.forEach { it.add(fragment) } - } - } - - /** - * A flag to indicate whether the reader has more entries. - */ - private var hasNext: Boolean = true - - /** - * Initialize the reader. - */ - init { - val takenIds = mutableSetOf() - val entries = mutableMapOf() - val buffers = mutableMapOf>>() - - val metaReader = AvroParquetReader - .builder(LocalInputFile(File(traceFile, "meta.parquet"))) - .disableCompatibility() - .withFilter(filter) - .build() - - while (true) { - val record = metaReader.read() ?: break - val id = record["id"].toString() - entries[id] = record - } - - metaReader.close() - - val selection = selectedVms.ifEmpty { entries.keys } - - // Create the entry iterator - iterator = selection.asSequence() - .mapNotNull { entries[it] } - .mapIndexed { index, record -> - val id = record["id"].toString() - val submissionTime = record["submissionTime"] as Long - val endTime = record["endTime"] as Long - val maxCores = record["maxCores"] as Int - val requiredMemory = record["requiredMemory"] as Long - val uid = UUID.nameUUIDFromBytes("$id-$index".toByteArray()) - - assert(uid !in takenIds) - takenIds += uid - - logger.info { "Processing VM $id" } - - val internalBuffer = mutableListOf() - val externalBuffer = mutableListOf() - buffers.getOrPut(id) { mutableListOf() }.add(externalBuffer) - val fragments = sequence { - var time = submissionTime - repeat@ while (true) { - if (externalBuffer.isEmpty()) { - if (hasNext) { - pull(buffers) - continue - } else { - break - } - } - - internalBuffer.addAll(externalBuffer) - externalBuffer.clear() - - for (fragment in internalBuffer) { - yield(fragment) - - time += fragment.duration - if (time >= endTime) { - break@repeat - } - } - - internalBuffer.clear() - } - - buffers.remove(id) - } - val workload = SimTraceWorkload(fragments) - val meta = mapOf( - "cores" to maxCores, - "required-memory" to requiredMemory, - "workload" to workload - ) - - TraceEntry(uid, id, submissionTime, workload, meta) - } - .sortedBy { it.start } - .toList() - .iterator() - } - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() { - readerThread.interrupt() - } - - private class SelectedVmFilter(val selectedVms: SortedSet) : UserDefinedPredicate(), Serializable { - override fun keep(value: Binary?): Boolean = value != null && selectedVms.contains(value.toStringUsingUTF8()) - - override fun canDrop(statistics: Statistics): Boolean { - val min = statistics.min - val max = statistics.max - - return selectedVms.subSet(min.toStringUsingUTF8(), max.toStringUsingUTF8() + "\u0000").isEmpty() - } - - override fun inverseCanDrop(statistics: Statistics): Boolean { - val min = statistics.min - val max = statistics.max - - return selectedVms.subSet(min.toStringUsingUTF8(), max.toStringUsingUTF8() + "\u0000").isNotEmpty() - } - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt deleted file mode 100644 index bfa2d051..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceEntry.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace - -import java.util.UUID - -/** - * An entry in a workload trace. - * - * @param uid The unique identifier of the entry. - * @param name The name of the entry. - * @param start The start time of the workload. - * @param workload The workload of the entry. - * @param meta The meta-data associated with the workload. - */ -public data class TraceEntry( - val uid: UUID, - val name: String, - val start: Long, - val workload: T, - val meta: Map -) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt deleted file mode 100644 index b0795d61..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceReader.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace - -/** - * An interface for reading workloads into memory. - * - * This interface must guarantee that the entries are delivered in order of submission time. - * - * @param T The shape of the workloads supported by this reader. - */ -public interface TraceReader : Iterator>, AutoCloseable diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/CompositeWorkloadPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/CompositeWorkloadPortfolio.kt index faabe5cb..31e8f961 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/CompositeWorkloadPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/CompositeWorkloadPortfolio.kt @@ -22,7 +22,8 @@ package org.opendc.experiments.capelin -import org.opendc.experiments.capelin.model.CompositeWorkload +import org.opendc.compute.workload.composite +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload @@ -42,30 +43,25 @@ public class CompositeWorkloadPortfolio : Portfolio("composite-workload") { ) override val workload: Workload by anyOf( - CompositeWorkload( + Workload( "all-azure", - listOf(Workload("solvinity-short", 0.0), Workload("azure", 1.0)), - totalSampleLoad + composite(trace("solvinity-short") to 0.0, trace("azure") to 1.0) ), - CompositeWorkload( + Workload( "solvinity-25-azure-75", - listOf(Workload("solvinity-short", 0.25), Workload("azure", 0.75)), - totalSampleLoad + composite(trace("solvinity-short") to 0.25, trace("azure") to 0.75) ), - CompositeWorkload( + Workload( "solvinity-50-azure-50", - listOf(Workload("solvinity-short", 0.5), Workload("azure", 0.5)), - totalSampleLoad + composite(trace("solvinity-short") to 0.5, trace("azure") to 0.5) ), - CompositeWorkload( + Workload( "solvinity-75-azure-25", - listOf(Workload("solvinity-short", 0.75), Workload("azure", 0.25)), - totalSampleLoad + composite(trace("solvinity-short") to 0.75, trace("azure") to 0.25) ), - CompositeWorkload( + Workload( "all-solvinity", - listOf(Workload("solvinity-short", 1.0), Workload("azure", 0.0)), - totalSampleLoad + composite(trace("solvinity-short") to 1.0, trace("azure") to 0.0) ) ) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/HorVerPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/HorVerPortfolio.kt index e1cf8517..cd093e6c 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/HorVerPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/HorVerPortfolio.kt @@ -22,6 +22,8 @@ package org.opendc.experiments.capelin +import org.opendc.compute.workload.sampleByLoad +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload @@ -44,10 +46,10 @@ public class HorVerPortfolio : Portfolio("horizontal_vs_vertical") { ) override val workload: Workload by anyOf( - Workload("solvinity", 0.1), - Workload("solvinity", 0.25), - Workload("solvinity", 0.5), - Workload("solvinity", 1.0) + Workload("solvinity", trace("solvinity").sampleByLoad(0.1)), + Workload("solvinity", trace("solvinity").sampleByLoad(0.25)), + Workload("solvinity", trace("solvinity").sampleByLoad(0.5)), + Workload("solvinity", trace("solvinity").sampleByLoad(1.0)) ) override val operationalPhenomena: OperationalPhenomena by anyOf( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreHpcPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreHpcPortfolio.kt index a995e467..73e59a58 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreHpcPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreHpcPortfolio.kt @@ -22,8 +22,10 @@ package org.opendc.experiments.capelin +import org.opendc.compute.workload.sampleByHpc +import org.opendc.compute.workload.sampleByHpcLoad +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena -import org.opendc.experiments.capelin.model.SamplingStrategy import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload import org.opendc.harness.dsl.anyOf @@ -40,13 +42,13 @@ public class MoreHpcPortfolio : Portfolio("more_hpc") { ) override val workload: Workload by anyOf( - Workload("solvinity", 0.0, samplingStrategy = SamplingStrategy.HPC), - Workload("solvinity", 0.25, samplingStrategy = SamplingStrategy.HPC), - Workload("solvinity", 0.5, samplingStrategy = SamplingStrategy.HPC), - Workload("solvinity", 1.0, samplingStrategy = SamplingStrategy.HPC), - Workload("solvinity", 0.25, samplingStrategy = SamplingStrategy.HPC_LOAD), - Workload("solvinity", 0.5, samplingStrategy = SamplingStrategy.HPC_LOAD), - Workload("solvinity", 1.0, samplingStrategy = SamplingStrategy.HPC_LOAD) + Workload("solvinity", trace("solvinity").sampleByHpc(0.0)), + Workload("solvinity", trace("solvinity").sampleByHpc(0.25)), + Workload("solvinity", trace("solvinity").sampleByHpc(0.5)), + Workload("solvinity", trace("solvinity").sampleByHpc(1.0)), + Workload("solvinity", trace("solvinity").sampleByHpcLoad(0.25)), + Workload("solvinity", trace("solvinity").sampleByHpcLoad(0.5)), + Workload("solvinity", trace("solvinity").sampleByHpcLoad(1.0)) ) override val operationalPhenomena: OperationalPhenomena by anyOf( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreVelocityPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreVelocityPortfolio.kt index 49559e0e..9d5717bb 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreVelocityPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/MoreVelocityPortfolio.kt @@ -22,6 +22,8 @@ package org.opendc.experiments.capelin +import org.opendc.compute.workload.sampleByLoad +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload @@ -40,10 +42,10 @@ public class MoreVelocityPortfolio : Portfolio("more_velocity") { ) override val workload: Workload by anyOf( - Workload("solvinity", 0.1), - Workload("solvinity", 0.25), - Workload("solvinity", 0.5), - Workload("solvinity", 1.0) + Workload("solvinity", trace("solvinity").sampleByLoad(0.1)), + Workload("solvinity", trace("solvinity").sampleByLoad(0.25)), + Workload("solvinity", trace("solvinity").sampleByLoad(0.5)), + Workload("solvinity", trace("solvinity").sampleByLoad(1.0)) ) override val operationalPhenomena: OperationalPhenomena by anyOf( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/OperationalPhenomenaPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/OperationalPhenomenaPortfolio.kt index 1aac4f9e..7ab586b3 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/OperationalPhenomenaPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/OperationalPhenomenaPortfolio.kt @@ -22,6 +22,8 @@ package org.opendc.experiments.capelin +import org.opendc.compute.workload.sampleByLoad +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload @@ -36,10 +38,10 @@ public class OperationalPhenomenaPortfolio : Portfolio("operational_phenomena") ) override val workload: Workload by anyOf( - Workload("solvinity", 0.1), - Workload("solvinity", 0.25), - Workload("solvinity", 0.5), - Workload("solvinity", 1.0) + Workload("solvinity", trace("solvinity").sampleByLoad(0.1)), + Workload("solvinity", trace("solvinity").sampleByLoad(0.25)), + Workload("solvinity", trace("solvinity").sampleByLoad(0.5)), + Workload("solvinity", trace("solvinity").sampleByLoad(1.0)) ) override val operationalPhenomena: OperationalPhenomena by anyOf( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 02811d83..630b76c4 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -24,18 +24,16 @@ package org.opendc.experiments.capelin import com.typesafe.config.ConfigFactory import mu.KotlinLogging +import org.opendc.compute.workload.ComputeWorkloadLoader import org.opendc.compute.workload.ComputeWorkloadRunner import org.opendc.compute.workload.export.parquet.ParquetExportMonitor import org.opendc.compute.workload.grid5000 import org.opendc.compute.workload.topology.apply -import org.opendc.compute.workload.trace.RawParquetTraceReader import org.opendc.compute.workload.util.PerformanceInterferenceReader -import org.opendc.experiments.capelin.model.CompositeWorkload import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.topology.clusterTopology -import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf @@ -47,7 +45,6 @@ import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.io.File import java.time.Duration import java.util.* -import java.util.concurrent.ConcurrentHashMap import kotlin.math.roundToLong /** @@ -92,9 +89,9 @@ abstract class Portfolio(name: String) : Experiment(name) { abstract val allocationPolicy: String /** - * A map of trace readers. + * A helper class to load workload traces. */ - private val traceReaders = ConcurrentHashMap() + private val workloadLoader = ComputeWorkloadLoader(File(config.getString("trace-path"))) /** * Perform a single trial for this portfolio. @@ -102,19 +99,6 @@ abstract class Portfolio(name: String) : Experiment(name) { override fun doRun(repeat: Int): Unit = runBlockingSimulation { val seeder = Random(repeat.toLong()) - val workload = workload - val workloadNames = if (workload is CompositeWorkload) { - workload.workloads.map { it.name } - } else { - listOf(workload.name) - } - val rawReaders = workloadNames.map { workloadName -> - traceReaders.computeIfAbsent(workloadName) { - logger.info { "Loading trace $workloadName" } - RawParquetTraceReader(File(config.getString("trace-path"), workloadName)) - } - } - val trace = ParquetTraceReader(rawReaders, workload, seeder.nextInt()) val performanceInterferenceModel = if (operationalPhenomena.hasInterference) PerformanceInterferenceReader() .read(File(config.getString("interference-model"))) @@ -125,7 +109,7 @@ abstract class Portfolio(name: String) : Experiment(name) { val computeScheduler = createComputeScheduler(allocationPolicy, seeder, vmPlacements) val failureModel = if (operationalPhenomena.failureFrequency > 0) - grid5000(Duration.ofSeconds((operationalPhenomena.failureFrequency * 60).roundToLong()), seeder.nextInt()) + grid5000(Duration.ofSeconds((operationalPhenomena.failureFrequency * 60).roundToLong())) else null val runner = ComputeWorkloadRunner( @@ -149,7 +133,7 @@ abstract class Portfolio(name: String) : Experiment(name) { runner.apply(topology) // Run the workload trace - runner.run(trace) + runner.run(workload.source.resolve(workloadLoader, seeder), seeder.nextLong()) } finally { runner.close() metricReader.close() diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ReplayPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ReplayPortfolio.kt index b6d3b30c..17ec48d4 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ReplayPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ReplayPortfolio.kt @@ -22,6 +22,7 @@ package org.opendc.experiments.capelin +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload @@ -36,7 +37,7 @@ public class ReplayPortfolio : Portfolio("replay") { ) override val workload: Workload by anyOf( - Workload("solvinity", 1.0) + Workload("solvinity", trace("solvinity")) ) override val operationalPhenomena: OperationalPhenomena by anyOf( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/TestPortfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/TestPortfolio.kt index 90840db8..98eb989d 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/TestPortfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/TestPortfolio.kt @@ -22,6 +22,7 @@ package org.opendc.experiments.capelin +import org.opendc.compute.workload.trace import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload @@ -36,7 +37,7 @@ public class TestPortfolio : Portfolio("test") { ) override val workload: Workload by anyOf( - Workload("solvinity", 1.0) + Workload("solvinity", trace("solvinity")) ) override val operationalPhenomena: OperationalPhenomena by anyOf( diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/model/Workload.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/model/Workload.kt index c4ddd158..a2e71243 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/model/Workload.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/model/Workload.kt @@ -22,23 +22,12 @@ package org.opendc.experiments.capelin.model -public enum class SamplingStrategy { - REGULAR, - HPC, - HPC_LOAD -} +import org.opendc.compute.workload.ComputeWorkload /** - * A workload that is considered for a scenario. - */ -public open class Workload( - public open val name: String, - public val fraction: Double, - public val samplingStrategy: SamplingStrategy = SamplingStrategy.REGULAR -) - -/** - * A workload that is composed of multiple workloads. + * A single workload originating from a trace. + * + * @param name the name of the workload. + * @param source The source of the workload data. */ -public class CompositeWorkload(override val name: String, public val workloads: List, public val totalLoad: Double) : - Workload(name, -1.0) +data class Workload(val name: String, val source: ComputeWorkload) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt deleted file mode 100644 index 498636ba..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/ParquetTraceReader.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import org.opendc.compute.workload.trace.RawParquetTraceReader -import org.opendc.compute.workload.trace.TraceEntry -import org.opendc.compute.workload.trace.TraceReader -import org.opendc.experiments.capelin.model.CompositeWorkload -import org.opendc.experiments.capelin.model.Workload -import org.opendc.simulator.compute.workload.SimWorkload - -/** - * A [TraceReader] for the internal VM workload trace format. - * - * @param rawReaders The internal raw trace readers to use. - * @param workload The workload to read. - * @param seed The seed to use for sampling. - */ -public class ParquetTraceReader( - rawReaders: List, - workload: Workload, - seed: Int -) : TraceReader { - /** - * The iterator over the actual trace. - */ - private val iterator: Iterator> = - rawReaders - .map { it.read() } - .run { - if (workload is CompositeWorkload) { - this.zip(workload.workloads) - } else { - this.zip(listOf(workload)) - } - } - .flatMap { - sampleWorkload(it.first, workload, it.second, seed) - .sortedBy(TraceEntry::start) - } - .iterator() - - override fun hasNext(): Boolean = iterator.hasNext() - - override fun next(): TraceEntry = iterator.next() - - override fun close() {} -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt deleted file mode 100644 index b42951df..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/WorkloadSampler.kt +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.experiments.capelin.trace - -import mu.KotlinLogging -import org.opendc.compute.workload.trace.TraceEntry -import org.opendc.experiments.capelin.model.CompositeWorkload -import org.opendc.experiments.capelin.model.SamplingStrategy -import org.opendc.experiments.capelin.model.Workload -import org.opendc.simulator.compute.workload.SimWorkload -import java.util.* -import kotlin.random.Random - -private val logger = KotlinLogging.logger {} - -/** - * Sample the workload for the specified [run]. - */ -public fun sampleWorkload( - trace: List>, - workload: Workload, - subWorkload: Workload, - seed: Int -): List> { - return when { - workload is CompositeWorkload -> sampleRegularWorkload(trace, workload, subWorkload, seed) - workload.samplingStrategy == SamplingStrategy.HPC -> - sampleHpcWorkload(trace, workload, seed, sampleOnLoad = false) - workload.samplingStrategy == SamplingStrategy.HPC_LOAD -> - sampleHpcWorkload(trace, workload, seed, sampleOnLoad = true) - else -> - sampleRegularWorkload(trace, workload, workload, seed) - } -} - -/** - * Sample a regular (non-HPC) workload. - */ -public fun sampleRegularWorkload( - trace: List>, - workload: Workload, - subWorkload: Workload, - seed: Int -): List> { - val fraction = subWorkload.fraction - - val shuffled = trace.shuffled(Random(seed)) - val res = mutableListOf>() - val totalLoad = if (workload is CompositeWorkload) { - workload.totalLoad - } else { - shuffled.sumOf { it.meta.getValue("total-load") as Double } - } - var currentLoad = 0.0 - - for (entry in shuffled) { - val entryLoad = entry.meta.getValue("total-load") as Double - if ((currentLoad + entryLoad) / totalLoad > fraction) { - break - } - - currentLoad += entryLoad - res += entry - } - - logger.info { "Sampled ${trace.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } - - return res -} - -/** - * Sample a HPC workload. - */ -public fun sampleHpcWorkload( - trace: List>, - workload: Workload, - seed: Int, - sampleOnLoad: Boolean -): List> { - val pattern = Regex("^vm__workload__(ComputeNode|cn).*") - val random = Random(seed) - - val fraction = workload.fraction - val (hpc, nonHpc) = trace.partition { entry -> - val name = entry.name - name.matches(pattern) - } - - val hpcSequence = generateSequence(0) { it + 1 } - .map { index -> - val res = mutableListOf>() - hpc.mapTo(res) { sample(it, index) } - res.shuffle(random) - res - } - .flatten() - - val nonHpcSequence = generateSequence(0) { it + 1 } - .map { index -> - val res = mutableListOf>() - nonHpc.mapTo(res) { sample(it, index) } - res.shuffle(random) - res - } - .flatten() - - logger.debug { "Found ${hpc.size} HPC workloads and ${nonHpc.size} non-HPC workloads" } - - val totalLoad = if (workload is CompositeWorkload) { - workload.totalLoad - } else { - trace.sumOf { it.meta.getValue("total-load") as Double } - } - - logger.debug { "Total trace load: $totalLoad" } - var hpcCount = 0 - var hpcLoad = 0.0 - var nonHpcCount = 0 - var nonHpcLoad = 0.0 - - val res = mutableListOf>() - - if (sampleOnLoad) { - var currentLoad = 0.0 - for (entry in hpcSequence) { - val entryLoad = entry.meta.getValue("total-load") as Double - if ((currentLoad + entryLoad) / totalLoad > fraction) { - break - } - - hpcLoad += entryLoad - hpcCount += 1 - currentLoad += entryLoad - res += entry - } - - for (entry in nonHpcSequence) { - val entryLoad = entry.meta.getValue("total-load") as Double - if ((currentLoad + entryLoad) / totalLoad > 1) { - break - } - - nonHpcLoad += entryLoad - nonHpcCount += 1 - currentLoad += entryLoad - res += entry - } - } else { - hpcSequence - .take((fraction * trace.size).toInt()) - .forEach { entry -> - hpcLoad += entry.meta.getValue("total-load") as Double - hpcCount += 1 - res.add(entry) - } - - nonHpcSequence - .take(((1 - fraction) * trace.size).toInt()) - .forEach { entry -> - nonHpcLoad += entry.meta.getValue("total-load") as Double - nonHpcCount += 1 - res.add(entry) - } - } - - logger.debug { "HPC $hpcCount (load $hpcLoad) and non-HPC $nonHpcCount (load $nonHpcLoad)" } - logger.debug { "Total sampled load: ${hpcLoad + nonHpcLoad}" } - logger.info { "Sampled ${trace.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } - - return res -} - -/** - * Sample a random trace entry. - */ -private fun sample(entry: TraceEntry, i: Int): TraceEntry { - val uid = UUID.nameUUIDFromBytes("${entry.uid}-$i".toByteArray()) - return entry.copy(uid = uid) -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index c1386bfe..140a84db 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -31,18 +31,12 @@ import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.filters.RamFilter import org.opendc.compute.service.scheduler.filters.VCpuFilter import org.opendc.compute.service.scheduler.weights.CoreRamWeigher -import org.opendc.compute.workload.ComputeWorkloadRunner -import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.* import org.opendc.compute.workload.topology.Topology import org.opendc.compute.workload.topology.apply -import org.opendc.compute.workload.trace.RawParquetTraceReader -import org.opendc.compute.workload.trace.TraceReader import org.opendc.compute.workload.util.PerformanceInterferenceReader -import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.topology.clusterTopology -import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel -import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.ComputeMonitor @@ -67,6 +61,11 @@ class CapelinIntegrationTest { */ private lateinit var computeScheduler: FilterScheduler + /** + * The [ComputeWorkloadLoader] responsible for loading the traces. + */ + private lateinit var workloadLoader: ComputeWorkloadLoader + /** * Setup the experimental environment. */ @@ -77,6 +76,7 @@ class CapelinIntegrationTest { filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) ) + workloadLoader = ComputeWorkloadLoader(File("src/test/resources/trace")) } /** @@ -84,24 +84,24 @@ class CapelinIntegrationTest { */ @Test fun testLarge() = runBlockingSimulation { - val traceReader = createTestTraceReader() - val simulator = ComputeWorkloadRunner( + val workload = createTestWorkload(1.0) + val runner = ComputeWorkloadRunner( coroutineContext, clock, computeScheduler ) val topology = createTopology() - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, runner.producers, ComputeMetricExporter(clock, monitor)) try { - simulator.apply(topology) - simulator.run(traceReader) + runner.apply(topology) + runner.run(workload, 0) } finally { - simulator.close() + runner.close() metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(clock.instant(), runner.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -117,11 +117,11 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, - { assertEquals(223856043, monitor.idleTime) { "Incorrect idle time" } }, - { assertEquals(66481557, monitor.activeTime) { "Incorrect active time" } }, - { assertEquals(360441, monitor.stealTime) { "Incorrect steal time" } }, + { assertEquals(221949826, monitor.idleTime) { "Incorrect idle time" } }, + { assertEquals(68421374, monitor.activeTime) { "Incorrect active time" } }, + { assertEquals(947010, monitor.stealTime) { "Incorrect steal time" } }, { assertEquals(0, monitor.lostTime) { "Incorrect lost time" } }, - { assertEquals(5.418336360461193E9, monitor.energyUsage, 0.01) { "Incorrect power draw" } }, + { assertEquals(5.783711298639437E9, monitor.energyUsage, 0.01) { "Incorrect power draw" } }, ) } @@ -131,7 +131,7 @@ class CapelinIntegrationTest { @Test fun testSmall() = runBlockingSimulation { val seed = 1 - val traceReader = createTestTraceReader(0.25, seed) + val workload = createTestWorkload(0.25, seed) val simulator = ComputeWorkloadRunner( coroutineContext, @@ -143,7 +143,7 @@ class CapelinIntegrationTest { try { simulator.apply(topology) - simulator.run(traceReader) + simulator.run(workload, seed.toLong()) } finally { simulator.close() metricReader.close() @@ -161,9 +161,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(9597804, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(11140596, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(326138, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(8545158, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(12195642, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(941038, monitor.stealTime) { "Steal time incorrect" } }, { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } } ) } @@ -173,9 +173,8 @@ class CapelinIntegrationTest { */ @Test fun testInterference() = runBlockingSimulation { - val seed = 1 - val traceReader = createTestTraceReader(0.25, seed) - + val seed = 0 + val workload = createTestWorkload(1.0, seed) val perfInterferenceInput = checkNotNull(CapelinIntegrationTest::class.java.getResourceAsStream("/bitbrains-perf-interference.json")) val performanceInterferenceModel = PerformanceInterferenceReader() @@ -193,7 +192,7 @@ class CapelinIntegrationTest { try { simulator.apply(topology) - simulator.run(traceReader) + simulator.run(workload, seed.toLong()) } finally { simulator.close() metricReader.close() @@ -211,10 +210,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(9597804, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(11140596, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(326138, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(925305, monitor.lostTime) { "Lost time incorrect" } } + { assertEquals(8545158, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(12195642, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(941038, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(3378, monitor.lostTime) { "Lost time incorrect" } } ) } @@ -228,15 +227,15 @@ class CapelinIntegrationTest { coroutineContext, clock, computeScheduler, - grid5000(Duration.ofDays(7), seed) + grid5000(Duration.ofDays(7)) ) val topology = createTopology("single") - val traceReader = createTestTraceReader(0.25, seed) + val workload = createTestWorkload(0.25, seed) val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) try { simulator.apply(topology) - simulator.run(traceReader) + simulator.run(workload, seed.toLong()) } finally { simulator.close() metricReader.close() @@ -254,23 +253,20 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(9836315, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(10902085, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(306249, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(8640140, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(12100660, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(939456, monitor.stealTime) { "Steal time incorrect" } }, { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, - { assertEquals(2540877457, monitor.uptime) { "Uptime incorrect" } } + { assertEquals(2559305056, monitor.uptime) { "Uptime incorrect" } } ) } /** * Obtain the trace reader for the test. */ - private fun createTestTraceReader(fraction: Double = 1.0, seed: Int = 0): TraceReader { - return ParquetTraceReader( - listOf(RawParquetTraceReader(File("src/test/resources/trace"))), - Workload("test", fraction), - seed - ) + private fun createTestWorkload(fraction: Double, seed: Int = 0): List { + val source = trace("bitbrains-small").sampleByLoad(fraction) + return source.resolve(workloadLoader, Random(seed.toLong())) } /** diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet new file mode 100644 index 00000000..ee76d38f Binary files /dev/null and b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet differ diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet new file mode 100644 index 00000000..9b1cde13 Binary files /dev/null and b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet differ diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet deleted file mode 100644 index ee76d38f..00000000 Binary files a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/meta.parquet and /dev/null differ diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet deleted file mode 100644 index 9b1cde13..00000000 Binary files a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/trace.parquet and /dev/null differ diff --git a/opendc-experiments/opendc-experiments-radice/build.gradle.kts b/opendc-experiments/opendc-experiments-radice/build.gradle.kts deleted file mode 100644 index 0c716183..00000000 --- a/opendc-experiments/opendc-experiments-radice/build.gradle.kts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -description = "Experiments for the Risk Analysis work" - -/* Build configuration */ -plugins { - `experiment-conventions` - `testing-conventions` -} - -dependencies { - api(platform(projects.opendcPlatform)) - api(projects.opendcHarness.opendcHarnessApi) - implementation(projects.opendcFormat) - implementation(projects.opendcSimulator.opendcSimulatorCore) - implementation(projects.opendcSimulator.opendcSimulatorCompute) - implementation(projects.opendcCompute.opendcComputeSimulator) - implementation(projects.opendcTelemetry.opendcTelemetrySdk) - - implementation(libs.kotlin.logging) - implementation(libs.config) - implementation(libs.progressbar) - implementation(libs.clikt) - - implementation(libs.parquet) - testImplementation(libs.log4j.slf4j) -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 48183d71..1b518fee 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -28,15 +28,12 @@ import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.long import kotlinx.coroutines.* import mu.KotlinLogging -import org.opendc.compute.workload.ComputeWorkloadRunner -import org.opendc.compute.workload.grid5000 +import org.opendc.compute.workload.* import org.opendc.compute.workload.topology.HostSpec import org.opendc.compute.workload.topology.Topology import org.opendc.compute.workload.topology.apply -import org.opendc.compute.workload.trace.RawParquetTraceReader import org.opendc.compute.workload.util.PerformanceInterferenceReader import org.opendc.experiments.capelin.model.Workload -import org.opendc.experiments.capelin.trace.ParquetTraceReader import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.model.MachineModel @@ -136,13 +133,9 @@ class RunnerCli : CliktCommand(name = "runner") { logger.info { "Constructing performance interference model" } - val traceDir = File( - tracePath, - scenario.trace.traceId - ) - val traceReader = RawParquetTraceReader(traceDir) + val workloadLoader = ComputeWorkloadLoader(tracePath) val interferenceGroups = let { - val path = File(traceDir, "performance-interference-model.json") + val path = tracePath.resolve(scenario.trace.traceId).resolve("performance-interference-model.json") val operational = scenario.operationalPhenomena val enabled = operational.performanceInterferenceEnabled @@ -158,7 +151,7 @@ class RunnerCli : CliktCommand(name = "runner") { logger.info { "Starting repeat $repeat" } withTimeout(runTimeout * 1000) { val interferenceModel = interferenceGroups?.let { VmInterferenceModel(it, Random(repeat.toLong())) } - runRepeat(scenario, repeat, topology, traceReader, interferenceModel) + runRepeat(scenario, repeat, topology, workloadLoader, interferenceModel) } } @@ -174,7 +167,7 @@ class RunnerCli : CliktCommand(name = "runner") { scenario: Scenario, repeat: Int, topology: Topology, - traceReader: RawParquetTraceReader, + workloadLoader: ComputeWorkloadLoader, interferenceModel: VmInterferenceModel? ): WebComputeMonitor.Result { val monitor = WebComputeMonitor() @@ -188,15 +181,11 @@ class RunnerCli : CliktCommand(name = "runner") { val operational = scenario.operationalPhenomena val computeScheduler = createComputeScheduler(operational.schedulerName, seeder) + val workload = Workload(workloadName, trace(workloadName).sampleByLoad(workloadFraction)) - val trace = ParquetTraceReader( - listOf(traceReader), - Workload(workloadName, workloadFraction), - repeat - ) val failureModel = if (operational.failuresEnabled) - grid5000(Duration.ofDays(7), repeat) + grid5000(Duration.ofDays(7)) else null @@ -214,7 +203,7 @@ class RunnerCli : CliktCommand(name = "runner") { // Instantiate the topology onto the simulator simulator.apply(topology) // Run workload trace - simulator.run(trace) + simulator.run(workload.source.resolve(workloadLoader, seeder), seeder.nextLong()) } finally { simulator.close() metricReader.close() -- cgit v1.2.3 From 6b7929f7730d5031758878f2eb2e55b4904a477a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 17 Sep 2021 22:47:33 +0200 Subject: feat(trace): Add support for extended Bitbrains trace format This change adds support in the trace library for the extended Bitbrains format. This format is slightly different than the CSV format used by the original Bitbrains traces and contains more fields. --- .../compute/workload/trace/TraceConverter.kt | 4 +- .../workload/trace/sv/SvResourceStateTable.kt | 138 -------------- .../trace/sv/SvResourceStateTableReader.kt | 212 --------------------- .../opendc/compute/workload/trace/sv/SvTrace.kt | 45 ----- .../compute/workload/trace/sv/SvTraceFormat.kt | 47 ----- .../bitbrains/BitbrainsExResourceStateTable.kt | 138 ++++++++++++++ .../BitbrainsExResourceStateTableReader.kt | 212 +++++++++++++++++++++ .../org/opendc/trace/bitbrains/BitbrainsExTrace.kt | 45 +++++ .../trace/bitbrains/BitbrainsExTraceFormat.kt | 47 +++++ .../services/org.opendc.trace.spi.TraceFormat | 1 + .../trace/bitbrains/BitbrainsExTraceFormatTest.kt | 94 +++++++++ .../src/test/resources/vm.txt | 2 + 12 files changed, 541 insertions(+), 444 deletions(-) delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-bitbrains/src/test/resources/vm.txt diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt index bae7cb22..02666cc7 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt @@ -37,8 +37,8 @@ import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.compute.workload.trace.azure.AzureTraceFormat import org.opendc.compute.workload.trace.bp.BP_RESOURCES_SCHEMA import org.opendc.compute.workload.trace.bp.BP_RESOURCE_STATES_SCHEMA -import org.opendc.compute.workload.trace.sv.SvTraceFormat import org.opendc.trace.* +import org.opendc.trace.bitbrains.BitbrainsExTraceFormat import org.opendc.trace.bitbrains.BitbrainsTraceFormat import org.opendc.trace.util.parquet.LocalOutputFile import java.io.File @@ -79,7 +79,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { */ private val format by option("-f", "--format", help = "input format of trace") .choice( - "solvinity" to SvTraceFormat(), + "solvinity" to BitbrainsExTraceFormat(), "bitbrains" to BitbrainsTraceFormat(), "azure" to AzureTraceFormat() ) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt deleted file mode 100644 index 3ff69d36..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTable.kt +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.sv - -import org.opendc.trace.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.bufferedReader -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] in the extended Bitbrains format. - */ -internal class SvResourceStateTable(path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "txt" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_CLUSTER_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_NCPUS, - RESOURCE_STATE_CPU_CAPACITY, - RESOURCE_STATE_CPU_USAGE, - RESOURCE_STATE_CPU_USAGE_PCT, - RESOURCE_STATE_CPU_DEMAND, - RESOURCE_STATE_CPU_READY_PCT, - RESOURCE_STATE_MEM_CAPACITY, - RESOURCE_STATE_DISK_READ, - RESOURCE_STATE_DISK_WRITE, - ) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - } - - this.delegate = delegate - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { - return if (it.hasNext()) { - val (_, path) = it.next() - val reader = path.bufferedReader() - return SvResourceStateTableReader(reader) - } else { - null - } - } - - override fun toString(): String = "SvCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - val reader = path.bufferedReader() - return SvResourceStateTableReader(reader) - } - - override fun toString(): String = "SvResourceStateTable" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt deleted file mode 100644 index 487be950..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvResourceStateTableReader.kt +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.sv - -import org.opendc.trace.* -import java.io.BufferedReader -import java.time.Instant - -/** - * A [TableReader] for the Bitbrains resource state table. - */ -internal class SvResourceStateTableReader(private val reader: BufferedReader) : TableReader { - override fun nextRow(): Boolean { - reset() - - var line: String - var num = 0 - - while (true) { - line = reader.readLine() ?: return false - num++ - - if (line[0] == '#' || line.isBlank()) { - // Ignore empty lines or comments - continue - } - - break - } - - line = line.trim() - - val length = line.length - var col = 0 - var start: Int - var end = 0 - - while (end < length) { - // Trim all whitespace before the field - start = end - while (start < length && line[start].isWhitespace()) { - start++ - } - - end = line.indexOf(' ', start) - - if (end < 0) { - end = length - } - - val field = line.subSequence(start, end) as String - when (col++) { - COL_TIMESTAMP -> timestamp = Instant.ofEpochSecond(field.toLong(10)) - COL_CPU_USAGE -> cpuUsage = field.toDouble() - COL_CPU_DEMAND -> cpuDemand = field.toDouble() - COL_DISK_READ -> diskRead = field.toDouble() - COL_DISK_WRITE -> diskWrite = field.toDouble() - COL_CLUSTER_ID -> cluster = field.trim() - COL_NCPUS -> cpuCores = field.toInt(10) - COL_CPU_READY_PCT -> cpuReadyPct = field.toDouble() - COL_POWERED_ON -> poweredOn = field.toInt(10) == 1 - COL_CPU_CAPACITY -> cpuCapacity = field.toDouble() - COL_ID -> id = field.trim() - COL_MEM_CAPACITY -> memCapacity = field.toDouble() - } - } - - return true - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_CLUSTER_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_CAPACITY -> true - RESOURCE_STATE_CPU_USAGE -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_STATE_CPU_DEMAND -> true - RESOURCE_STATE_CPU_READY_PCT -> true - RESOURCE_STATE_MEM_CAPACITY -> true - RESOURCE_STATE_DISK_READ -> true - RESOURCE_STATE_DISK_WRITE -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_STATE_ID -> id - RESOURCE_STATE_CLUSTER_ID -> cluster - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) - RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) - RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) - RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) - RESOURCE_STATE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) - RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) - RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - return when (column) { - RESOURCE_STATE_POWERED_ON -> poweredOn - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_STATE_NCPUS -> cpuCores - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity - RESOURCE_STATE_CPU_USAGE -> cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity - RESOURCE_STATE_CPU_DEMAND -> cpuDemand - RESOURCE_STATE_MEM_CAPACITY -> memCapacity - RESOURCE_STATE_DISK_READ -> diskRead - RESOURCE_STATE_DISK_WRITE -> diskWrite - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - reader.close() - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var cluster: String? = null - private var timestamp: Instant? = null - private var cpuCores = -1 - private var cpuCapacity = Double.NaN - private var cpuUsage = Double.NaN - private var cpuDemand = Double.NaN - private var cpuReadyPct = Double.NaN - private var memCapacity = Double.NaN - private var diskRead = Double.NaN - private var diskWrite = Double.NaN - private var poweredOn: Boolean = false - - /** - * Reset the state of the reader. - */ - private fun reset() { - id = null - timestamp = null - cluster = null - cpuCores = -1 - cpuCapacity = Double.NaN - cpuUsage = Double.NaN - cpuDemand = Double.NaN - cpuReadyPct = Double.NaN - memCapacity = Double.NaN - diskRead = Double.NaN - diskWrite = Double.NaN - poweredOn = false - } - - /** - * Default column indices for the extended Bitbrains format. - */ - private val COL_TIMESTAMP = 0 - private val COL_CPU_USAGE = 1 - private val COL_CPU_DEMAND = 2 - private val COL_DISK_READ = 4 - private val COL_DISK_WRITE = 6 - private val COL_CLUSTER_ID = 10 - private val COL_NCPUS = 12 - private val COL_CPU_READY_PCT = 13 - private val COL_POWERED_ON = 14 - private val COL_CPU_CAPACITY = 18 - private val COL_ID = 19 - private val COL_MEM_CAPACITY = 20 -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt deleted file mode 100644 index 932c73ab..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTrace.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.sv - -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the extended Bitbrains format. - */ -public class SvTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name - - override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null - } - - return SvResourceStateTable(path) - } - - override fun toString(): String = "SvTrace[$path]" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt deleted file mode 100644 index ba673b5f..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/sv/SvTraceFormat.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.sv - -import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists - -/** - * A format implementation for the extended Bitbrains trace format. - */ -public class SvTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "sv" - - /** - * Open the trace file. - */ - override fun open(url: URL): SvTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return SvTrace(path) - } -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt new file mode 100644 index 00000000..4db2bace --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.bufferedReader +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] in the extended Bitbrains format. + */ +internal class BitbrainsExResourceStateTable(path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "txt" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_CLUSTER_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT, + RESOURCE_STATE_CPU_DEMAND, + RESOURCE_STATE_CPU_READY_PCT, + RESOURCE_STATE_MEM_CAPACITY, + RESOURCE_STATE_DISK_READ, + RESOURCE_STATE_DISK_WRITE, + ) + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (_, path) = it.next() + val reader = path.bufferedReader() + return BitbrainsExResourceStateTableReader(reader) + } else { + null + } + } + + override fun toString(): String = "SvCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + val reader = path.bufferedReader() + return BitbrainsExResourceStateTableReader(reader) + } + + override fun toString(): String = "BitbrainsExResourceStateTable" +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt new file mode 100644 index 00000000..6fe5d397 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import org.opendc.trace.* +import java.io.BufferedReader +import java.time.Instant + +/** + * A [TableReader] for the Bitbrains resource state table. + */ +internal class BitbrainsExResourceStateTableReader(private val reader: BufferedReader) : TableReader { + override fun nextRow(): Boolean { + reset() + + var line: String + var num = 0 + + while (true) { + line = reader.readLine() ?: return false + num++ + + if (line[0] == '#' || line.isBlank()) { + // Ignore empty lines or comments + continue + } + + break + } + + line = line.trim() + + val length = line.length + var col = 0 + var start: Int + var end = 0 + + while (end < length) { + // Trim all whitespace before the field + start = end + while (start < length && line[start].isWhitespace()) { + start++ + } + + end = line.indexOf(' ', start) + + if (end < 0) { + end = length + } + + val field = line.subSequence(start, end) as String + when (col++) { + COL_TIMESTAMP -> timestamp = Instant.ofEpochSecond(field.toLong(10)) + COL_CPU_USAGE -> cpuUsage = field.toDouble() + COL_CPU_DEMAND -> cpuDemand = field.toDouble() + COL_DISK_READ -> diskRead = field.toDouble() + COL_DISK_WRITE -> diskWrite = field.toDouble() + COL_CLUSTER_ID -> cluster = field.trim() + COL_NCPUS -> cpuCores = field.toInt(10) + COL_CPU_READY_PCT -> cpuReadyPct = field.toDouble() + COL_POWERED_ON -> poweredOn = field.toInt(10) == 1 + COL_CPU_CAPACITY -> cpuCapacity = field.toDouble() + COL_ID -> id = field.trim() + COL_MEM_CAPACITY -> memCapacity = field.toDouble() + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_CLUSTER_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_STATE_CPU_USAGE -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + RESOURCE_STATE_CPU_DEMAND -> true + RESOURCE_STATE_CPU_READY_PCT -> true + RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_STATE_DISK_READ -> true + RESOURCE_STATE_DISK_WRITE -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> id + RESOURCE_STATE_CLUSTER_ID -> cluster + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) + RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) + RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) + RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) + RESOURCE_STATE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) + RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) + RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + return when (column) { + RESOURCE_STATE_POWERED_ON -> poweredOn + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_STATE_NCPUS -> cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_STATE_CPU_USAGE -> cpuUsage + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity + RESOURCE_STATE_CPU_DEMAND -> cpuDemand + RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_STATE_DISK_READ -> diskRead + RESOURCE_STATE_DISK_WRITE -> diskWrite + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var cluster: String? = null + private var timestamp: Instant? = null + private var cpuCores = -1 + private var cpuCapacity = Double.NaN + private var cpuUsage = Double.NaN + private var cpuDemand = Double.NaN + private var cpuReadyPct = Double.NaN + private var memCapacity = Double.NaN + private var diskRead = Double.NaN + private var diskWrite = Double.NaN + private var poweredOn: Boolean = false + + /** + * Reset the state of the reader. + */ + private fun reset() { + id = null + timestamp = null + cluster = null + cpuCores = -1 + cpuCapacity = Double.NaN + cpuUsage = Double.NaN + cpuDemand = Double.NaN + cpuReadyPct = Double.NaN + memCapacity = Double.NaN + diskRead = Double.NaN + diskWrite = Double.NaN + poweredOn = false + } + + /** + * Default column indices for the extended Bitbrains format. + */ + private val COL_TIMESTAMP = 0 + private val COL_CPU_USAGE = 1 + private val COL_CPU_DEMAND = 2 + private val COL_DISK_READ = 4 + private val COL_DISK_WRITE = 6 + private val COL_CLUSTER_ID = 10 + private val COL_NCPUS = 12 + private val COL_CPU_READY_PCT = 13 + private val COL_POWERED_ON = 14 + private val COL_CPU_CAPACITY = 18 + private val COL_ID = 19 + private val COL_MEM_CAPACITY = 20 +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt new file mode 100644 index 00000000..f16c493d --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the extended Bitbrains format. + */ +public class BitbrainsExTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name + + override fun getTable(name: String): Table? { + if (!containsTable(name)) { + return null + } + + return BitbrainsExResourceStateTable(path) + } + + override fun toString(): String = "BitbrainsExTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt new file mode 100644 index 00000000..06388a84 --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the extended Bitbrains trace format. + */ +public class BitbrainsExTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "bitbrains-ex" + + /** + * Open the trace file. + */ + override fun open(url: URL): BitbrainsExTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return BitbrainsExTrace(path) + } +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat index f18135d0..fd6a2180 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat +++ b/opendc-trace/opendc-trace-bitbrains/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -1 +1,2 @@ org.opendc.trace.bitbrains.BitbrainsTraceFormat +org.opendc.trace.bitbrains.BitbrainsExTraceFormat diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt new file mode 100644 index 00000000..2e4f176a --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.bitbrains + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.* +import java.net.URL + +/** + * Test suite for the [BitbrainsExTraceFormat] class. + */ +class BitbrainsExTraceFormatTest { + private val format = BitbrainsExTraceFormat() + + @Test + fun testTraceExists() { + val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) + assertDoesNotThrow { + format.open(url) + } + } + + @Test + fun testTraceDoesNotExists() { + val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) + assertThrows { + format.open(URL(url.toString() + "help")) + } + } + + @Test + fun testTables() { + val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) + val trace = format.open(url) + + assertEquals(listOf(TABLE_RESOURCE_STATES), trace.tables) + } + + @Test + fun testTableExists() { + val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) + val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) + val trace = format.open(url) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + @Test + fun testSmoke() { + val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals(1631911500, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) }, + { assertEquals(21.2, reader.getDouble(RESOURCE_STATE_CPU_USAGE), 0.01) } + ) + + reader.close() + } +} diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/resources/vm.txt b/opendc-trace/opendc-trace-bitbrains/src/test/resources/vm.txt new file mode 100644 index 00000000..28bebb0c --- /dev/null +++ b/opendc-trace/opendc-trace-bitbrains/src/test/resources/vm.txt @@ -0,0 +1,2 @@ +1631911500 21.2 22.10 0.0 0.0 0.67 1.2 0.0 0.0 5 1 abc 1 0.01 1 10 0.0 0.0 2699 vm 4096 +1631911800 30.4 31.80 0.0 0.0 0.56 1.3 0.0 0.0 5 1 abc 1 0.02 1 10 0.0 0.0 2699 vm 4096 -- cgit v1.2.3 From 736aef9e56d149d54be16b735daf6784339071de Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 17 Sep 2021 23:04:00 +0200 Subject: feat(trace): Add support for Azure VM trace format This change adds support in the trace library for the Azure VM trace format. --- .../opendc-compute-workload/build.gradle.kts | 2 +- .../compute/workload/trace/TraceConverter.kt | 2 +- .../trace/azure/AzureResourceStateTable.kt | 127 ---------------- .../trace/azure/AzureResourceStateTableReader.kt | 149 ------------------ .../workload/trace/azure/AzureResourceTable.kt | 54 ------- .../trace/azure/AzureResourceTableReader.kt | 168 --------------------- .../compute/workload/trace/azure/AzureTrace.kt | 46 ------ .../workload/trace/azure/AzureTraceFormat.kt | 56 ------- opendc-trace/opendc-trace-azure/build.gradle.kts | 36 +++++ .../opendc/trace/azure/AzureResourceStateTable.kt | 127 ++++++++++++++++ .../trace/azure/AzureResourceStateTableReader.kt | 149 ++++++++++++++++++ .../org/opendc/trace/azure/AzureResourceTable.kt | 54 +++++++ .../opendc/trace/azure/AzureResourceTableReader.kt | 168 +++++++++++++++++++++ .../kotlin/org/opendc/trace/azure/AzureTrace.kt | 46 ++++++ .../org/opendc/trace/azure/AzureTraceFormat.kt | 56 +++++++ .../services/org.opendc.trace.spi.TraceFormat | 1 + .../org/opendc/trace/azure/AzureTraceFormatTest.kt | 113 ++++++++++++++ .../vm_cpu_readings-file-1-of-125.csv | 100 ++++++++++++ .../src/test/resources/trace/vmtable/vmtable.csv | 10 ++ settings.gradle.kts | 1 + 20 files changed, 863 insertions(+), 602 deletions(-) delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-azure/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt create mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt create mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt create mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt create mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt create mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-azure/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-azure/src/test/resources/trace/vm_cpu_readings/vm_cpu_readings-file-1-of-125.csv create mode 100644 opendc-trace/opendc-trace-azure/src/test/resources/trace/vmtable/vmtable.csv diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts index 390c7455..d67bbc66 100644 --- a/opendc-compute/opendc-compute-workload/build.gradle.kts +++ b/opendc-compute/opendc-compute-workload/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { api(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTrace.opendcTraceParquet) + implementation(projects.opendcTrace.opendcTraceAzure) implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) @@ -44,6 +45,5 @@ dependencies { implementation(libs.clikt) implementation(libs.jackson.databind) implementation(libs.jackson.module.kotlin) - implementation(libs.jackson.dataformat.csv) implementation(kotlin("reflect")) } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt index 02666cc7..20d0fef1 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt @@ -34,10 +34,10 @@ import org.apache.avro.generic.GenericRecordBuilder import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.compute.workload.trace.azure.AzureTraceFormat import org.opendc.compute.workload.trace.bp.BP_RESOURCES_SCHEMA import org.opendc.compute.workload.trace.bp.BP_RESOURCE_STATES_SCHEMA import org.opendc.trace.* +import org.opendc.trace.azure.AzureTraceFormat import org.opendc.trace.bitbrains.BitbrainsExTraceFormat import org.opendc.trace.bitbrains.BitbrainsTraceFormat import org.opendc.trace.util.parquet.LocalOutputFile diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt deleted file mode 100644 index 32843595..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTable.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] for the Azure v1 VM traces. - */ -internal class AzureResourceStateTable(private val factory: CsvFactory, path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_CPU_USAGE_PCT - ) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - } - - this.delegate = delegate - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { - return if (it.hasNext()) { - val (_, path) = it.next() - return AzureResourceStateTableReader(factory.createParser(path.toFile())) - } else { - null - } - } - - override fun toString(): String = "AzureCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - return AzureResourceStateTableReader(factory.createParser(path.toFile())) - } - - override fun toString(): String = "AzureResourceStateTable" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt deleted file mode 100644 index ded9d4d6..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceStateTableReader.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.azure - -import com.fasterxml.jackson.core.JsonToken -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import org.opendc.trace.* -import java.time.Instant - -/** - * A [TableReader] for the Azure v1 VM resource state table. - */ -internal class AzureResourceStateTableReader(private val parser: CsvParser) : TableReader { - init { - parser.schema = schema - } - - override fun nextRow(): Boolean { - reset() - - if (!nextStart()) { - return false - } - - while (true) { - val token = parser.nextValue() - - if (token == null || token == JsonToken.END_OBJECT) { - break - } - - when (parser.currentName) { - "timestamp" -> timestamp = Instant.ofEpochSecond(parser.longValue) - "vm id" -> id = parser.text - "avg cpu" -> cpuUsagePct = parser.doubleValue - } - } - - return true - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_STATE_ID -> id - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - throw IllegalArgumentException("Invalid column") - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - parser.close() - } - - /** - * Advance the parser until the next object start. - */ - private fun nextStart(): Boolean { - var token = parser.nextValue() - - while (token != null && token != JsonToken.START_OBJECT) { - token = parser.nextValue() - } - - return token != null - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var timestamp: Instant? = null - private var cpuUsagePct = Double.NaN - - /** - * Reset the state. - */ - private fun reset() { - id = null - timestamp = null - cpuUsagePct = Double.NaN - } - - companion object { - /** - * The [CsvSchema] that is used to parse the trace. - */ - private val schema = CsvSchema.builder() - .addColumn("timestamp", CsvSchema.ColumnType.NUMBER) - .addColumn("vm id", CsvSchema.ColumnType.STRING) - .addColumn("CPU min cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU max cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("CPU avg cpu", CsvSchema.ColumnType.NUMBER) - .setAllowComments(true) - .build() - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt deleted file mode 100644 index 2bed7725..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTable.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * The resource [Table] for the Azure v1 VM traces. - */ -internal class AzureResourceTable(private val factory: CsvFactory, private val path: Path) : Table { - override val name: String = TABLE_RESOURCES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_START_TIME, - RESOURCE_STOP_TIME, - RESOURCE_NCPUS, - RESOURCE_MEM_CAPACITY - ) - - override fun newReader(): TableReader { - return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("No partition $partition") - } - - override fun toString(): String = "AzureResourceTable" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt deleted file mode 100644 index 108ce4ed..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureResourceTableReader.kt +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.azure - -import com.fasterxml.jackson.core.JsonToken -import com.fasterxml.jackson.dataformat.csv.CsvParser -import com.fasterxml.jackson.dataformat.csv.CsvSchema -import org.opendc.trace.* -import java.time.Instant - -/** - * A [TableReader] for the Azure v1 VM resources table. - */ -internal class AzureResourceTableReader(private val parser: CsvParser) : TableReader { - init { - parser.schema = schema - } - - override fun nextRow(): Boolean { - reset() - - if (!nextStart()) { - return false - } - - while (true) { - val token = parser.nextValue() - - if (token == null || token == JsonToken.END_OBJECT) { - break - } - - when (parser.currentName) { - "vm id" -> id = parser.text - "vm created" -> startTime = Instant.ofEpochSecond(parser.longValue) - "vm deleted" -> stopTime = Instant.ofEpochSecond(parser.longValue) - "vm virtual core count" -> cpuCores = parser.intValue - "vm memory" -> memCapacity = parser.doubleValue * 1e6 // GB to KB - } - } - - return true - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> id - RESOURCE_START_TIME -> startTime - RESOURCE_STOP_TIME -> stopTime - RESOURCE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_NCPUS -> cpuCores - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_MEM_CAPACITY -> memCapacity - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - parser.close() - } - - /** - * Advance the parser until the next object start. - */ - private fun nextStart(): Boolean { - var token = parser.nextValue() - - while (token != null && token != JsonToken.START_OBJECT) { - token = parser.nextValue() - } - - return token != null - } - - /** - * State fields of the reader. - */ - private var id: String? = null - private var startTime: Instant? = null - private var stopTime: Instant? = null - private var cpuCores = -1 - private var memCapacity = Double.NaN - - /** - * Reset the state. - */ - fun reset() { - id = null - startTime = null - stopTime = null - cpuCores = -1 - memCapacity = Double.NaN - } - - companion object { - /** - * The [CsvSchema] that is used to parse the trace. - */ - private val schema = CsvSchema.builder() - .addColumn("vm id", CsvSchema.ColumnType.NUMBER) - .addColumn("subscription id", CsvSchema.ColumnType.STRING) - .addColumn("deployment id", CsvSchema.ColumnType.NUMBER) - .addColumn("timestamp vm created", CsvSchema.ColumnType.NUMBER) - .addColumn("timestamp vm deleted", CsvSchema.ColumnType.NUMBER) - .addColumn("max cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("avg cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("p95 cpu", CsvSchema.ColumnType.NUMBER) - .addColumn("vm category", CsvSchema.ColumnType.NUMBER) - .addColumn("vm virtual core count", CsvSchema.ColumnType.NUMBER) - .addColumn("vm memory", CsvSchema.ColumnType.NUMBER) - .setAllowComments(true) - .build() - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt deleted file mode 100644 index 93c2210b..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTrace.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the Azure v1 VM traces. - */ -public class AzureTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = name in tables - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> AzureResourceTable(factory, path) - TABLE_RESOURCE_STATES -> AzureResourceStateTable(factory, path) - else -> null - } - } - - override fun toString(): String = "AzureTrace[$path]" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt deleted file mode 100644 index d400e1da..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/azure/AzureTraceFormat.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import com.fasterxml.jackson.dataformat.csv.CsvParser -import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists - -/** - * A format implementation for the Azure v1 format. - */ -public class AzureTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "azure-v1" - - /** - * The [CsvFactory] used to create the parser. - */ - private val factory = CsvFactory() - .enable(CsvParser.Feature.ALLOW_COMMENTS) - .enable(CsvParser.Feature.TRIM_SPACES) - - /** - * Open the trace file. - */ - override fun open(url: URL): AzureTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return AzureTrace(factory, path) - } -} diff --git a/opendc-trace/opendc-trace-azure/build.gradle.kts b/opendc-trace/opendc-trace-azure/build.gradle.kts new file mode 100644 index 00000000..8bde56cb --- /dev/null +++ b/opendc-trace/opendc-trace-azure/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for Azure VM traces in OpenDC" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) + implementation(libs.jackson.dataformat.csv) +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt new file mode 100644 index 00000000..189ab52a --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +/** + * The resource state [Table] for the Azure v1 VM traces. + */ +internal class AzureResourceStateTable(private val factory: CsvFactory, path: Path) : Table { + /** + * The partitions that belong to the table. + */ + private val partitions = Files.walk(path.resolve("vm_cpu_readings"), 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + + override val name: String = TABLE_RESOURCE_STATES + + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_CPU_USAGE_PCT + ) + + override fun newReader(): TableReader { + val it = partitions.iterator() + + return object : TableReader { + var delegate: TableReader? = nextDelegate() + + override fun nextRow(): Boolean { + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextDelegate() + } + + this.delegate = delegate + return delegate != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false + + override fun get(column: TableColumn): T { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(column) + } + + override fun getBoolean(column: TableColumn): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(column) + } + + override fun getInt(column: TableColumn): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(column) + } + + override fun getLong(column: TableColumn): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(column) + } + + override fun getDouble(column: TableColumn): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(column) + } + + override fun close() { + delegate?.close() + } + + private fun nextDelegate(): TableReader? { + return if (it.hasNext()) { + val (_, path) = it.next() + return AzureResourceStateTableReader(factory.createParser(path.toFile())) + } else { + null + } + } + + override fun toString(): String = "AzureCompositeTableReader" + } + } + + override fun newReader(partition: String): TableReader { + val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } + return AzureResourceStateTableReader(factory.createParser(path.toFile())) + } + + override fun toString(): String = "AzureResourceStateTable" +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt new file mode 100644 index 00000000..c17a17ab --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Azure v1 VM resource state table. + */ +internal class AzureResourceStateTableReader(private val parser: CsvParser) : TableReader { + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "timestamp" -> timestamp = Instant.ofEpochSecond(parser.longValue) + "vm id" -> id = parser.text + "CPU avg cpu" -> cpuUsagePct = parser.doubleValue + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_CPU_USAGE_PCT -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_STATE_ID -> id + RESOURCE_STATE_TIMESTAMP -> timestamp + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + throw IllegalArgumentException("Invalid column") + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var timestamp: Instant? = null + private var cpuUsagePct = Double.NaN + + /** + * Reset the state. + */ + private fun reset() { + id = null + timestamp = null + cpuUsagePct = Double.NaN + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("timestamp", CsvSchema.ColumnType.NUMBER) + .addColumn("vm id", CsvSchema.ColumnType.STRING) + .addColumn("CPU min cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU max cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("CPU avg cpu", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .build() + } +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt new file mode 100644 index 00000000..d9f6f156 --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * The resource [Table] for the Azure v1 VM traces. + */ +internal class AzureResourceTable(private val factory: CsvFactory, private val path: Path) : Table { + override val name: String = TABLE_RESOURCES + + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_NCPUS, + RESOURCE_MEM_CAPACITY + ) + + override fun newReader(): TableReader { + return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("No partition $partition") + } + + override fun toString(): String = "AzureResourceTable" +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt new file mode 100644 index 00000000..d3970b07 --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.dataformat.csv.CsvParser +import com.fasterxml.jackson.dataformat.csv.CsvSchema +import org.opendc.trace.* +import java.time.Instant + +/** + * A [TableReader] for the Azure v1 VM resources table. + */ +internal class AzureResourceTableReader(private val parser: CsvParser) : TableReader { + init { + parser.schema = schema + } + + override fun nextRow(): Boolean { + reset() + + if (!nextStart()) { + return false + } + + while (true) { + val token = parser.nextValue() + + if (token == null || token == JsonToken.END_OBJECT) { + break + } + + when (parser.currentName) { + "vm id" -> id = parser.text + "vm created" -> startTime = Instant.ofEpochSecond(parser.longValue) + "vm deleted" -> stopTime = Instant.ofEpochSecond(parser.longValue) + "vm virtual core count" -> cpuCores = parser.intValue + "vm memory" -> memCapacity = parser.doubleValue * 1e6 // GB to KB + } + } + + return true + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_STOP_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val res: Any? = when (column) { + RESOURCE_ID -> id + RESOURCE_START_TIME -> startTime + RESOURCE_STOP_TIME -> stopTime + RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + return when (column) { + RESOURCE_NCPUS -> cpuCores + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + return when (column) { + RESOURCE_MEM_CAPACITY -> memCapacity + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + parser.close() + } + + /** + * Advance the parser until the next object start. + */ + private fun nextStart(): Boolean { + var token = parser.nextValue() + + while (token != null && token != JsonToken.START_OBJECT) { + token = parser.nextValue() + } + + return token != null + } + + /** + * State fields of the reader. + */ + private var id: String? = null + private var startTime: Instant? = null + private var stopTime: Instant? = null + private var cpuCores = -1 + private var memCapacity = Double.NaN + + /** + * Reset the state. + */ + fun reset() { + id = null + startTime = null + stopTime = null + cpuCores = -1 + memCapacity = Double.NaN + } + + companion object { + /** + * The [CsvSchema] that is used to parse the trace. + */ + private val schema = CsvSchema.builder() + .addColumn("vm id", CsvSchema.ColumnType.NUMBER) + .addColumn("subscription id", CsvSchema.ColumnType.STRING) + .addColumn("deployment id", CsvSchema.ColumnType.NUMBER) + .addColumn("timestamp vm created", CsvSchema.ColumnType.NUMBER) + .addColumn("timestamp vm deleted", CsvSchema.ColumnType.NUMBER) + .addColumn("max cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("avg cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("p95 cpu", CsvSchema.ColumnType.NUMBER) + .addColumn("vm category", CsvSchema.ColumnType.NUMBER) + .addColumn("vm virtual core count", CsvSchema.ColumnType.NUMBER) + .addColumn("vm memory", CsvSchema.ColumnType.NUMBER) + .setAllowComments(true) + .build() + } +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt new file mode 100644 index 00000000..c7e7dc36 --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import org.opendc.trace.* +import java.nio.file.Path + +/** + * [Trace] implementation for the Azure v1 VM traces. + */ +public class AzureTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = name in tables + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_RESOURCES -> AzureResourceTable(factory, path) + TABLE_RESOURCE_STATES -> AzureResourceStateTable(factory, path) + else -> null + } + } + + override fun toString(): String = "AzureTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt new file mode 100644 index 00000000..1230d857 --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import com.fasterxml.jackson.dataformat.csv.CsvFactory +import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A format implementation for the Azure v1 format. + */ +public class AzureTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "azure" + + /** + * The [CsvFactory] used to create the parser. + */ + private val factory = CsvFactory() + .enable(CsvParser.Feature.ALLOW_COMMENTS) + .enable(CsvParser.Feature.TRIM_SPACES) + + /** + * Open the trace file. + */ + override fun open(url: URL): AzureTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return AzureTrace(factory, path) + } +} diff --git a/opendc-trace/opendc-trace-azure/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-azure/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..08e75529 --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.azure.AzureTraceFormat diff --git a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt new file mode 100644 index 00000000..20375547 --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.azure + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.* +import java.io.File +import java.net.URL + +/** + * Test suite for the [AzureTraceFormat] class. + */ +class AzureTraceFormatTest { + private val format = AzureTraceFormat() + + @Test + fun testTraceExists() { + val url = File("src/test/resources/trace").toURI().toURL() + assertDoesNotThrow { + format.open(url) + } + } + + @Test + fun testTraceDoesNotExists() { + val url = File("src/test/resources/trace").toURI().toURL() + assertThrows { + format.open(URL(url.toString() + "help")) + } + } + + @Test + fun testTables() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) + } + + @Test + fun testTableExists() { + val url = File("src/test/resources/trace").toURI().toURL() + val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + @Test + fun testResources() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("x/XsOfHO4ocsV99i4NluqKDuxctW2MMVmwqOPAlg4wp8mqbBOe3wxBlQo0+Qx+uf", reader.get(RESOURCE_ID)) }, + { assertEquals(1, reader.getInt(RESOURCE_NCPUS)) }, + { assertEquals(1750000.0, reader.getDouble(RESOURCE_MEM_CAPACITY)) }, + ) + + reader.close() + } + + @Test + fun testSmoke() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("+ZcrOp5/c/fJ6mVgP5qMZlOAGDwyjaaDNM0WoWOt2IDb47gT0UwK9lFwkPQv3C7Q", reader.get(RESOURCE_STATE_ID)) }, + { assertEquals(0, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) }, + { assertEquals(2.86979, reader.getDouble(RESOURCE_STATE_CPU_USAGE_PCT), 0.01) } + ) + + reader.close() + } +} diff --git a/opendc-trace/opendc-trace-azure/src/test/resources/trace/vm_cpu_readings/vm_cpu_readings-file-1-of-125.csv b/opendc-trace/opendc-trace-azure/src/test/resources/trace/vm_cpu_readings/vm_cpu_readings-file-1-of-125.csv new file mode 100644 index 00000000..db6ddf8a --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/test/resources/trace/vm_cpu_readings/vm_cpu_readings-file-1-of-125.csv @@ -0,0 +1,100 @@ +0,+ZcrOp5/c/fJ6mVgP5qMZlOAGDwyjaaDNM0WoWOt2IDb47gT0UwK9lFwkPQv3C7Q,2.052803,3.911587,2.86979 +0,2zrgeOqUDy+l0GVi5NXudU+3sqZH+nLowfcz+D/JsCymTXbKrRf1Hr3OjAtxjnKm,1.64695,8.794403,3.254472 +0,/34Wh1Kq/qkNkW0tQrMiQ1eZ8hg9hHopydCzsXriefhgrn+0Rg1j22k1IHcV6PIQ,2.440088,6.941048,4.33624 +0,2lzdXk1Rqn1ibH2kZhGamYTMvVcRP6+x8b5zGiD/8t++5BQhzU18hGaL5sfR01Lo,0.302992,2.046712,0.970692 +0,0GrUQuLhCER5bWWcoJAgblPJWkaU4v3nf+NUrZnFTlXWEK99qgTRBTkjjUjJVAqA,1.515922,4.471657,2.438805 +0,2I8OpI6bMkdzL3HYLz4KlBcDhy2VTEm3skQbOvEo9rLoxryB0iB9iVh3rGd5DW2j,0.148552,0.315007,0.264341 +0,2IuuDcRMd97gln/+CrgPqI/fwffx67s87T1odKrA0wLYf8YuzGooHdKihitv2Q+s,0.169838,2.277277,0.859669 +0,2KaB1faO0ZB2KqB8MGwasWkqRLJHIE6+2wPuhzlzLNEUyeGzo0dU7brFa/cll/VJ,0.539162,1.371926,0.782212 +0,2BMVXt472mr/Y8m1vaaGoyGTSXcLvXk968PCHixwCDjPSgCm7yYSimGuBw7VPIiS,3.625195,7.211996,4.807884 +0,/3+EY60PnzKwod6nAUGBFSDDpBBOVEVUi90JWWWjPAlNyTUrGwlfQcSDoSkRumD7,0.180582,1.313473,0.43792 +0,+hulsuci78MKSG60G/gHJLqmz5/TFEB3WpS6HI1G1mm052le8oeemF3kz3eoPsnS,2.653344,9.983403,4.262461 +0,0O4otykohyRcsqqsg68kqo6ZCY6sL6eQLHUMYZxGVRhwQmTXRUN89izib3pOucrC,0.72983,4.516831,1.846142 +0,239KfRqrlUdyYuU0ubcASPKztu3q7hernahrolO5AczjUFI/QgoU+OoKzPuivFHQ,1.42953,11.553488,4.271241 +0,/SVzWHvPhr7KAIOUFr10EK8WdKXbrJojgcc4IGvutJ2S6HpRMD0zTfv/h0720+Q6,1.676634,6.703915,3.102252 +0,2a7bYEHqZvcgOeos5Q3J5qxpY4lXinv8M9mORfel5DlWRut0JynZtobNGNlBWn41,0.54178,8.239316,2.234877 +0,1NwFYwEAgv8qnCaWzzWv9hHj0TIJAZ2HT+iH+dsZKeSAPGoJGyVSDB+Zj4EuqWRC,2.933124,4.630701,3.975568 +0,3rg4SRyS/p6eMuGCJpjkz4oHzXSeeF16a7jJ9GAAYPiAQAsQNOEjHOe07on5RbjK,0.719536,3.383279,1.506528 +0,0DVV+uR/jr4XbwYQhVf2Yg0Kg7DfIDa7qJNzqvjVgEqGRJAUisrnYFv7AWr1k7by,0.949333,22.157649,3.751856 +0,3bHtb6EIFo9yXByIhpVDOJ7bzbIQvnGGb+jm8eOsEf0eKbrKMJvUiOYc6Wq3DXbR,3.504534,15.581505,6.388424 +0,0O5yc/ZVSHWxf4UHf/1b8Nut9raakorgqDwGV9k7TJdq55alNeMDB7CREuxZystP,7.587743,20.323464,16.540802 +0,0ZbYi+cMH7hCzT+8ICYVp5ZgcRUFNKsODuH09bbPdPioUPCPkBK2PM2oHhE3y4I6,2.694185,6.361789,4.55337 +0,1jw70sEl89jY2iRpd38PuYSBiOcuwe6tF4Q+YuGBJg20+gRIW3A7H3WZ+uL0EVmb,3.570395,5.707428,4.233997 +0,24MvpVXzcNO2qxwF4hMwCToFTBfoAE5xUQ4L6fwfWuBZ1GW06hHh5jWwWCu+8lPm,5.102273,8.678012,6.369649 +0,2gHzFAqM+fL7f1wtNETuzSoM7I6xlEWk2BJmj1SNXly/7z1RQFmwYRXU49DiYciJ,0.27374,54.447146,5.445003 +0,/hCom+lGMIkeE1wQi+VTFh+zzgbikbO0jQDzchDMCUNSgo6cEJfD1sIT2Ok4NlD6,0.170892,1.843549,0.737087 +0,2UwesOu8HXTdHyj0jd1agckz1KH5+Z4KOFe+wKFo9uvRI4GalozAPaxsMrBmx7Wo,3.349887,6.272554,4.425039 +0,1V8Fr/ZhjQcxql5s9p3hA1b0Wx6Sx9e+np1OImlp3GKyleH87bYjmQLZJouKYJR2,2.022219,4.724097,2.616506 +0,23E/SPMZKCUWz8nBmuCdbNBWf9ou6IQuZjmh0x2/icPrbLLvUk5SvbTjwqoLQxBX,0,0.46365,0.178483 +0,0Mj8nT0fnkeMIbcTBf27pOtUuTtMZH8uAZqAViSaye+9mBIjsNPmU6Z5hLK6f2I0,15.023186,23.297875,18.965327 +0,2xM0uOcqSowNzsbFbzhy5J1Ms2vv0jVQ5aM+J2E/LCBzTVKPrCCeWQ/r/cKmS1Tm,8.272075,9.415241,8.797159 +0,0MYQXyW75q9UURkn+O/V6iww0JaBl2qRG0Mh2bqRcuU5/Ws+7HJMPKSzVKlUEgcU,3.798828,8.915124,4.856879 +0,/HQfnMjgclpCxPod9jmGVQxfTnsjyNWA4KNkLMn4IKRlqheUo9AhhWv4vAumZNqg,4.788548,7.269977,6.640435 +0,0Q2PP+9O7LcnNI7AJQQR7pwM4ISG4024Z+INOw+TWgf2DCl8/prdGC7QJRGjc+Aa,0.10703,0.183798,0.136907 +0,/zLQxB1DGXC7iK7JeyYrUSguf6DjNA1MVTJzieRWmcobm0M+xgd28r842y3p5u5J,1.306953,3.22913,2.226509 +0,42cXpXkVqdXH/ok/tD46zKKCToy0k6HXoH3x7eeo4+zIva3IJKle5xfSEW3R45ON,1.018462,3.240817,2.196357 +0,+9HYwMx1Ckj15bJswEycBgiBSfrBw5NJE3p86IeFpFYKKxdw3NzMPTFKpg67XhsF,1.859664,7.255261,3.501303 +0,10KKTL95cApo6Pf24KZqgrM67v4M6rgZBoX+w/I3j4KS66FNhKomGnap9H8SVAvy,0.041225,2.593651,0.25894 +0,+LyaeKb1faiLEjAzynXF3xO/ZAho1R/Zyh1H4d45+NGsIJR6ryUTDmhyNvMh1wQ9,4.614357,11.692623,6.05005 +0,1SS5EeD9rxdWRFYBkR36PAd96w+Q7V2V4fDcc/2IJ1L07In7RGpQk/HVcOTKd78w,0.020435,0.515471,0.135453 +0,+HFoxb6Eu9kwzVkxs+A+9Q7zXa4aSIcOFm3AnYDCTQQMYyf6EST9nSHslGhUkgAD,8.53904,48.459572,16.166212 +0,+N+B5FPJIUVyH9v1Zcc+kjSTNvULkosDBM48N2JkDjhuVhQtWSfYQMQTQkGeVjLi,3.139119,99.036916,51.090982 +0,1ey9c7Hc1FyxLVbESoty7AkXbuENFSDXRAZiizFifRmJNM6IEx9eNu3bkUR+qCUJ,2.466582,5.842213,3.765056 +0,35F/52yPsKPGondM8xnzX68EKiKiKiZMDqsVnvc9ZOAc/rS3zvQ6YYj3QkLAHFhN,1.963258,43.494868,16.459037 +0,2KX+BTc0TPZOtCgbzKtKvP1yrM+Cc3WQU9DPkZDFD/5aNN/aPV40aQCKwW/HeTzh,1.040522,5.961609,3.305858 +0,+8X+qRHRLwwgj70uuXrkus7lrNtjMeTHfy5yQgymNJI+yFd5pbhRfStfS7lkVOhP,0.436353,15.995153,1.431229 +0,/g5MAtFnYaMO5MpJg40BsFmhS22s0tfwHiivGhPbcZ+KgEAtNxKkFdZYDtrDUUFO,6.905489,8.196952,7.527238 +0,/ke0seVq80UFQeXSTUh5hTrjghtn5qqWf38lQVTis+/ZR6Pdv5vdAotz4dvZcKDp,6.444482,23.136676,15.470455 +0,+tQeKqKqbAui7YXK0Efk3GUnvbzM+0pOpmOJ6OhkMSozjRyl5tHl7+mZwFznU3Mk,17.90259,20.095464,18.937014 +0,/hiC5yD45GhNtMpJTVwVF5ZnNNWfEHttESv/+KH6go9FBoncns+CuQ1M92c0xzFA,2.290396,2.609893,2.523336 +0,0i9+1LVd2t4m1KScDuoJnAAEL0bz9UGXh2iLAGV/8Eq5hTsAliyraV7j6wsf2MZX,4.266491,16.607137,6.929279 +0,2PVcv0/vy8mIjzH7CiB9cJU737jRi6kAO7PhqkxEWA4GrxvaCsK3ZDckhD8YR04U,1.048596,2.309172,1.447266 +0,/kbT+MIfY7jEW2Nn+TKf5BKkLAmBslDqKuZ8HI2Ire6eMKinGP7aTt6SY77vt8PK,2.409783,7.79851,5.552826 +0,2cCRKSXs9v9tPskjJn8UmV15qynI3I3GLPTor/i81nxh5Ocwb7Fq1zwEN5zmtXyx,0.356014,1.468193,0.781642 +0,2qsVNbcvPD0H3cs/p/6MTpuvUBtr5QN3iavAmkCQBCtrHcEpgskYVJf/6WQkEhOF,2.688901,85.501739,37.676562 +0,30FpxnoytvMKoGeJYqwnuL2mPbvKlxpjPIfVT8LKqqFl9smEksQjEzG3lgxhT4U7,2.499018,6.534664,3.508567 +0,/f1C+4xtoPaBxD+FoFdM52MiaWXZEqPqSnBxz4q4XMzoXabJvdddHchLrxc6SlYc,1.894231,15.683948000000001,3.199591 +0,30tz9NOV1bIKUB6uIOy4qZT8BVk3escZ0bWXBD9oedOQN1Qi06pplm7WM9iMvvvL,0.959278,63.599827,14.983399 +0,2q0sA6/4VZfksnucqVASzYgruD9T0219afuGrf3O/u8jpGHpn0k3oWvY35I7x8F/,2.694575,11.900751,5.254742 +0,/Qq/SKTnRJ4RZPWKIdCyPmYQUf+csOcFYS+rVD+kc1OkLboeKHK7CLV88wVVLlm9,55.553347,99.204744,93.215797 +0,2PJIXiy3/m1MNf4SQAQ9xU+LDqsHvyyCIWA2X0nB9kgLyVNh3g9xxpAeUpkXgvK6,0.591771,0.676084,0.628958 +0,/VIH23Tzi+711eCdsc7apDAoSBY6hcNqCu8oaZcPrUQmUXUyH8HJS7Z1DyhR6j/I,3.136726,5.477124,4.036594 +0,3/bNFRCZog1M2qwSCcwMYYos07f/9kRsfeFyaOmT0mNx3ldbNvRRbMBhoseq0DIg,2.993954,5.787727,4.272684 +0,3F+42xbLAiVPTJeHpyDwx6ZXcxArLFiMGGZTa9jmsLIpxxkBqC1QwN8mAwzDqWsU,3.488578,6.178318,4.692753 +0,08iqvtN8ilXeJdfiL86fde5JRTrjuLTp8guNabblV7QqkkAL23TwtLdwuFtg4P9G,3.64316,22.992153,10.256498 +0,0ZiQ/5P4mgnYud0uaI1lZCIJaCzrlEJdnAz8bcFMLDFryCrUJJDecbWQbLo6K69J,2.924592,4.261972,3.543138 +0,28JHlDFu72v9lIhjKLF+h9g1pyPq9+ruVET8NnBGKksclnvwx0WlQ066nh6doanS,1.2833,1.589682,1.353967 +0,3ClcWgHBEw8WzFSqnMYKUib9Abx6RDf3ITN8ivUilopa4t+UTJU0Y/U25sT/1okS,1.387814,2.764987,2.116221 +0,/qj8bL8dARqa83U6HwU/bUF5kLq12PKaebM0/2WrM2a3oH+BCC/IxFf1PjIWBNC5,23.139855,97.95723,75.918613 +0,17KWFIkHqLQpslptyD70Qof2iISdFN4IzZBc/WffQeds/tDjuZ/1O4KY68u10srE,2.374392,4.461708,3.201956 +0,3fNyZ1Bf9hUvTVDbHwh8Fh3E2i0BgPPL3QkkS9T0cjanDQA0u0z/Y5TSdXldEJM8,1.199056,3.188352,2.14033 +0,3DYNNYBvhBlVPHsg1uoo7ZVjKX5k1c0gZsfc8W0o0cJ1WJAI8f049TnSu/yIfp/m,1.305688,4.700476,2.216015 +0,2e9qO7smv0DTuXeR3VEzG2jztbM9wntJ3bMt6/LlN3RZBQzIY9vP7FFsphJC9bsW,0.087859,22.556549,10.203507 +0,3EeP6Vgbh292ahLWQJrInzehyR4Nuj2vNtdWuEbvFjKcmCc2i6VZVN4dQTRfIVxR,7.663198,22.199953,15.461753 +0,/Vi7oNg70eAzJHXwsCM9nzwBMg4l7cMyZhUT14V48AWjIAQzVYsbdI0KwNlBAXhK,0.61977,2.24158,1.181003 +0,4/c7nkT3SrtRRrRCsZxUJXxJjUr61iivwZxdihwPAtpCDUawKfPUzaq/05zFYBAk,2.667104,7.383679,4.050989 +0,1HYzfmk+s4SedWtOeHk4j5Zj52ateGX5bRFK5K3rwTVdB2A2m+3iwbL1IEzx8ir8,5.366892,12.404488,6.877072 +0,3vPq2HsXQ9SQT+URugEaQ3ezvstcGd5Bt9FIiFx1SrUfUrvvi/Gj8Nyw5DZhvyAR,3.014601,13.363316,4.535414 +0,2YbmUab2MqBMpvMaoaMP3zVxOhgqkNytraWdt/GG261oZ/tmgEB239WsbKJh1bE3,3.121409,98.73306,51.009852 +0,1IYQhDD8NGuAFnVPnffmt1yk20B9JHQI5DMC4Ny09pe6Sedik6YCIIVeBHIEo34W,1.512222,3.53396,2.379989 +0,1SSMSUcJ7qKM7q2yka80+ZP0yYWiYxGQxcJ8KBi4+TsDpv5FLUS6i2DHLMtXB3An,3.9704,4.345802,4.126586 +0,17CA6zpUCxW+Pdh2g5W0kTdlPlgWbBKz4YrHvbGP/Hmf13nZQBc/VZO7EL6nM75C,8.052588,16.023168,13.600106 +0,04rwScmEvRr0aU/mAE7aKtKFwowolGaTAPyQHuaVKEFmEVMAKxo+7UBCk3vRRRBd,2.221999,5.809178,3.021269 +0,1H9K/TW4c28Aob/H1O53cyQT7pHRww0L1ocyn19z1+MxC+k+5M/PgEx9B3zT/CNf,2.985884,7.584636,3.995057 +0,2fgXOaNZld/i7o20ULRNhCeL+o+vgZYzDOIhQ2n28TcGxXR047+F1b7QiD+l1Ypf,0.068074,0.884132,0.239792 +0,+0bAvqEMTl/RGyFmuz4zJH3DLMI6Q+iHapYn5BpbZI+0PNNfM7PXm/mojw+e8Xpn,3.238927,4.259525,3.611511 +0,3OdFPkhA5Q99wyfxmgyxPAhWyDLkV++XFtPL8pD3w5f8mBWbokeBwgk4gmNIxCOL,0.461767,10.466777,4.985617 +0,0UE8gxQAdCGY+WGN9yd9CL2ZGGqoyGQ2PzQGndwecce24GyTUnuvREbnMWBZZ7bG,0.730279,6.785359,3.363408 +0,/Uk/U5u4d+KNQVPD63pklfxeWc2zDAkUnrVmvxgRTuqNFbn90h8TuU5GZ+OamGQ5,0.105853,1.739301,0.262678 +0,2im96EJfLyxm7TPrtOR9m6Inq4E4/qR+AvP0TbnSdvzXI+N9gHh7C2fzppzcR0i8,0.325895,2.012216,0.802437 +0,+CrXBNhT3ch1hYU2e9IGs7wfjSLRkKYgidJYc42LlsH39cYtwdAX3wKm1OGlf+Kl,18.815771,40.850218,22.470045 +0,/hXRrrjPrAw8xDSsJnEwLdkRN1e42zJLE/HO5DXk5gbGLRmRx5H9n4T0UmraZ8uW,0.361838,0.831517,0.423214 +0,/sTadDDv8poFeLWS7lD/SEtEgWCBHXB1IaiitjCru4AcK8Z32hNXlccdY8hlFzTp,3.203254,5.682829,3.859569 +0,333YaK054AGlUYuw0XWxYn5K8NwzhfzJ3mm4YNwB1YXKjgnO64ZItBNaBRQoOgXn,0.124811,0.384592,0.257066 +0,+ZkQz7QrPZIODz45A+60ZFnG18jnyYlSY/IgEe1Yj8c4cU8h+L8WDIKMv2uB7EwD,1.022656,6.508863,3.368929 +0,+X4DW7zA6whRfOWSHHONJ1u3f0DyBvC9PqDmXGFfbxT4aUGCC6kVm6fuGu9IsQyL,3.428286,15.183059,5.743137 +0,2KXdN0Pb4iyu0jVPocTTf3dwk2Z1LjIlAcydV3HURGIUn1dTycCDDCHg5G6l6i9t,0.282044,0.40582,0.311669 +0,2lGxRtUbBrRZmIYagONMp6vj0zHk4EGhu0aSH5Ws/CAXwBNZpCavBFDNCEcPsOkt,3.662958,8.660027,5.281077 +0,+IR6CKA4zeO742dCx1l2hR0plhTanlaxPWAbckkZNo6UAti83TpYPRXrrfdmm9Ar,0.086237,2.450893,0.969819 +0,2/hWJ+i+1FSHiD44Rr3S4xWMUHC6hIgoVBX2XGZ7cOFyLn9FWQ3Kevsocw7CGaxJ,1.499537,2.832775,1.900258 +0,1WnALZnCvRlfqnuRyrIf0wxQOGLhGuvxInHelnMBM6cw9G9hydTBxqV60JSL/48p,0.717535,5.066802,1.448937 diff --git a/opendc-trace/opendc-trace-azure/src/test/resources/trace/vmtable/vmtable.csv b/opendc-trace/opendc-trace-azure/src/test/resources/trace/vmtable/vmtable.csv new file mode 100644 index 00000000..299c518c --- /dev/null +++ b/opendc-trace/opendc-trace-azure/src/test/resources/trace/vmtable/vmtable.csv @@ -0,0 +1,10 @@ +x/XsOfHO4ocsV99i4NluqKDuxctW2MMVmwqOPAlg4wp8mqbBOe3wxBlQo0+Qx+uf,VDU4C8cqdr+ORcqquwMRcsBA2l0SC6lCPys0wdghKROuxPYysA2XYii9Y5ZkaYaq,Pc2VLB8aDxK2DCC96itq4vW/zVDp4wioAUiB3HoGSFYQ0o6/ZCegTpb9vEH4LeMTEWVObHTPRYEY81TYivZCMQ==,0,2591700,99.369869,3.4240942342446719,10.194309,Delay-insensitive,1,1.75 +H5CxmMoVcZSpjgGbohnVA3R+7uCTe/hM2ht2uIYi3t7KwXB4tkBxmZHBrt2A4x+n,BSXOcywx8pUU0DueDo6UMol1YzR6tn47KLEKaoXp0a1bf2PpzJ7n7lLlmhQ0OJf9,3J17LcV4gXjFat62qhVFRfoiWArHnY763HVqqI6orJCfV8h5j9yeotRMnCLlX1ooGkMyQ2MDOuY1oz111AGN9Q==,0,1539300,100,6.18178366757598,33.98136,Interactive,1,0.75 +wR/G1YUjpMP4zUbxGM/XJNhYS8cAK3SGKM2tqhF7VdeTUYHGktQiKQNoDTtYvnAc,VDU4C8cqdr+ORcqquwMRcsBA2l0SC6lCPys0wdghKROuxPYysA2XYii9Y5ZkaYaq,Pc2VLB8aDxK2DCC96itq4vW/zVDp4wioAUiB3HoGSFYQ0o6/ZCegTpb9vEH4LeMT+hzuAPZnYJMu61JNhTDF/Q==,2188800,2591700,99.569027,3.5736346071428589,7.92425,Delay-insensitive,1,1.75 +1XiU+KpvIa3T1XP8kk3ZY71Of03+ogFL5Pag9Mc2jBuh0YqeW0Zcb9lepKLdPEDg,8u+M3WcFp8pq183WoMB79PhK7xUzbaviOBv0qWN6Xn4mbuNVM1GYJlIjswgit+k1,DHbeI+pYTYFjH8JAF8SewM0z/4SqQctvxcBRGIRglBmeLW5VjISVEw7/IpY345kHwHtk7+SKlEwc1upnT3PigA==,0,2591700,99.405085,16.2876105408034,95.69789,Delay-insensitive,8,56 +z5i2HiSaz6ZdLR6PXdnDjGva3jIlkMPXx23VtfXx9q3dXFRBQrxCOj7sHUsrmFLa,VDU4C8cqdr+ORcqquwMRcsBA2l0SC6lCPys0wdghKROuxPYysA2XYii9Y5ZkaYaq,Pc2VLB8aDxK2DCC96itq4vW/zVDp4wioAUiB3HoGSFYQ0o6/ZCegTpb9vEH4LeMTEWVObHTPRYEY81TYivZCMQ==,0,2188500,98.967961,3.036037969572376,9.445484,Delay-insensitive,1,1.75 +n77nP00/UpJmT+Yx1ZkDphvAqPoHU8yUpDCwyUtPNlRENqvNp6Inya1eiy7VP1+x,8u+M3WcFp8pq183WoMB79PhK7xUzbaviOBv0qWN6Xn4mbuNVM1GYJlIjswgit+k1,DHbeI+pYTYFjH8JAF8SewM0z/4SqQctvxcBRGIRglBmeLW5VjISVEw7/IpY345kHwHtk7+SKlEwc1upnT3PigA==,0,2591700,99.448473,34.17401179027781,98.553018,Delay-insensitive,8,56 +aTSXW3N1KepxKYwKumd7T1+f7DkGolSKV8EArYAdctjD26YqSMKezCVSdvmSgqIQ,dBub/K+8I6jD9t2ExqUdRNlVxPPvDWqICA9Sr+yzcBZ/nNuC0W2swapPoBNIRoF+,C9GnRqFF2lzW/elUsLEwhyAQj9D/d5JIOOgvwfPL1aINf+m1f29G7nXhr6mRPGbiofmjfP9GkepcWz9LX5tp7Q==,2290500,2292300,94.113335,32.461745857142866,94.113335,Unkown,1,1.75 +uSkGH3DS6BVo3RFnw3GZb6WCFSmGgvgKi4HIj08yxO4f5ladUQc3pqDOtqRN0W9+,8u+M3WcFp8pq183WoMB79PhK7xUzbaviOBv0qWN6Xn4mbuNVM1GYJlIjswgit+k1,DHbeI+pYTYFjH8JAF8SewM0z/4SqQctvxcBRGIRglBmeLW5VjISVEw7/IpY345kHwHtk7+SKlEwc1upnT3PigA==,0,2591700,99.276369,1.3500837561060346,23.450372,Delay-insensitive,8,56 +ztRY/Sk5mrSFFcpy2usZ0YZZ7Eumq130/5BB8WVXfWaYvFkU+EhXUQ2kOFkCXuCw,dBub/K+8I6jD9t2ExqUdRNlVxPPvDWqICA9Sr+yzcBZ/nNuC0W2swapPoBNIRoF+,C9GnRqFF2lzW/elUsLEwhyAQj9D/d5JIOOgvwfPL1aINf+m1f29G7nXhr6mRPGbiofmjfP9GkepcWz9LX5tp7Q==,2281200,2300100,98.671595,43.724999781249991,98.13707,Unkown,1,1.75 +bJoIb8ras2ZNNSdAz3CAu4HYRd6k9MOqij/+6/+/5XaYw4+EoGdUEr74DCi974gJ,8u+M3WcFp8pq183WoMB79PhK7xUzbaviOBv0qWN6Xn4mbuNVM1GYJlIjswgit+k1,DHbeI+pYTYFjH8JAF8SewM0z/4SqQctvxcBRGIRglBmeLW5VjISVEw7/IpY345kHwHtk7+SKlEwc1upnT3PigA==,0,2591700,99.498748,18.989459534151351,94.751666,Interactive,8,56 diff --git a/settings.gradle.kts b/settings.gradle.kts index 7bfc8fc6..f77fb676 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -51,6 +51,7 @@ include(":opendc-trace:opendc-trace-swf") include(":opendc-trace:opendc-trace-wtf") include(":opendc-trace:opendc-trace-wfformat") include(":opendc-trace:opendc-trace-bitbrains") +include(":opendc-trace:opendc-trace-azure") include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") -- cgit v1.2.3 From 9b25eef67911d0aec6a36c82a34cd0e39b13b073 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 19 Sep 2021 12:56:26 +0200 Subject: feat(trace): Add support for internal OpenDC VM trace format This change adds official support to the trace library for the internal VM trace format used by OpenDC for its experiments. This is a compact format that uses Parquet to store the virtual machine trace data in two Parquet files. --- .../opendc-compute-workload/build.gradle.kts | 1 + .../compute/workload/ComputeWorkloadLoader.kt | 6 +- .../compute/workload/trace/TraceConverter.kt | 11 +- .../workload/trace/bp/BPResourceStateTable.kt | 53 ---------- .../trace/bp/BPResourceStateTableReader.kt | 103 ------------------ .../compute/workload/trace/bp/BPResourceTable.kt | 53 ---------- .../workload/trace/bp/BPResourceTableReader.kt | 103 ------------------ .../opendc/compute/workload/trace/bp/BPTrace.kt | 49 --------- .../compute/workload/trace/bp/BPTraceFormat.kt | 47 --------- .../opendc/compute/workload/trace/bp/Schemas.kt | 55 ---------- opendc-trace/opendc-trace-opendc/build.gradle.kts | 39 +++++++ .../opendc/trace/opendc/OdcVmResourceStateTable.kt | 53 ++++++++++ .../trace/opendc/OdcVmResourceStateTableReader.kt | 103 ++++++++++++++++++ .../org/opendc/trace/opendc/OdcVmResourceTable.kt | 53 ++++++++++ .../trace/opendc/OdcVmResourceTableReader.kt | 103 ++++++++++++++++++ .../kotlin/org/opendc/trace/opendc/OdcVmTrace.kt | 49 +++++++++ .../org/opendc/trace/opendc/OdcVmTraceFormat.kt | 82 +++++++++++++++ .../services/org.opendc.trace.spi.TraceFormat | 1 + .../opendc/trace/opendc/OdcVmTraceFormatTest.kt | 117 +++++++++++++++++++++ .../src/test/resources/trace/meta.parquet | Bin 0 -> 1582 bytes .../src/test/resources/trace/trace.parquet | Bin 0 -> 83524 bytes settings.gradle.kts | 1 + 22 files changed, 610 insertions(+), 472 deletions(-) delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt create mode 100644 opendc-trace/opendc-trace-opendc/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat create mode 100644 opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet create mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts index d67bbc66..a651633d 100644 --- a/opendc-compute/opendc-compute-workload/build.gradle.kts +++ b/opendc-compute/opendc-compute-workload/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { api(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTrace.opendcTraceParquet) + implementation(projects.opendcTrace.opendcTraceOpendc) implementation(projects.opendcTrace.opendcTraceAzure) implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index 46176609..afc0fce9 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -23,9 +23,9 @@ package org.opendc.compute.workload import mu.KotlinLogging -import org.opendc.compute.workload.trace.bp.BPTraceFormat import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.trace.* +import org.opendc.trace.opendc.OdcVmTraceFormat import java.io.File import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -43,9 +43,9 @@ public class ComputeWorkloadLoader(private val baseDir: File) { private val logger = KotlinLogging.logger {} /** - * The [BPTraceFormat] instance to load the traces + * The [OdcVmTraceFormat] instance to load the traces */ - private val format = BPTraceFormat() + private val format = OdcVmTraceFormat() /** * The cache of workloads. diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt index 20d0fef1..50f3a669 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt @@ -34,12 +34,11 @@ import org.apache.avro.generic.GenericRecordBuilder import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.compute.workload.trace.bp.BP_RESOURCES_SCHEMA -import org.opendc.compute.workload.trace.bp.BP_RESOURCE_STATES_SCHEMA import org.opendc.trace.* import org.opendc.trace.azure.AzureTraceFormat import org.opendc.trace.bitbrains.BitbrainsExTraceFormat import org.opendc.trace.bitbrains.BitbrainsTraceFormat +import org.opendc.trace.opendc.OdcVmTraceFormat import org.opendc.trace.util.parquet.LocalOutputFile import java.io.File import java.util.* @@ -106,7 +105,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { logger.info { "Building resources table" } val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) - .withSchema(BP_RESOURCES_SCHEMA) + .withSchema(OdcVmTraceFormat.RESOURCES_SCHEMA) .withCompressionCodec(CompressionCodecName.ZSTD) .enablePageWriteChecksum() .build() @@ -117,7 +116,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { logger.info { "Building resource states table" } val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) - .withSchema(BP_RESOURCE_STATES_SCHEMA) + .withSchema(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) .withCompressionCodec(CompressionCodecName.ZSTD) .enableDictionaryEncoding() .enablePageWriteChecksum() @@ -170,7 +169,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { continue } - val builder = GenericRecordBuilder(BP_RESOURCES_SCHEMA) + val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCES_SCHEMA) builder["id"] = id builder["submissionTime"] = startTime @@ -207,7 +206,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { continue } - val builder = GenericRecordBuilder(BP_RESOURCE_STATES_SCHEMA) + val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) builder["id"] = id val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt deleted file mode 100644 index 958ed49d..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * The resource state [Table] in the Bitbrains Parquet format. - */ -internal class BPResourceStateTable(private val path: Path) : Table { - override val name: String = TABLE_RESOURCE_STATES - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_DURATION, - RESOURCE_STATE_NCPUS, - RESOURCE_STATE_CPU_USAGE, - ) - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("trace.parquet")) - return BPResourceStateTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt deleted file mode 100644 index 655da2b6..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.time.Duration -import java.time.Instant - -/** - * A [TableReader] implementation for the Bitbrains Parquet format. - */ -internal class BPResourceStateTableReader(private val reader: LocalParquetReader) : TableReader { - /** - * The current record. - */ - private var record: GenericRecord? = null - - override fun nextRow(): Boolean { - record = reader.read() - return record != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_DURATION -> true - RESOURCE_STATE_NCPUS -> true - RESOURCE_STATE_CPU_USAGE -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val record = checkNotNull(record) { "Reader in invalid state" } - - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - RESOURCE_STATE_ID -> record["id"].toString() - RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record["time"] as Long) - RESOURCE_STATE_DURATION -> Duration.ofMillis(record["duration"] as Long) - RESOURCE_STATE_NCPUS -> record["cores"] - RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - RESOURCE_STATE_NCPUS -> record["cores"] as Int - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - reader.close() - } - - override fun toString(): String = "BPResourceStateTableReader" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt deleted file mode 100644 index 75782486..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * The resource [Table] in the Bitbrains Parquet format. - */ -internal class BPResourceTable(private val path: Path) : Table { - override val name: String = TABLE_RESOURCES - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_START_TIME, - RESOURCE_STOP_TIME, - RESOURCE_NCPUS, - RESOURCE_MEM_CAPACITY - ) - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("meta.parquet")) - return BPResourceTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt deleted file mode 100644 index 323ee9d0..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.time.Instant - -/** - * A [TableReader] implementation for the Bitbrains Parquet format. - */ -internal class BPResourceTableReader(private val reader: LocalParquetReader) : TableReader { - /** - * The current record. - */ - private var record: GenericRecord? = null - - override fun nextRow(): Boolean { - record = reader.read() - return record != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } - } - - override fun get(column: TableColumn): T { - val record = checkNotNull(record) { "Reader in invalid state" } - - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - RESOURCE_ID -> record["id"].toString() - RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) - RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) - RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) - else -> throw IllegalArgumentException("Invalid column") - } - - @Suppress("UNCHECKED_CAST") - return res as T - } - - override fun getBoolean(column: TableColumn): Boolean { - throw IllegalArgumentException("Invalid column") - } - - override fun getInt(column: TableColumn): Int { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - RESOURCE_NCPUS -> record["maxCores"] as Int - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun getLong(column: TableColumn): Long { - throw IllegalArgumentException("Invalid column") - } - - override fun getDouble(column: TableColumn): Double { - val record = checkNotNull(record) { "Reader in invalid state" } - - return when (column) { - RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() * 1000.0 // MB to KB - else -> throw IllegalArgumentException("Invalid column") - } - } - - override fun close() { - reader.close() - } - - override fun toString(): String = "BPResourceTableReader" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt deleted file mode 100644 index b4e64fab..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.opendc.trace.TABLE_RESOURCES -import org.opendc.trace.TABLE_RESOURCE_STATES -import org.opendc.trace.Table -import org.opendc.trace.Trace -import java.nio.file.Path - -/** - * A [Trace] in the Bitbrains Parquet format. - */ -public class BPTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = - name == TABLE_RESOURCES || name == TABLE_RESOURCE_STATES - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> BPResourceTable(path) - TABLE_RESOURCE_STATES -> BPResourceStateTable(path) - else -> null - } - } - - override fun toString(): String = "BPTrace[$path]" -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt deleted file mode 100644 index 9662476d..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists - -/** - * A format implementation for the GWF trace format. - */ -public class BPTraceFormat : TraceFormat { - /** - * The name of this trace format. - */ - override val name: String = "bitbrains-parquet" - - /** - * Open a Bitbrains Parquet trace. - */ - override fun open(url: URL): BPTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return BPTrace(path) - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt deleted file mode 100644 index 4f6dbce3..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace.bp - -import org.apache.avro.Schema -import org.apache.avro.SchemaBuilder - -/** - * Schema for the resources table in the trace. - */ -public val BP_RESOURCES_SCHEMA: Schema = SchemaBuilder - .record("meta") - .namespace("org.opendc.trace.capelin") - .fields() - .requiredString("id") - .requiredLong("submissionTime") - .requiredLong("endTime") - .requiredInt("maxCores") - .requiredLong("requiredMemory") - .endRecord() - -/** - * Schema for the resource states table in the trace. - */ -public val BP_RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder - .record("meta") - .namespace("org.opendc.trace.capelin") - .fields() - .requiredString("id") - .requiredLong("time") - .requiredLong("duration") - .requiredInt("cores") - .requiredDouble("cpuUsage") - .requiredLong("flops") - .endRecord() diff --git a/opendc-trace/opendc-trace-opendc/build.gradle.kts b/opendc-trace/opendc-trace-opendc/build.gradle.kts new file mode 100644 index 00000000..b9c242a1 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/build.gradle.kts @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Support for OpenDC-specific trace formats" + +/* Build configuration */ +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcTrace.opendcTraceApi) + + implementation(projects.opendcTrace.opendcTraceParquet) + + testRuntimeOnly(libs.slf4j.simple) +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt new file mode 100644 index 00000000..32a71052 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * The resource state [Table] in the OpenDC virtual machine trace format. + */ +internal class OdcVmResourceStateTable(private val path: Path) : Table { + override val name: String = TABLE_RESOURCE_STATES + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_STATE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_DURATION, + RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_USAGE, + ) + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("trace.parquet")) + return OdcVmResourceStateTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt new file mode 100644 index 00000000..8850ad39 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Duration +import java.time.Instant + +/** + * A [TableReader] implementation for the OpenDC virtual machine trace format. + */ +internal class OdcVmResourceStateTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_STATE_ID -> true + RESOURCE_STATE_TIMESTAMP -> true + RESOURCE_STATE_DURATION -> true + RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_USAGE -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + RESOURCE_STATE_ID -> record["id"].toString() + RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record["time"] as Long) + RESOURCE_STATE_DURATION -> Duration.ofMillis(record["duration"] as Long) + RESOURCE_STATE_NCPUS -> record["cores"] + RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_STATE_NCPUS -> record["cores"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + val record = checkNotNull(record) { "Reader in invalid state" } + return when (column) { + RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + override fun toString(): String = "OdcVmResourceStateTableReader" +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt new file mode 100644 index 00000000..9927afee --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path + +/** + * The resource [Table] for the OpenDC virtual machine trace format. + */ +internal class OdcVmResourceTable(private val path: Path) : Table { + override val name: String = TABLE_RESOURCES + override val isSynthetic: Boolean = false + + override val columns: List> = listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_NCPUS, + RESOURCE_MEM_CAPACITY + ) + + override fun newReader(): TableReader { + val reader = LocalParquetReader(path.resolve("meta.parquet")) + return OdcVmResourceTableReader(reader) + } + + override fun newReader(partition: String): TableReader { + throw IllegalArgumentException("Unknown partition $partition") + } +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt new file mode 100644 index 00000000..fe4379e6 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.util.parquet.LocalParquetReader +import java.time.Instant + +/** + * A [TableReader] implementation for the resources table in the OpenDC virtual machine trace format. + */ +internal class OdcVmResourceTableReader(private val reader: LocalParquetReader) : TableReader { + /** + * The current record. + */ + private var record: GenericRecord? = null + + override fun nextRow(): Boolean { + record = reader.read() + return record != null + } + + override fun hasColumn(column: TableColumn<*>): Boolean { + return when (column) { + RESOURCE_ID -> true + RESOURCE_START_TIME -> true + RESOURCE_STOP_TIME -> true + RESOURCE_NCPUS -> true + RESOURCE_MEM_CAPACITY -> true + else -> false + } + } + + override fun get(column: TableColumn): T { + val record = checkNotNull(record) { "Reader in invalid state" } + + @Suppress("UNCHECKED_CAST") + val res: Any = when (column) { + RESOURCE_ID -> record["id"].toString() + RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) + RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) + RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) + else -> throw IllegalArgumentException("Invalid column") + } + + @Suppress("UNCHECKED_CAST") + return res as T + } + + override fun getBoolean(column: TableColumn): Boolean { + throw IllegalArgumentException("Invalid column") + } + + override fun getInt(column: TableColumn): Int { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_NCPUS -> record["maxCores"] as Int + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun getLong(column: TableColumn): Long { + throw IllegalArgumentException("Invalid column") + } + + override fun getDouble(column: TableColumn): Double { + val record = checkNotNull(record) { "Reader in invalid state" } + + return when (column) { + RESOURCE_MEM_CAPACITY -> (record["requiredMemory"] as Number).toDouble() * 1000.0 // MB to KB + else -> throw IllegalArgumentException("Invalid column") + } + } + + override fun close() { + reader.close() + } + + override fun toString(): String = "OdcVmResourceTableReader" +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt new file mode 100644 index 00000000..3e5029b4 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.opendc.trace.TABLE_RESOURCES +import org.opendc.trace.TABLE_RESOURCE_STATES +import org.opendc.trace.Table +import org.opendc.trace.Trace +import java.nio.file.Path + +/** + * A [Trace] in the OpenDC virtual machine trace format. + */ +public class OdcVmTrace internal constructor(private val path: Path) : Trace { + override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun containsTable(name: String): Boolean = + name == TABLE_RESOURCES || name == TABLE_RESOURCE_STATES + + override fun getTable(name: String): Table? { + return when (name) { + TABLE_RESOURCES -> OdcVmResourceTable(path) + TABLE_RESOURCE_STATES -> OdcVmResourceStateTable(path) + else -> null + } + } + + override fun toString(): String = "OdcVmTrace[$path]" +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt new file mode 100644 index 00000000..b69b5edf --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.Schema +import org.apache.avro.SchemaBuilder +import org.opendc.trace.spi.TraceFormat +import java.net.URL +import java.nio.file.Paths +import kotlin.io.path.exists + +/** + * A [TraceFormat] implementation of the OpenDC virtual machine trace format. + */ +public class OdcVmTraceFormat : TraceFormat { + /** + * The name of this trace format. + */ + override val name: String = "opendc-vm" + + /** + * Open a Bitbrains Parquet trace. + */ + override fun open(url: URL): OdcVmTrace { + val path = Paths.get(url.toURI()) + require(path.exists()) { "URL $url does not exist" } + return OdcVmTrace(path) + } + + public companion object { + /** + * Schema for the resources table in the trace. + */ + @JvmStatic + public val RESOURCES_SCHEMA: Schema = SchemaBuilder + .record("resource") + .namespace("org.opendc.trace.opendc") + .fields() + .requiredString("id") + .requiredLong("submissionTime") + .requiredLong("endTime") + .requiredInt("maxCores") + .requiredLong("requiredMemory") + .endRecord() + + /** + * Schema for the resource states table in the trace. + */ + @JvmStatic + public val RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder + .record("resource_state") + .namespace("org.opendc.trace.opendc") + .fields() + .requiredString("id") + .requiredLong("time") + .requiredLong("duration") + .requiredInt("cores") + .requiredDouble("cpuUsage") + .requiredLong("flops") + .endRecord() + } +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat new file mode 100644 index 00000000..94094af4 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat @@ -0,0 +1 @@ +org.opendc.trace.opendc.OdcVmTraceFormat diff --git a/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt new file mode 100644 index 00000000..21f1174c --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.opendc.trace.* +import java.io.File +import java.net.URL + +/** + * Test suite for the [OdcVmTraceFormat] implementation. + */ +internal class OdcVmTraceFormatTest { + private val format = OdcVmTraceFormat() + + @Test + fun testTraceExists() { + val url = File("src/test/resources/trace").toURI().toURL() + assertDoesNotThrow { format.open(url) } + } + + @Test + fun testTraceDoesNotExists() { + val url = File("src/test/resources/trace").toURI().toURL() + assertThrows { + format.open(URL(url.toString() + "help")) + } + } + + @Test + fun testTables() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) + } + + @Test + fun testTableExists() { + val url = File("src/test/resources/trace").toURI().toURL() + val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + + assertNotNull(table) + assertDoesNotThrow { table!!.newReader() } + } + + @Test + fun testTableDoesNotExist() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + assertFalse(trace.containsTable("test")) + assertNull(trace.getTable("test")) + } + + @Test + fun testResources() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("1019", reader.get(RESOURCE_ID)) }, + { assertTrue(reader.nextRow()) }, + { assertEquals("1023", reader.get(RESOURCE_ID)) }, + { assertTrue(reader.nextRow()) }, + { assertEquals("1052", reader.get(RESOURCE_ID)) }, + { assertTrue(reader.nextRow()) }, + { assertEquals("1073", reader.get(RESOURCE_ID)) }, + { assertFalse(reader.nextRow()) } + ) + + reader.close() + } + + @Test + fun testSmoke() { + val url = File("src/test/resources/trace").toURI().toURL() + val trace = format.open(url) + + val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + + assertAll( + { assertTrue(reader.nextRow()) }, + { assertEquals("1019", reader.get(RESOURCE_STATE_ID)) }, + { assertEquals(1376314846, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) }, + { assertEquals(0.0, reader.getDouble(RESOURCE_STATE_CPU_USAGE), 0.01) } + ) + + reader.close() + } +} diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet new file mode 100644 index 00000000..d6ff09d8 Binary files /dev/null and b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet differ diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet new file mode 100644 index 00000000..5b6fa6b7 Binary files /dev/null and b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet differ diff --git a/settings.gradle.kts b/settings.gradle.kts index f77fb676..26bd0b11 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -52,6 +52,7 @@ include(":opendc-trace:opendc-trace-wtf") include(":opendc-trace:opendc-trace-wfformat") include(":opendc-trace:opendc-trace-bitbrains") include(":opendc-trace:opendc-trace-azure") +include(":opendc-trace:opendc-trace-opendc") include(":opendc-trace:opendc-trace-parquet") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") -- cgit v1.2.3 From 474044649a67cfcc857615b6a0f8387a2954abbd Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 16 Sep 2021 12:34:53 +0200 Subject: feat(trace): Update OpenDC VM trace format This change optimizes the OpenDC VM trace format by removing unnecessary columns as well as optimizing the writer settings. The new implementation still supports reading the old trace format in case users run OpenDC with older workload traces. --- .../compute/workload/ComputeWorkloadLoader.kt | 6 +- .../compute/workload/trace/TraceConverter.kt | 86 +++++++++++++-------- .../experiments/capelin/CapelinIntegrationTest.kt | 30 +++---- .../resources/trace/bitbrains-small/meta.parquet | Bin 2081 -> 2099 bytes .../resources/trace/bitbrains-small/trace.parquet | Bin 1647189 -> 1125930 bytes .../kotlin/org/opendc/trace/ResourceColumns.kt | 2 +- .../org/opendc/trace/ResourceStateColumns.kt | 2 +- .../opendc/trace/azure/AzureResourceStateTable.kt | 2 +- .../org/opendc/trace/azure/AzureResourceTable.kt | 2 +- .../opendc/trace/azure/AzureResourceTableReader.kt | 6 +- .../org/opendc/trace/azure/AzureTraceFormatTest.kt | 2 +- .../bitbrains/BitbrainsExResourceStateTable.kt | 4 +- .../BitbrainsExResourceStateTableReader.kt | 8 +- .../trace/bitbrains/BitbrainsResourceStateTable.kt | 4 +- .../bitbrains/BitbrainsResourceStateTableReader.kt | 6 +- .../opendc/trace/opendc/OdcVmResourceStateTable.kt | 2 +- .../trace/opendc/OdcVmResourceStateTableReader.kt | 54 ++++++++++--- .../org/opendc/trace/opendc/OdcVmResourceTable.kt | 4 +- .../trace/opendc/OdcVmResourceTableReader.kt | 51 ++++++++++-- .../org/opendc/trace/opendc/OdcVmTraceFormat.kt | 16 ++-- .../opendc/trace/opendc/OdcVmTraceFormatTest.kt | 26 ++++--- .../src/test/resources/trace-v2.0/meta.parquet | Bin 0 -> 1582 bytes .../src/test/resources/trace-v2.0/trace.parquet | Bin 0 -> 83524 bytes .../src/test/resources/trace-v2.1/meta.parquet | Bin 0 -> 1679 bytes .../src/test/resources/trace-v2.1/trace.parquet | Bin 0 -> 65174 bytes .../src/test/resources/trace/meta.parquet | Bin 1582 -> 0 bytes .../src/test/resources/trace/trace.parquet | Bin 83524 -> 0 bytes traces/bitbrains-small/meta.parquet | Bin 2140 -> 2099 bytes traces/bitbrains-small/trace.parquet | Bin 1610917 -> 1125930 bytes 29 files changed, 203 insertions(+), 110 deletions(-) create mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/meta.parquet create mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/trace.parquet create mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/meta.parquet create mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/trace.parquet delete mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet delete mode 100644 opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index afc0fce9..c92b212f 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -65,7 +65,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { val id = reader.get(RESOURCE_STATE_ID) val time = reader.get(RESOURCE_STATE_TIMESTAMP) val duration = reader.get(RESOURCE_STATE_DURATION) - val cores = reader.getInt(RESOURCE_STATE_NCPUS) + val cores = reader.getInt(RESOURCE_STATE_CPU_COUNT) val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) val fragment = SimTraceWorkload.Fragment( @@ -75,7 +75,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { cores ) - fragments.getOrPut(id) { mutableListOf() }.add(fragment) + fragments.computeIfAbsent(id) { mutableListOf() }.add(fragment) } fragments @@ -103,7 +103,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { val submissionTime = reader.get(RESOURCE_START_TIME) val endTime = reader.get(RESOURCE_STOP_TIME) - val maxCores = reader.getInt(RESOURCE_NCPUS) + val maxCores = reader.getInt(RESOURCE_CPU_COUNT) val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt index 50f3a669..2d570787 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.workload.vm.trace +package org.opendc.compute.workload.trace import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.arguments.argument @@ -42,6 +42,7 @@ import org.opendc.trace.opendc.OdcVmTraceFormat import org.opendc.trace.util.parquet.LocalOutputFile import java.io.File import java.util.* +import kotlin.math.abs import kotlin.math.max import kotlin.math.min import kotlin.math.roundToLong @@ -112,16 +113,21 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { val selectedVms = metaWriter.use { convertResources(trace, it) } + if (selectedVms.isEmpty()) { + logger.warn { "No VMs selected" } + return + } + logger.info { "Wrote ${selectedVms.size} rows" } logger.info { "Building resource states table" } val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) .withSchema(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) .withCompressionCodec(CompressionCodecName.ZSTD) - .enableDictionaryEncoding() - .enablePageWriteChecksum() + .withDictionaryEncoding("id", true) .withBloomFilterEnabled("id", true) .withBloomFilterNDV("id", selectedVms.size.toLong()) + .enableValidation() .build() val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } @@ -154,7 +160,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { startTime = min(startTime, timestamp) stopTime = max(stopTime, timestamp) - numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_NCPUS)) + numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_CPU_COUNT)) memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { @@ -172,10 +178,10 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCES_SCHEMA) builder["id"] = id - builder["submissionTime"] = startTime - builder["endTime"] = stopTime - builder["maxCores"] = numCpus - builder["requiredMemory"] = max(memCapacity, memUsage).roundToLong() + builder["start_time"] = startTime + builder["stop_time"] = stopTime + builder["cpu_count"] = numCpus + builder["mem_capacity"] = max(memCapacity, memUsage).roundToLong() logger.info { "Selecting VM $id" } @@ -194,44 +200,58 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { var hasNextRow = reader.nextRow() var count = 0 + var lastId: String? = null + var lastTimestamp = 0L while (hasNextRow) { - var lastTimestamp = Long.MIN_VALUE + val id = reader.get(RESOURCE_STATE_ID) - do { - val id = reader.get(RESOURCE_STATE_ID) + if (id !in selectedVms) { + hasNextRow = reader.nextRow() + continue + } - if (id !in selectedVms) { - hasNextRow = reader.nextRow() - continue - } + val cpuCount = reader.getInt(RESOURCE_STATE_CPU_COUNT) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) - builder["id"] = id + val startTimestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + var timestamp = startTimestamp + var duration: Long - val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() - if (lastTimestamp < 0) { - lastTimestamp = timestamp - 5 * 60 * 1000L + // Check whether the previous entry is from a different VM + if (id != lastId) { + lastTimestamp = timestamp - 5 * 60 * 1000L + } + + do { + timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + + duration = timestamp - lastTimestamp + hasNextRow = reader.nextRow() + + if (!hasNextRow) { + break } - val duration = timestamp - lastTimestamp - val cores = reader.getInt(RESOURCE_STATE_NCPUS) - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - val flops = (cpuUsage * duration / 1000.0).roundToLong() + val shouldContinue = id == reader.get(RESOURCE_STATE_ID) && + abs(cpuUsage - reader.getDouble(RESOURCE_STATE_CPU_USAGE)) < 0.01 && + cpuCount == reader.getInt(RESOURCE_STATE_CPU_COUNT) + } while (shouldContinue) - builder["time"] = timestamp - builder["duration"] = duration - builder["cores"] = cores - builder["cpuUsage"] = cpuUsage - builder["flops"] = flops + val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) - writer.write(builder.build()) + builder["id"] = id + builder["timestamp"] = startTimestamp + builder["duration"] = duration + builder["cpu_count"] = cpuCount + builder["cpu_usage"] = cpuUsage - lastTimestamp = timestamp - hasNextRow = reader.nextRow() - } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) + writer.write(builder.build()) count++ + + lastId = id + lastTimestamp = timestamp } return count diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 140a84db..ac2ea646 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -117,11 +117,11 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, - { assertEquals(221949826, monitor.idleTime) { "Incorrect idle time" } }, - { assertEquals(68421374, monitor.activeTime) { "Incorrect active time" } }, - { assertEquals(947010, monitor.stealTime) { "Incorrect steal time" } }, + { assertEquals(223331032, monitor.idleTime) { "Incorrect idle time" } }, + { assertEquals(67006568, monitor.activeTime) { "Incorrect active time" } }, + { assertEquals(3159379, monitor.stealTime) { "Incorrect steal time" } }, { assertEquals(0, monitor.lostTime) { "Incorrect lost time" } }, - { assertEquals(5.783711298639437E9, monitor.energyUsage, 0.01) { "Incorrect power draw" } }, + { assertEquals(5.841120890240688E9, monitor.energyUsage, 0.01) { "Incorrect power draw" } }, ) } @@ -161,9 +161,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(8545158, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(12195642, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(941038, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(10998110, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(9740290, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(0, monitor.stealTime) { "Steal time incorrect" } }, { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } } ) } @@ -210,10 +210,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(8545158, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(12195642, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(941038, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(3378, monitor.lostTime) { "Lost time incorrect" } } + { assertEquals(6013899, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(14724501, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(12530742, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(473394, monitor.lostTime) { "Lost time incorrect" } } ) } @@ -253,11 +253,11 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(8640140, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(12100660, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(939456, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(11134319, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(9604081, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(0, monitor.stealTime) { "Steal time incorrect" } }, { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, - { assertEquals(2559305056, monitor.uptime) { "Uptime incorrect" } } + { assertEquals(2559005056, monitor.uptime) { "Uptime incorrect" } } ) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet index ee76d38f..da6e5330 100644 Binary files a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet and b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/meta.parquet differ diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet index 9b1cde13..fe0a254c 100644 Binary files a/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet and b/opendc-experiments/opendc-experiments-capelin/src/test/resources/trace/bitbrains-small/trace.parquet differ diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt index e2e5ea6d..219002e0 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt @@ -47,7 +47,7 @@ public val RESOURCE_STOP_TIME: TableColumn = TableColumn("resource:stop * Number of CPUs for the resource. */ @JvmField -public val RESOURCE_NCPUS: TableColumn = intColumn("resource:num_cpus") +public val RESOURCE_CPU_COUNT: TableColumn = intColumn("resource:cpu_count") /** * Memory capacity for the resource in KB. diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt index 1933967e..b683923b 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt @@ -60,7 +60,7 @@ public val RESOURCE_STATE_POWERED_ON: TableColumn = booleanColumn("reso * Number of CPUs for the resource. */ @JvmField -public val RESOURCE_STATE_NCPUS: TableColumn = intColumn("resource_state:ncpus") +public val RESOURCE_STATE_CPU_COUNT: TableColumn = intColumn("resource_state:cpu_count") /** * Total CPU capacity of the resource in MHz. diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt index 189ab52a..84c9b347 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt @@ -68,9 +68,9 @@ internal class AzureResourceStateTable(private val factory: CsvFactory, path: Pa delegate.close() delegate = nextDelegate() + this.delegate = delegate } - this.delegate = delegate return delegate != null } diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt index d9f6f156..96ee3158 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt @@ -38,7 +38,7 @@ internal class AzureResourceTable(private val factory: CsvFactory, private val p RESOURCE_ID, RESOURCE_START_TIME, RESOURCE_STOP_TIME, - RESOURCE_NCPUS, + RESOURCE_CPU_COUNT, RESOURCE_MEM_CAPACITY ) diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt index d3970b07..5ea97483 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt @@ -67,7 +67,7 @@ internal class AzureResourceTableReader(private val parser: CsvParser) : TableRe RESOURCE_ID -> true RESOURCE_START_TIME -> true RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true + RESOURCE_CPU_COUNT -> true RESOURCE_MEM_CAPACITY -> true else -> false } @@ -78,7 +78,7 @@ internal class AzureResourceTableReader(private val parser: CsvParser) : TableRe RESOURCE_ID -> id RESOURCE_START_TIME -> startTime RESOURCE_STOP_TIME -> stopTime - RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) + RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) else -> throw IllegalArgumentException("Invalid column") } @@ -93,7 +93,7 @@ internal class AzureResourceTableReader(private val parser: CsvParser) : TableRe override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_NCPUS -> cpuCores + RESOURCE_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } diff --git a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt index 20375547..e5735f0d 100644 --- a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt @@ -87,7 +87,7 @@ class AzureTraceFormatTest { assertAll( { assertTrue(reader.nextRow()) }, { assertEquals("x/XsOfHO4ocsV99i4NluqKDuxctW2MMVmwqOPAlg4wp8mqbBOe3wxBlQo0+Qx+uf", reader.get(RESOURCE_ID)) }, - { assertEquals(1, reader.getInt(RESOURCE_NCPUS)) }, + { assertEquals(1, reader.getInt(RESOURCE_CPU_COUNT)) }, { assertEquals(1750000.0, reader.getDouble(RESOURCE_MEM_CAPACITY)) }, ) diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt index 4db2bace..4a60dff3 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt @@ -50,7 +50,7 @@ internal class BitbrainsExResourceStateTable(path: Path) : Table { RESOURCE_STATE_ID, RESOURCE_STATE_CLUSTER_ID, RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_COUNT, RESOURCE_STATE_CPU_CAPACITY, RESOURCE_STATE_CPU_USAGE, RESOURCE_STATE_CPU_USAGE_PCT, @@ -77,9 +77,9 @@ internal class BitbrainsExResourceStateTable(path: Path) : Table { delegate.close() delegate = nextDelegate() + this.delegate = delegate } - this.delegate = delegate return delegate != null } diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt index 6fe5d397..f1cf7307 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt @@ -81,7 +81,7 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR COL_POWERED_ON -> poweredOn = field.toInt(10) == 1 COL_CPU_CAPACITY -> cpuCapacity = field.toDouble() COL_ID -> id = field.trim() - COL_MEM_CAPACITY -> memCapacity = field.toDouble() + COL_MEM_CAPACITY -> memCapacity = field.toDouble() * 1000 // Convert from MB to KB } } @@ -93,7 +93,7 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR RESOURCE_STATE_ID -> true RESOURCE_STATE_CLUSTER_ID -> true RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_COUNT -> true RESOURCE_STATE_CPU_CAPACITY -> true RESOURCE_STATE_CPU_USAGE -> true RESOURCE_STATE_CPU_USAGE_PCT -> true @@ -111,7 +111,7 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR RESOURCE_STATE_ID -> id RESOURCE_STATE_CLUSTER_ID -> cluster RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_NCPUS -> getInt(RESOURCE_STATE_NCPUS) + RESOURCE_STATE_CPU_COUNT -> getInt(RESOURCE_STATE_CPU_COUNT) RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) @@ -134,7 +134,7 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_STATE_NCPUS -> cpuCores + RESOURCE_STATE_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index c9e5954d..7241b18b 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -50,7 +50,7 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path override val columns: List> = listOf( RESOURCE_STATE_ID, RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_COUNT, RESOURCE_STATE_CPU_CAPACITY, RESOURCE_STATE_CPU_USAGE, RESOURCE_STATE_CPU_USAGE_PCT, @@ -78,9 +78,9 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path delegate.close() delegate = nextDelegate() + this.delegate = delegate } - this.delegate = delegate return delegate != null } diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt index dab784c2..56e66f5c 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt @@ -115,7 +115,7 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, return when (column) { RESOURCE_STATE_ID -> true RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_COUNT -> true RESOURCE_STATE_CPU_CAPACITY -> true RESOURCE_STATE_CPU_USAGE -> true RESOURCE_STATE_CPU_USAGE_PCT -> true @@ -133,7 +133,7 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, val res: Any? = when (column) { RESOURCE_STATE_ID -> partition RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_NCPUS -> cpuCores + RESOURCE_STATE_CPU_COUNT -> cpuCores RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity RESOURCE_STATE_CPU_USAGE -> cpuUsage RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct @@ -156,7 +156,7 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_STATE_NCPUS -> cpuCores + RESOURCE_STATE_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt index 32a71052..bee4ba7e 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt @@ -38,7 +38,7 @@ internal class OdcVmResourceStateTable(private val path: Path) : Table { RESOURCE_STATE_ID, RESOURCE_STATE_TIMESTAMP, RESOURCE_STATE_DURATION, - RESOURCE_STATE_NCPUS, + RESOURCE_STATE_CPU_COUNT, RESOURCE_STATE_CPU_USAGE, ) diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt index 8850ad39..df3bcfa6 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt @@ -22,6 +22,7 @@ package org.opendc.trace.opendc +import org.apache.avro.Schema import org.apache.avro.generic.GenericRecord import org.opendc.trace.* import org.opendc.trace.util.parquet.LocalParquetReader @@ -37,8 +38,20 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea */ private var record: GenericRecord? = null + /** + * A flag to indicate that the columns have been initialized. + */ + private var hasInitializedColumns = false + override fun nextRow(): Boolean { - record = reader.read() + val record = reader.read() + this.record = record + + if (!hasInitializedColumns && record != null) { + initColumns(record.schema) + hasInitializedColumns = true + } + return record != null } @@ -47,7 +60,7 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea RESOURCE_STATE_ID -> true RESOURCE_STATE_TIMESTAMP -> true RESOURCE_STATE_DURATION -> true - RESOURCE_STATE_NCPUS -> true + RESOURCE_STATE_CPU_COUNT -> true RESOURCE_STATE_CPU_USAGE -> true else -> false } @@ -58,11 +71,11 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea @Suppress("UNCHECKED_CAST") val res: Any = when (column) { - RESOURCE_STATE_ID -> record["id"].toString() - RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record["time"] as Long) - RESOURCE_STATE_DURATION -> Duration.ofMillis(record["duration"] as Long) - RESOURCE_STATE_NCPUS -> record["cores"] - RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + RESOURCE_STATE_ID -> record[COL_ID].toString() + RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record[COL_TIMESTAMP] as Long) + RESOURCE_STATE_DURATION -> Duration.ofMillis(record[COL_DURATION] as Long) + RESOURCE_STATE_CPU_COUNT -> getInt(RESOURCE_STATE_CPU_COUNT) + RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) else -> throw IllegalArgumentException("Invalid column") } @@ -76,9 +89,8 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea override fun getInt(column: TableColumn): Int { val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_STATE_NCPUS -> record["cores"] as Int + RESOURCE_STATE_CPU_COUNT -> record[COL_CPU_COUNT] as Int else -> throw IllegalArgumentException("Invalid column") } } @@ -90,7 +102,7 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea override fun getDouble(column: TableColumn): Double { val record = checkNotNull(record) { "Reader in invalid state" } return when (column) { - RESOURCE_STATE_CPU_USAGE -> (record["cpuUsage"] as Number).toDouble() + RESOURCE_STATE_CPU_USAGE -> (record[COL_CPU_USAGE] as Number).toDouble() else -> throw IllegalArgumentException("Invalid column") } } @@ -100,4 +112,26 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea } override fun toString(): String = "OdcVmResourceStateTableReader" + + /** + * Initialize the columns for the reader based on [schema]. + */ + private fun initColumns(schema: Schema) { + try { + COL_ID = schema.getField("id").pos() + COL_TIMESTAMP = (schema.getField("timestamp") ?: schema.getField("time")).pos() + COL_DURATION = schema.getField("duration").pos() + COL_CPU_COUNT = (schema.getField("cpu_count") ?: schema.getField("cores")).pos() + COL_CPU_USAGE = (schema.getField("cpu_usage") ?: schema.getField("cpuUsage")).pos() + } catch (e: NullPointerException) { + // This happens when the field we are trying to access does not exist + throw IllegalArgumentException("Invalid schema", e) + } + } + + private var COL_ID = -1 + private var COL_TIMESTAMP = -1 + private var COL_DURATION = -1 + private var COL_CPU_COUNT = -1 + private var COL_CPU_USAGE = -1 } diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt index 9927afee..b1456560 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt @@ -38,8 +38,8 @@ internal class OdcVmResourceTable(private val path: Path) : Table { RESOURCE_ID, RESOURCE_START_TIME, RESOURCE_STOP_TIME, - RESOURCE_NCPUS, - RESOURCE_MEM_CAPACITY + RESOURCE_CPU_COUNT, + RESOURCE_MEM_CAPACITY, ) override fun newReader(): TableReader { diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt index fe4379e6..c52da62d 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt @@ -22,6 +22,7 @@ package org.opendc.trace.opendc +import org.apache.avro.Schema import org.apache.avro.generic.GenericRecord import org.opendc.trace.* import org.opendc.trace.util.parquet.LocalParquetReader @@ -36,8 +37,20 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader true RESOURCE_START_TIME -> true RESOURCE_STOP_TIME -> true - RESOURCE_NCPUS -> true + RESOURCE_CPU_COUNT -> true RESOURCE_MEM_CAPACITY -> true else -> false } @@ -57,10 +70,10 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader record["id"].toString() - RESOURCE_START_TIME -> Instant.ofEpochMilli(record["submissionTime"] as Long) - RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record["endTime"] as Long) - RESOURCE_NCPUS -> getInt(RESOURCE_NCPUS) + RESOURCE_ID -> record[COL_ID].toString() + RESOURCE_START_TIME -> Instant.ofEpochMilli(record[COL_START_TIME] as Long) + RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record[COL_STOP_TIME] as Long) + RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) else -> throw IllegalArgumentException("Invalid column") } @@ -77,7 +90,7 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader record["maxCores"] as Int + RESOURCE_CPU_COUNT -> record[COL_CPU_COUNT] as Int else -> throw IllegalArgumentException("Invalid column") } } @@ -90,7 +103,7 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader (record["requiredMemory"] as Number).toDouble() * 1000.0 // MB to KB + RESOURCE_MEM_CAPACITY -> (record[COL_MEM_CAPACITY] as Number).toDouble() else -> throw IllegalArgumentException("Invalid column") } } @@ -100,4 +113,26 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader { format.open(URL(url.toString() + "help")) } @@ -52,7 +54,7 @@ internal class OdcVmTraceFormatTest { @Test fun testTables() { - val url = File("src/test/resources/trace").toURI().toURL() + val url = File("src/test/resources/trace-v2.1").toURI().toURL() val trace = format.open(url) assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) @@ -60,7 +62,7 @@ internal class OdcVmTraceFormatTest { @Test fun testTableExists() { - val url = File("src/test/resources/trace").toURI().toURL() + val url = File("src/test/resources/trace-v2.1").toURI().toURL() val table = format.open(url).getTable(TABLE_RESOURCE_STATES) assertNotNull(table) @@ -69,16 +71,17 @@ internal class OdcVmTraceFormatTest { @Test fun testTableDoesNotExist() { - val url = File("src/test/resources/trace").toURI().toURL() + val url = File("src/test/resources/trace-v2.1").toURI().toURL() val trace = format.open(url) assertFalse(trace.containsTable("test")) assertNull(trace.getTable("test")) } - @Test - fun testResources() { - val url = File("src/test/resources/trace").toURI().toURL() + @ParameterizedTest + @ValueSource(strings = ["trace-v2.0", "trace-v2.1"]) + fun testResources(name: String) { + val url = File("src/test/resources/$name").toURI().toURL() val trace = format.open(url) val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() @@ -98,9 +101,10 @@ internal class OdcVmTraceFormatTest { reader.close() } - @Test - fun testSmoke() { - val url = File("src/test/resources/trace").toURI().toURL() + @ParameterizedTest + @ValueSource(strings = ["trace-v2.0", "trace-v2.1"]) + fun testSmoke(name: String) { + val url = File("src/test/resources/$name").toURI().toURL() val trace = format.open(url) val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/meta.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/meta.parquet new file mode 100644 index 00000000..d6ff09d8 Binary files /dev/null and b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/meta.parquet differ diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/trace.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/trace.parquet new file mode 100644 index 00000000..5b6fa6b7 Binary files /dev/null and b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.0/trace.parquet differ diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/meta.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/meta.parquet new file mode 100644 index 00000000..d8184945 Binary files /dev/null and b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/meta.parquet differ diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/trace.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/trace.parquet new file mode 100644 index 00000000..00ab5835 Binary files /dev/null and b/opendc-trace/opendc-trace-opendc/src/test/resources/trace-v2.1/trace.parquet differ diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet deleted file mode 100644 index d6ff09d8..00000000 Binary files a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet and /dev/null differ diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet deleted file mode 100644 index 5b6fa6b7..00000000 Binary files a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet and /dev/null differ diff --git a/traces/bitbrains-small/meta.parquet b/traces/bitbrains-small/meta.parquet index 43f51cb8..da6e5330 100644 Binary files a/traces/bitbrains-small/meta.parquet and b/traces/bitbrains-small/meta.parquet differ diff --git a/traces/bitbrains-small/trace.parquet b/traces/bitbrains-small/trace.parquet index f4dd5a50..fe0a254c 100644 Binary files a/traces/bitbrains-small/trace.parquet and b/traces/bitbrains-small/trace.parquet differ -- cgit v1.2.3 From 6502fb752a6f80695c024b8904d7523c420ebdda Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 19 Sep 2021 13:42:26 +0200 Subject: feat(trace): Add tool for converting workload traces This change adds an initial implementation to the trace library for converting between workload trace formats. Currently the tool supports only converting to the OpenDC VM trace format. However, in the future, we will add support for converting between other formats as well. --- .../opendc-compute-workload/build.gradle.kts | 5 +- .../compute/workload/trace/TraceConverter.kt | 279 --------------------- opendc-trace/opendc-trace-tools/build.gradle.kts | 47 ++++ .../org/opendc/trace/tools/TraceConverter.kt | 279 +++++++++++++++++++++ settings.gradle.kts | 1 + 5 files changed, 328 insertions(+), 283 deletions(-) delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt create mode 100644 opendc-trace/opendc-trace-tools/build.gradle.kts create mode 100644 opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts index a651633d..e82cf203 100644 --- a/opendc-compute/opendc-compute-workload/build.gradle.kts +++ b/opendc-compute/opendc-compute-workload/build.gradle.kts @@ -32,10 +32,8 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeSimulator) - implementation(projects.opendcTrace.opendcTraceParquet) implementation(projects.opendcTrace.opendcTraceOpendc) - implementation(projects.opendcTrace.opendcTraceAzure) - implementation(projects.opendcTrace.opendcTraceBitbrains) + implementation(projects.opendcTrace.opendcTraceParquet) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcTelemetry.opendcTelemetrySdk) @@ -43,7 +41,6 @@ dependencies { implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) - implementation(libs.clikt) implementation(libs.jackson.databind) implementation(libs.jackson.module.kotlin) implementation(kotlin("reflect")) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt deleted file mode 100644 index 2d570787..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.trace - -import com.github.ajalt.clikt.core.CliktCommand -import com.github.ajalt.clikt.parameters.arguments.argument -import com.github.ajalt.clikt.parameters.groups.OptionGroup -import com.github.ajalt.clikt.parameters.groups.cooccurring -import com.github.ajalt.clikt.parameters.options.* -import com.github.ajalt.clikt.parameters.types.* -import mu.KotlinLogging -import org.apache.avro.generic.GenericData -import org.apache.avro.generic.GenericRecordBuilder -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetWriter -import org.apache.parquet.hadoop.metadata.CompressionCodecName -import org.opendc.trace.* -import org.opendc.trace.azure.AzureTraceFormat -import org.opendc.trace.bitbrains.BitbrainsExTraceFormat -import org.opendc.trace.bitbrains.BitbrainsTraceFormat -import org.opendc.trace.opendc.OdcVmTraceFormat -import org.opendc.trace.util.parquet.LocalOutputFile -import java.io.File -import java.util.* -import kotlin.math.abs -import kotlin.math.max -import kotlin.math.min -import kotlin.math.roundToLong - -/** - * A script to convert a trace in text format into a Parquet trace. - */ -public fun main(args: Array): Unit = TraceConverterCli().main(args) - -/** - * Represents the command for converting traces - */ -internal class TraceConverterCli : CliktCommand(name = "trace-converter") { - /** - * The logger instance for the converter. - */ - private val logger = KotlinLogging.logger {} - - /** - * The directory where the trace should be stored. - */ - private val output by option("-O", "--output", help = "path to store the trace") - .file(canBeFile = false, mustExist = false) - .defaultLazy { File("output") } - - /** - * The directory where the input trace is located. - */ - private val input by argument("input", help = "path to the input trace") - .file(canBeFile = false) - - /** - * The input format of the trace. - */ - private val format by option("-f", "--format", help = "input format of trace") - .choice( - "solvinity" to BitbrainsExTraceFormat(), - "bitbrains" to BitbrainsTraceFormat(), - "azure" to AzureTraceFormat() - ) - .required() - - /** - * The sampling options. - */ - private val samplingOptions by SamplingOptions().cooccurring() - - override fun run() { - val metaParquet = File(output, "meta.parquet") - val traceParquet = File(output, "trace.parquet") - - if (metaParquet.exists()) { - metaParquet.delete() - } - if (traceParquet.exists()) { - traceParquet.delete() - } - - val trace = format.open(input.toURI().toURL()) - - logger.info { "Building resources table" } - - val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) - .withSchema(OdcVmTraceFormat.RESOURCES_SCHEMA) - .withCompressionCodec(CompressionCodecName.ZSTD) - .enablePageWriteChecksum() - .build() - - val selectedVms = metaWriter.use { convertResources(trace, it) } - - if (selectedVms.isEmpty()) { - logger.warn { "No VMs selected" } - return - } - - logger.info { "Wrote ${selectedVms.size} rows" } - logger.info { "Building resource states table" } - - val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) - .withSchema(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) - .withCompressionCodec(CompressionCodecName.ZSTD) - .withDictionaryEncoding("id", true) - .withBloomFilterEnabled("id", true) - .withBloomFilterNDV("id", selectedVms.size.toLong()) - .enableValidation() - .build() - - val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } - logger.info { "Wrote $statesCount rows" } - } - - /** - * Convert the resources table for the trace. - */ - private fun convertResources(trace: Trace, writer: ParquetWriter): Set { - val random = samplingOptions?.let { Random(it.seed) } - val samplingFraction = samplingOptions?.fraction ?: 1.0 - val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - - var hasNextRow = reader.nextRow() - val selectedVms = mutableSetOf() - - while (hasNextRow) { - var id: String - var numCpus = Int.MIN_VALUE - var memCapacity = Double.MIN_VALUE - var memUsage = Double.MIN_VALUE - var startTime = Long.MAX_VALUE - var stopTime = Long.MIN_VALUE - - do { - id = reader.get(RESOURCE_STATE_ID) - - val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() - startTime = min(startTime, timestamp) - stopTime = max(stopTime, timestamp) - - numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_CPU_COUNT)) - - memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) - if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { - memUsage = max(memUsage, reader.getDouble(RESOURCE_STATE_MEM_USAGE)) - } - - hasNextRow = reader.nextRow() - } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) - - // Sample only a fraction of the VMs - if (random != null && random.nextDouble() > samplingFraction) { - continue - } - - val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCES_SCHEMA) - - builder["id"] = id - builder["start_time"] = startTime - builder["stop_time"] = stopTime - builder["cpu_count"] = numCpus - builder["mem_capacity"] = max(memCapacity, memUsage).roundToLong() - - logger.info { "Selecting VM $id" } - - writer.write(builder.build()) - selectedVms.add(id) - } - - return selectedVms - } - - /** - * Convert the resource states table for the trace. - */ - private fun convertResourceStates(trace: Trace, writer: ParquetWriter, selectedVms: Set): Int { - val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() - - var hasNextRow = reader.nextRow() - var count = 0 - var lastId: String? = null - var lastTimestamp = 0L - - while (hasNextRow) { - val id = reader.get(RESOURCE_STATE_ID) - - if (id !in selectedVms) { - hasNextRow = reader.nextRow() - continue - } - - val cpuCount = reader.getInt(RESOURCE_STATE_CPU_COUNT) - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) - - val startTimestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() - var timestamp = startTimestamp - var duration: Long - - // Check whether the previous entry is from a different VM - if (id != lastId) { - lastTimestamp = timestamp - 5 * 60 * 1000L - } - - do { - timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() - - duration = timestamp - lastTimestamp - hasNextRow = reader.nextRow() - - if (!hasNextRow) { - break - } - - val shouldContinue = id == reader.get(RESOURCE_STATE_ID) && - abs(cpuUsage - reader.getDouble(RESOURCE_STATE_CPU_USAGE)) < 0.01 && - cpuCount == reader.getInt(RESOURCE_STATE_CPU_COUNT) - } while (shouldContinue) - - val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) - - builder["id"] = id - builder["timestamp"] = startTimestamp - builder["duration"] = duration - builder["cpu_count"] = cpuCount - builder["cpu_usage"] = cpuUsage - - writer.write(builder.build()) - - count++ - - lastId = id - lastTimestamp = timestamp - } - - return count - } - - /** - * Options for sampling the workload trace. - */ - private class SamplingOptions : OptionGroup() { - /** - * The fraction of VMs to sample - */ - val fraction by option("--sampling-fraction", help = "fraction of the workload to sample") - .double() - .restrictTo(0.0001, 1.0) - .required() - - /** - * The seed for sampling the trace. - */ - val seed by option("--sampling-seed", help = "seed for sampling the workload") - .long() - .default(0) - } -} diff --git a/opendc-trace/opendc-trace-tools/build.gradle.kts b/opendc-trace/opendc-trace-tools/build.gradle.kts new file mode 100644 index 00000000..35190dba --- /dev/null +++ b/opendc-trace/opendc-trace-tools/build.gradle.kts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "Tools for working with workload traces" + +/* Build configuration */ +plugins { + `kotlin-conventions` + application +} + +application { + mainClass.set("org.opendc.trace.tools.TraceConverterKt") +} + +dependencies { + api(platform(projects.opendcPlatform)) + + implementation(projects.opendcTrace.opendcTraceParquet) + implementation(projects.opendcTrace.opendcTraceOpendc) + implementation(projects.opendcTrace.opendcTraceAzure) + implementation(projects.opendcTrace.opendcTraceBitbrains) + + implementation(libs.kotlin.logging) + implementation(libs.clikt) + + runtimeOnly(libs.log4j.slf4j) +} diff --git a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt new file mode 100644 index 00000000..322464cd --- /dev/null +++ b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.tools + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.groups.OptionGroup +import com.github.ajalt.clikt.parameters.groups.cooccurring +import com.github.ajalt.clikt.parameters.options.* +import com.github.ajalt.clikt.parameters.types.* +import mu.KotlinLogging +import org.apache.avro.generic.GenericData +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetWriter +import org.apache.parquet.hadoop.metadata.CompressionCodecName +import org.opendc.trace.* +import org.opendc.trace.azure.AzureTraceFormat +import org.opendc.trace.bitbrains.BitbrainsExTraceFormat +import org.opendc.trace.bitbrains.BitbrainsTraceFormat +import org.opendc.trace.opendc.OdcVmTraceFormat +import org.opendc.trace.util.parquet.LocalOutputFile +import java.io.File +import java.util.* +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.min +import kotlin.math.roundToLong + +/** + * A script to convert a trace in text format into a Parquet trace. + */ +public fun main(args: Array): Unit = TraceConverterCli().main(args) + +/** + * Represents the command for converting traces + */ +internal class TraceConverterCli : CliktCommand(name = "trace-converter") { + /** + * The logger instance for the converter. + */ + private val logger = KotlinLogging.logger {} + + /** + * The directory where the trace should be stored. + */ + private val output by option("-O", "--output", help = "path to store the trace") + .file(canBeFile = false, mustExist = false) + .defaultLazy { File("output") } + + /** + * The directory where the input trace is located. + */ + private val input by argument("input", help = "path to the input trace") + .file(canBeFile = false) + + /** + * The input format of the trace. + */ + private val format by option("-f", "--format", help = "input format of trace") + .choice( + "solvinity" to BitbrainsExTraceFormat(), + "bitbrains" to BitbrainsTraceFormat(), + "azure" to AzureTraceFormat() + ) + .required() + + /** + * The sampling options. + */ + private val samplingOptions by SamplingOptions().cooccurring() + + override fun run() { + val metaParquet = File(output, "meta.parquet") + val traceParquet = File(output, "trace.parquet") + + if (metaParquet.exists()) { + metaParquet.delete() + } + if (traceParquet.exists()) { + traceParquet.delete() + } + + val trace = format.open(input.toURI().toURL()) + + logger.info { "Building resources table" } + + val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) + .withSchema(OdcVmTraceFormat.RESOURCES_SCHEMA) + .withCompressionCodec(CompressionCodecName.ZSTD) + .enablePageWriteChecksum() + .build() + + val selectedVms = metaWriter.use { convertResources(trace, it) } + + if (selectedVms.isEmpty()) { + logger.warn { "No VMs selected" } + return + } + + logger.info { "Wrote ${selectedVms.size} rows" } + logger.info { "Building resource states table" } + + val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) + .withSchema(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) + .withCompressionCodec(CompressionCodecName.ZSTD) + .withDictionaryEncoding("id", true) + .withBloomFilterEnabled("id", true) + .withBloomFilterNDV("id", selectedVms.size.toLong()) + .enableValidation() + .build() + + val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } + logger.info { "Wrote $statesCount rows" } + } + + /** + * Convert the resources table for the trace. + */ + private fun convertResources(trace: Trace, writer: ParquetWriter): Set { + val random = samplingOptions?.let { Random(it.seed) } + val samplingFraction = samplingOptions?.fraction ?: 1.0 + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + var hasNextRow = reader.nextRow() + val selectedVms = mutableSetOf() + + while (hasNextRow) { + var id: String + var numCpus = Int.MIN_VALUE + var memCapacity = Double.MIN_VALUE + var memUsage = Double.MIN_VALUE + var startTime = Long.MAX_VALUE + var stopTime = Long.MIN_VALUE + + do { + id = reader.get(RESOURCE_STATE_ID) + + val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + startTime = min(startTime, timestamp) + stopTime = max(stopTime, timestamp) + + numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_CPU_COUNT)) + + memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) + if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { + memUsage = max(memUsage, reader.getDouble(RESOURCE_STATE_MEM_USAGE)) + } + + hasNextRow = reader.nextRow() + } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) + + // Sample only a fraction of the VMs + if (random != null && random.nextDouble() > samplingFraction) { + continue + } + + val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCES_SCHEMA) + + builder["id"] = id + builder["start_time"] = startTime + builder["stop_time"] = stopTime + builder["cpu_count"] = numCpus + builder["mem_capacity"] = max(memCapacity, memUsage).roundToLong() + + logger.info { "Selecting VM $id" } + + writer.write(builder.build()) + selectedVms.add(id) + } + + return selectedVms + } + + /** + * Convert the resource states table for the trace. + */ + private fun convertResourceStates(trace: Trace, writer: ParquetWriter, selectedVms: Set): Int { + val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + + var hasNextRow = reader.nextRow() + var count = 0 + var lastId: String? = null + var lastTimestamp = 0L + + while (hasNextRow) { + val id = reader.get(RESOURCE_STATE_ID) + + if (id !in selectedVms) { + hasNextRow = reader.nextRow() + continue + } + + val cpuCount = reader.getInt(RESOURCE_STATE_CPU_COUNT) + val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) + + val startTimestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + var timestamp = startTimestamp + var duration: Long + + // Check whether the previous entry is from a different VM + if (id != lastId) { + lastTimestamp = timestamp - 5 * 60 * 1000L + } + + do { + timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() + + duration = timestamp - lastTimestamp + hasNextRow = reader.nextRow() + + if (!hasNextRow) { + break + } + + val shouldContinue = id == reader.get(RESOURCE_STATE_ID) && + abs(cpuUsage - reader.getDouble(RESOURCE_STATE_CPU_USAGE)) < 0.01 && + cpuCount == reader.getInt(RESOURCE_STATE_CPU_COUNT) + } while (shouldContinue) + + val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) + + builder["id"] = id + builder["timestamp"] = startTimestamp + builder["duration"] = duration + builder["cpu_count"] = cpuCount + builder["cpu_usage"] = cpuUsage + + writer.write(builder.build()) + + count++ + + lastId = id + lastTimestamp = timestamp + } + + return count + } + + /** + * Options for sampling the workload trace. + */ + private class SamplingOptions : OptionGroup() { + /** + * The fraction of VMs to sample + */ + val fraction by option("--sampling-fraction", help = "fraction of the workload to sample") + .double() + .restrictTo(0.0001, 1.0) + .required() + + /** + * The seed for sampling the trace. + */ + val seed by option("--sampling-seed", help = "seed for sampling the workload") + .long() + .default(0) + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 26bd0b11..587f1cb2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -54,6 +54,7 @@ include(":opendc-trace:opendc-trace-bitbrains") include(":opendc-trace:opendc-trace-azure") include(":opendc-trace:opendc-trace-opendc") include(":opendc-trace:opendc-trace-parquet") +include(":opendc-trace:opendc-trace-tools") include(":opendc-harness:opendc-harness-api") include(":opendc-harness:opendc-harness-engine") include(":opendc-harness:opendc-harness-cli") -- cgit v1.2.3 From 76a0f8889a4990108bc7906556dec6381647404b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 19 Sep 2021 13:59:33 +0200 Subject: refactor(simulator): Remove dependency on SnakeYaml This change removes the dependency on SnakeYaml for the simulator. It was only required for a very small component of the simulator and therefore does not justify bringing in such a dependency. --- gradle/libs.versions.toml | 2 -- opendc-simulator/opendc-simulator-compute/build.gradle.kts | 1 - .../simulator/compute/power/InterpolationPowerModel.kt | 13 ------------- .../org/opendc/simulator/compute/power/PowerModelTest.kt | 3 ++- 4 files changed, 2 insertions(+), 17 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 11580338..82da905c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,6 @@ parquet = "1.12.0" progressbar = "0.9.0" sentry = "5.1.2" slf4j = "1.7.32" -yaml = "1.29" [libraries] # Kotlin @@ -58,7 +57,6 @@ jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module- jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } jackson-dataformat-csv = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-csv", version.ref = "jackson" } parquet = { module = "org.apache.parquet:parquet-avro", version.ref = "parquet" } -yaml = { module = "org.yaml:snakeyaml", version.ref = "yaml" } config = { module = "com.typesafe:config", version.ref = "config" } # HTTP client diff --git a/opendc-simulator/opendc-simulator-compute/build.gradle.kts b/opendc-simulator/opendc-simulator-compute/build.gradle.kts index 74384480..7d06ee62 100644 --- a/opendc-simulator/opendc-simulator-compute/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-compute/build.gradle.kts @@ -36,5 +36,4 @@ dependencies { api(projects.opendcSimulator.opendcSimulatorNetwork) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcUtils) - implementation(libs.yaml) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/InterpolationPowerModel.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/InterpolationPowerModel.kt index 0c995f06..2694700c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/InterpolationPowerModel.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/InterpolationPowerModel.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.compute.power -import org.yaml.snakeyaml.Yaml import kotlin.math.ceil import kotlin.math.floor import kotlin.math.max @@ -37,8 +36,6 @@ import kotlin.math.min * @see Machines used in the SPEC benchmark */ public class InterpolationPowerModel(private val powerValues: List) : PowerModel { - public constructor(hardwareName: String) : this(loadAveragePowerValue(hardwareName)) - public override fun computePower(utilization: Double): Double { val clampedUtilization = min(1.0, max(0.0, utilization)) val utilizationFlr = floor(clampedUtilization * 10).toInt() @@ -63,14 +60,4 @@ public class InterpolationPowerModel(private val powerValues: List) : Po * @return the power consumption for the given utilization percentage */ private fun getAveragePowerValue(index: Int): Double = powerValues[index] - - private companion object { - private fun loadAveragePowerValue(hardwareName: String, path: String = "spec_machines.yml"): List { - val content = this::class - .java.classLoader - .getResourceAsStream(path) - val hardwareToAveragePowerValues: Map> = Yaml().load(content) - return hardwareToAveragePowerValues.getOrDefault(hardwareName, listOf()) - } - } } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt index ac2ed303..7852534a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt @@ -61,7 +61,8 @@ internal class PowerModelTest { @Test fun `compute power draw by the SPEC benchmark model`() { - val powerModel = InterpolationPowerModel("IBMx3550M3_XeonX5675") + val ibm = listOf(58.4, 98.0, 109.0, 118.0, 128.0, 140.0, 153.0, 170.0, 189.0, 205.0, 222.0) + val powerModel = InterpolationPowerModel(ibm) assertAll( { assertEquals(58.4, powerModel.computePower(0.0)) }, -- cgit v1.2.3 From 55a4c8208cc44ac626f7b8c61a19d5ec725ec936 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 20 Sep 2021 11:48:18 +0200 Subject: refactor(trace): Unify columns of different tables This change unifies columns of different tables used by trace formats. This concretely means that instead of having columns specific per table (e.g., RESOURCE_ID and RESOURCE_STATE_ID), with this changes these columns are shared between the tables with a single definition (RESOURCE_ID). --- .../compute/workload/ComputeWorkloadLoader.kt | 4 +- .../kotlin/org/opendc/trace/ResourceColumns.kt | 22 +++++++-- .../org/opendc/trace/ResourceStateColumns.kt | 54 +++++----------------- .../main/kotlin/org/opendc/trace/TableColumns.kt | 33 ++----------- .../main/kotlin/org/opendc/trace/TaskColumns.kt | 28 ++++++----- .../opendc/trace/azure/AzureResourceStateTable.kt | 2 +- .../trace/azure/AzureResourceStateTableReader.kt | 4 +- .../org/opendc/trace/azure/AzureTraceFormatTest.kt | 2 +- .../bitbrains/BitbrainsExResourceStateTable.kt | 10 ++-- .../BitbrainsExResourceStateTableReader.kt | 26 +++++------ .../trace/bitbrains/BitbrainsResourceStateTable.kt | 8 ++-- .../bitbrains/BitbrainsResourceStateTableReader.kt | 22 ++++----- .../bitbrains/BitbrainsResourceTableReader.kt | 2 +- .../opendc/trace/opendc/OdcVmResourceStateTable.kt | 4 +- .../trace/opendc/OdcVmResourceStateTableReader.kt | 10 ++-- .../opendc/trace/opendc/OdcVmTraceFormatTest.kt | 2 +- .../org/opendc/trace/tools/TraceConverter.kt | 16 +++---- 17 files changed, 102 insertions(+), 147 deletions(-) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index c92b212f..8a2585ce 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -62,10 +62,10 @@ public class ComputeWorkloadLoader(private val baseDir: File) { return try { while (reader.nextRow()) { - val id = reader.get(RESOURCE_STATE_ID) + val id = reader.get(RESOURCE_ID) val time = reader.get(RESOURCE_STATE_TIMESTAMP) val duration = reader.get(RESOURCE_STATE_DURATION) - val cores = reader.getInt(RESOURCE_STATE_CPU_COUNT) + val cores = reader.getInt(RESOURCE_CPU_COUNT) val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) val fragment = SimTraceWorkload.Fragment( diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt index 219002e0..f1977945 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceColumns.kt @@ -29,28 +29,40 @@ import java.time.Instant * Identifier of the resource. */ @JvmField -public val RESOURCE_ID: TableColumn = stringColumn("resource:id") +public val RESOURCE_ID: TableColumn = column("resource:id") + +/** + * The cluster to which the resource belongs. + */ +@JvmField +public val RESOURCE_CLUSTER_ID: TableColumn = column("resource:cluster_id") /** * Start time for the resource. */ @JvmField -public val RESOURCE_START_TIME: TableColumn = TableColumn("resource:start_time", Instant::class.java) +public val RESOURCE_START_TIME: TableColumn = column("resource:start_time") /** * End time for the resource. */ @JvmField -public val RESOURCE_STOP_TIME: TableColumn = TableColumn("resource:stop_time", Instant::class.java) +public val RESOURCE_STOP_TIME: TableColumn = column("resource:stop_time") /** * Number of CPUs for the resource. */ @JvmField -public val RESOURCE_CPU_COUNT: TableColumn = intColumn("resource:cpu_count") +public val RESOURCE_CPU_COUNT: TableColumn = column("resource:cpu_count") + +/** + * Total CPU capacity of the resource in MHz. + */ +@JvmField +public val RESOURCE_CPU_CAPACITY: TableColumn = column("resource:cpu_capacity") /** * Memory capacity for the resource in KB. */ @JvmField -public val RESOURCE_MEM_CAPACITY: TableColumn = doubleColumn("resource:mem_capacity") +public val RESOURCE_MEM_CAPACITY: TableColumn = column("resource:mem_capacity") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt index b683923b..44762da5 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/ResourceStateColumns.kt @@ -26,104 +26,74 @@ package org.opendc.trace import java.time.Duration import java.time.Instant -/** - * Identifier of the resource. - */ -@JvmField -public val RESOURCE_STATE_ID: TableColumn = stringColumn("resource_state:id") - -/** - * The cluster to which the resource belongs. - */ -@JvmField -public val RESOURCE_STATE_CLUSTER_ID: TableColumn = stringColumn("resource_state:cluster_id") - /** * Timestamp for the state. */ @JvmField -public val RESOURCE_STATE_TIMESTAMP: TableColumn = TableColumn("resource_state:timestamp", Instant::class.java) +public val RESOURCE_STATE_TIMESTAMP: TableColumn = column("resource_state:timestamp") /** * Duration for the state. */ @JvmField -public val RESOURCE_STATE_DURATION: TableColumn = TableColumn("resource_state:duration", Duration::class.java) +public val RESOURCE_STATE_DURATION: TableColumn = column("resource_state:duration") /** * A flag to indicate that the resource is powered on. */ @JvmField -public val RESOURCE_STATE_POWERED_ON: TableColumn = booleanColumn("resource_state:powered_on") - -/** - * Number of CPUs for the resource. - */ -@JvmField -public val RESOURCE_STATE_CPU_COUNT: TableColumn = intColumn("resource_state:cpu_count") - -/** - * Total CPU capacity of the resource in MHz. - */ -@JvmField -public val RESOURCE_STATE_CPU_CAPACITY: TableColumn = doubleColumn("resource_state:cpu_capacity") +public val RESOURCE_STATE_POWERED_ON: TableColumn = column("resource_state:powered_on") /** * Total CPU usage of the resource in MHz. */ @JvmField -public val RESOURCE_STATE_CPU_USAGE: TableColumn = doubleColumn("resource_state:cpu_usage") +public val RESOURCE_STATE_CPU_USAGE: TableColumn = column("resource_state:cpu_usage") /** * Total CPU usage of the resource in percentage. */ @JvmField -public val RESOURCE_STATE_CPU_USAGE_PCT: TableColumn = doubleColumn("resource_state:cpu_usage_pct") +public val RESOURCE_STATE_CPU_USAGE_PCT: TableColumn = column("resource_state:cpu_usage_pct") /** * Total CPU demand of the resource in MHz. */ @JvmField -public val RESOURCE_STATE_CPU_DEMAND: TableColumn = doubleColumn("resource_state:cpu_demand") +public val RESOURCE_STATE_CPU_DEMAND: TableColumn = column("resource_state:cpu_demand") /** * CPU ready percentage. */ @JvmField -public val RESOURCE_STATE_CPU_READY_PCT: TableColumn = doubleColumn("resource_state:cpu_ready_pct") - -/** - * Memory capacity of the resource in KB. - */ -@JvmField -public val RESOURCE_STATE_MEM_CAPACITY: TableColumn = doubleColumn("resource_state:mem_capacity") +public val RESOURCE_STATE_CPU_READY_PCT: TableColumn = column("resource_state:cpu_ready_pct") /** * Memory usage of the resource in KB. */ @JvmField -public val RESOURCE_STATE_MEM_USAGE: TableColumn = doubleColumn("resource_state:mem_usage") +public val RESOURCE_STATE_MEM_USAGE: TableColumn = column("resource_state:mem_usage") /** * Disk read throughput of the resource in KB/s. */ @JvmField -public val RESOURCE_STATE_DISK_READ: TableColumn = doubleColumn("resource_state:disk_read") +public val RESOURCE_STATE_DISK_READ: TableColumn = column("resource_state:disk_read") /** * Disk write throughput of the resource in KB/s. */ @JvmField -public val RESOURCE_STATE_DISK_WRITE: TableColumn = doubleColumn("resource_state:disk_write") +public val RESOURCE_STATE_DISK_WRITE: TableColumn = column("resource_state:disk_write") /** * Network receive throughput of the resource in KB/s. */ @JvmField -public val RESOURCE_STATE_NET_RX: TableColumn = doubleColumn("resource_state:net_rx") +public val RESOURCE_STATE_NET_RX: TableColumn = column("resource_state:net_rx") /** * Network transmit throughput of the resource in KB/s. */ @JvmField -public val RESOURCE_STATE_NET_TX: TableColumn = doubleColumn("resource_state:net_tx") +public val RESOURCE_STATE_NET_TX: TableColumn = column("resource_state:net_tx") diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt index 64920498..31a58360 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableColumns.kt @@ -24,36 +24,11 @@ package org.opendc.trace /** - * Construct a [TableColumn] with [Any] type. + * Construct a [TableColumn] with the specified [name] and type [T]. */ -public fun objectColumn(name: String): TableColumn = TableColumn(name, Any::class.java) +public inline fun column(name: String): TableColumn = column(name, T::class.java) /** - * Construct a [TableColumn] with a [String] type. + * Construct a [TableColumn] with the specified [name] and [type]. */ -public fun stringColumn(name: String): TableColumn = TableColumn(name, String::class.java) - -/** - * Construct a [TableColumn] with a [Number] type. - */ -public fun numberColumn(name: String): TableColumn = TableColumn(name, Number::class.java) - -/** - * Construct a [TableColumn] with an [Int] type. - */ -public fun intColumn(name: String): TableColumn = TableColumn(name, Int::class.java) - -/** - * Construct a [TableColumn] with a [Long] type. - */ -public fun longColumn(name: String): TableColumn = TableColumn(name, Long::class.java) - -/** - * Construct a [TableColumn] with a [Double] type. - */ -public fun doubleColumn(name: String): TableColumn = TableColumn(name, Double::class.java) - -/** - * Construct a [TableColumn] with a [Boolean] type. - */ -public fun booleanColumn(name: String): TableColumn = TableColumn(name, Boolean::class.java) +public fun column(name: String, type: Class): TableColumn = TableColumn(name, type) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt index 46920dce..d103bce4 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TaskColumns.kt @@ -30,72 +30,70 @@ import java.time.Instant * A column containing the task identifier. */ @JvmField -public val TASK_ID: TableColumn = stringColumn("task:id") +public val TASK_ID: TableColumn = column("task:id") /** * A column containing the identifier of the workflow. */ @JvmField -public val TASK_WORKFLOW_ID: TableColumn = stringColumn("task:workflow_id") +public val TASK_WORKFLOW_ID: TableColumn = column("task:workflow_id") /** - * A column containing the submit time of the task. + * A column containing the submission time of the task. */ @JvmField -public val TASK_SUBMIT_TIME: TableColumn = TableColumn("task:submit_time", type = Instant::class.java) +public val TASK_SUBMIT_TIME: TableColumn = column("task:submit_time") /** * A column containing the wait time of the task. */ @JvmField -public val TASK_WAIT_TIME: TableColumn = TableColumn("task:wait_time", type = Instant::class.java) +public val TASK_WAIT_TIME: TableColumn = column("task:wait_time") /** * A column containing the runtime time of the task. */ @JvmField -public val TASK_RUNTIME: TableColumn = TableColumn("task:runtime", type = Duration::class.java) +public val TASK_RUNTIME: TableColumn = column("task:runtime") /** * A column containing the parents of a task. */ -@Suppress("UNCHECKED_CAST") @JvmField -public val TASK_PARENTS: TableColumn> = TableColumn("task:parents", type = Set::class.java as Class>) +public val TASK_PARENTS: TableColumn> = column("task:parents") /** * A column containing the children of a task. */ -@Suppress("UNCHECKED_CAST") @JvmField -public val TASK_CHILDREN: TableColumn> = TableColumn("task:children", type = Set::class.java as Class>) +public val TASK_CHILDREN: TableColumn> = column("task:children") /** * A column containing the requested CPUs of a task. */ @JvmField -public val TASK_REQ_NCPUS: TableColumn = intColumn("task:req_ncpus") +public val TASK_REQ_NCPUS: TableColumn = column("task:req_ncpus") /** * A column containing the allocated CPUs of a task. */ @JvmField -public val TASK_ALLOC_NCPUS: TableColumn = intColumn("task:alloc_ncpus") +public val TASK_ALLOC_NCPUS: TableColumn = column("task:alloc_ncpus") /** * A column containing the status of a task. */ @JvmField -public val TASK_STATUS: TableColumn = intColumn("task:status") +public val TASK_STATUS: TableColumn = column("task:status") /** * A column containing the group id of a task. */ @JvmField -public val TASK_GROUP_ID: TableColumn = intColumn("task:group_id") +public val TASK_GROUP_ID: TableColumn = column("task:group_id") /** * A column containing the user id of a task. */ @JvmField -public val TASK_USER_ID: TableColumn = intColumn("task:user_id") +public val TASK_USER_ID: TableColumn = column("task:user_id") diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt index 84c9b347..e6b89465 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt @@ -47,7 +47,7 @@ internal class AzureResourceStateTable(private val factory: CsvFactory, path: Pa override val isSynthetic: Boolean = false override val columns: List> = listOf( - RESOURCE_STATE_ID, + RESOURCE_ID, RESOURCE_STATE_TIMESTAMP, RESOURCE_STATE_CPU_USAGE_PCT ) diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt index c17a17ab..6c1cb770 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt @@ -62,7 +62,7 @@ internal class AzureResourceStateTableReader(private val parser: CsvParser) : Ta override fun hasColumn(column: TableColumn<*>): Boolean { return when (column) { - RESOURCE_STATE_ID -> true + RESOURCE_ID -> true RESOURCE_STATE_TIMESTAMP -> true RESOURCE_STATE_CPU_USAGE_PCT -> true else -> false @@ -71,7 +71,7 @@ internal class AzureResourceStateTableReader(private val parser: CsvParser) : Ta override fun get(column: TableColumn): T { val res: Any? = when (column) { - RESOURCE_STATE_ID -> id + RESOURCE_ID -> id RESOURCE_STATE_TIMESTAMP -> timestamp RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct else -> throw IllegalArgumentException("Invalid column") diff --git a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt index e5735f0d..2c1a2125 100644 --- a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt @@ -103,7 +103,7 @@ class AzureTraceFormatTest { assertAll( { assertTrue(reader.nextRow()) }, - { assertEquals("+ZcrOp5/c/fJ6mVgP5qMZlOAGDwyjaaDNM0WoWOt2IDb47gT0UwK9lFwkPQv3C7Q", reader.get(RESOURCE_STATE_ID)) }, + { assertEquals("+ZcrOp5/c/fJ6mVgP5qMZlOAGDwyjaaDNM0WoWOt2IDb47gT0UwK9lFwkPQv3C7Q", reader.get(RESOURCE_ID)) }, { assertEquals(0, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) }, { assertEquals(2.86979, reader.getDouble(RESOURCE_STATE_CPU_USAGE_PCT), 0.01) } ) diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt index 4a60dff3..44a6c26e 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt @@ -47,16 +47,16 @@ internal class BitbrainsExResourceStateTable(path: Path) : Table { override val isSynthetic: Boolean = false override val columns: List> = listOf( - RESOURCE_STATE_ID, - RESOURCE_STATE_CLUSTER_ID, + RESOURCE_ID, + RESOURCE_CLUSTER_ID, RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_CPU_COUNT, - RESOURCE_STATE_CPU_CAPACITY, + RESOURCE_CPU_COUNT, + RESOURCE_CPU_CAPACITY, RESOURCE_STATE_CPU_USAGE, RESOURCE_STATE_CPU_USAGE_PCT, RESOURCE_STATE_CPU_DEMAND, RESOURCE_STATE_CPU_READY_PCT, - RESOURCE_STATE_MEM_CAPACITY, + RESOURCE_MEM_CAPACITY, RESOURCE_STATE_DISK_READ, RESOURCE_STATE_DISK_WRITE, ) diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt index f1cf7307..5619e839 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt @@ -90,16 +90,16 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR override fun hasColumn(column: TableColumn<*>): Boolean { return when (column) { - RESOURCE_STATE_ID -> true - RESOURCE_STATE_CLUSTER_ID -> true + RESOURCE_ID -> true + RESOURCE_CLUSTER_ID -> true RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_CPU_COUNT -> true - RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_CPU_COUNT -> true + RESOURCE_CPU_CAPACITY -> true RESOURCE_STATE_CPU_USAGE -> true RESOURCE_STATE_CPU_USAGE_PCT -> true RESOURCE_STATE_CPU_DEMAND -> true RESOURCE_STATE_CPU_READY_PCT -> true - RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_MEM_CAPACITY -> true RESOURCE_STATE_DISK_READ -> true RESOURCE_STATE_DISK_WRITE -> true else -> false @@ -108,14 +108,14 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR override fun get(column: TableColumn): T { val res: Any? = when (column) { - RESOURCE_STATE_ID -> id - RESOURCE_STATE_CLUSTER_ID -> cluster + RESOURCE_ID -> id + RESOURCE_CLUSTER_ID -> cluster RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_CPU_COUNT -> getInt(RESOURCE_STATE_CPU_COUNT) - RESOURCE_STATE_CPU_CAPACITY -> getDouble(RESOURCE_STATE_CPU_CAPACITY) + RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) + RESOURCE_CPU_CAPACITY -> getDouble(RESOURCE_CPU_CAPACITY) RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) - RESOURCE_STATE_MEM_CAPACITY -> getDouble(RESOURCE_STATE_MEM_CAPACITY) + RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) else -> throw IllegalArgumentException("Invalid column") @@ -134,7 +134,7 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_STATE_CPU_COUNT -> cpuCores + RESOURCE_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } @@ -145,11 +145,11 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR override fun getDouble(column: TableColumn): Double { return when (column) { - RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_CPU_CAPACITY -> cpuCapacity RESOURCE_STATE_CPU_USAGE -> cpuUsage RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity RESOURCE_STATE_CPU_DEMAND -> cpuDemand - RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_MEM_CAPACITY -> memCapacity RESOURCE_STATE_DISK_READ -> diskRead RESOURCE_STATE_DISK_WRITE -> diskWrite else -> throw IllegalArgumentException("Invalid column") diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index 7241b18b..f68e61dc 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -48,13 +48,13 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path override val isSynthetic: Boolean = false override val columns: List> = listOf( - RESOURCE_STATE_ID, + RESOURCE_ID, RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_CPU_COUNT, - RESOURCE_STATE_CPU_CAPACITY, + RESOURCE_CPU_COUNT, + RESOURCE_CPU_CAPACITY, RESOURCE_STATE_CPU_USAGE, RESOURCE_STATE_CPU_USAGE_PCT, - RESOURCE_STATE_MEM_CAPACITY, + RESOURCE_MEM_CAPACITY, RESOURCE_STATE_MEM_USAGE, RESOURCE_STATE_DISK_READ, RESOURCE_STATE_DISK_WRITE, diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt index 56e66f5c..54be5dea 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt @@ -113,13 +113,13 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun hasColumn(column: TableColumn<*>): Boolean { return when (column) { - RESOURCE_STATE_ID -> true + RESOURCE_ID -> true RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_CPU_COUNT -> true - RESOURCE_STATE_CPU_CAPACITY -> true + RESOURCE_CPU_COUNT -> true + RESOURCE_CPU_CAPACITY -> true RESOURCE_STATE_CPU_USAGE -> true RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_STATE_MEM_CAPACITY -> true + RESOURCE_MEM_CAPACITY -> true RESOURCE_STATE_MEM_USAGE -> true RESOURCE_STATE_DISK_READ -> true RESOURCE_STATE_DISK_WRITE -> true @@ -131,13 +131,13 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun get(column: TableColumn): T { val res: Any? = when (column) { - RESOURCE_STATE_ID -> partition + RESOURCE_ID -> partition RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_CPU_COUNT -> cpuCores - RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_CPU_COUNT -> cpuCores + RESOURCE_CPU_CAPACITY -> cpuCapacity RESOURCE_STATE_CPU_USAGE -> cpuUsage RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_MEM_CAPACITY -> memCapacity RESOURCE_STATE_MEM_USAGE -> memUsage RESOURCE_STATE_DISK_READ -> diskRead RESOURCE_STATE_DISK_WRITE -> diskWrite @@ -156,7 +156,7 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun getInt(column: TableColumn): Int { return when (column) { - RESOURCE_STATE_CPU_COUNT -> cpuCores + RESOURCE_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } @@ -167,10 +167,10 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, override fun getDouble(column: TableColumn): Double { return when (column) { - RESOURCE_STATE_CPU_CAPACITY -> cpuCapacity + RESOURCE_CPU_CAPACITY -> cpuCapacity RESOURCE_STATE_CPU_USAGE -> cpuUsage RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - RESOURCE_STATE_MEM_CAPACITY -> memCapacity + RESOURCE_MEM_CAPACITY -> memCapacity RESOURCE_STATE_MEM_USAGE -> memUsage RESOURCE_STATE_DISK_READ -> diskRead RESOURCE_STATE_DISK_WRITE -> diskWrite diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt index c02dc5ae..146c04f0 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt @@ -49,7 +49,7 @@ internal class BitbrainsResourceTableReader(private val factory: CsvFactory, vms continue } - id = reader.get(RESOURCE_STATE_ID) + id = reader.get(RESOURCE_ID) return true } finally { reader.close() diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt index bee4ba7e..39613070 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt @@ -35,10 +35,10 @@ internal class OdcVmResourceStateTable(private val path: Path) : Table { override val isSynthetic: Boolean = false override val columns: List> = listOf( - RESOURCE_STATE_ID, + RESOURCE_ID, RESOURCE_STATE_TIMESTAMP, RESOURCE_STATE_DURATION, - RESOURCE_STATE_CPU_COUNT, + RESOURCE_CPU_COUNT, RESOURCE_STATE_CPU_USAGE, ) diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt index df3bcfa6..e4b18735 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt @@ -57,10 +57,10 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea override fun hasColumn(column: TableColumn<*>): Boolean { return when (column) { - RESOURCE_STATE_ID -> true + RESOURCE_ID -> true RESOURCE_STATE_TIMESTAMP -> true RESOURCE_STATE_DURATION -> true - RESOURCE_STATE_CPU_COUNT -> true + RESOURCE_CPU_COUNT -> true RESOURCE_STATE_CPU_USAGE -> true else -> false } @@ -71,10 +71,10 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea @Suppress("UNCHECKED_CAST") val res: Any = when (column) { - RESOURCE_STATE_ID -> record[COL_ID].toString() + RESOURCE_ID -> record[COL_ID].toString() RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record[COL_TIMESTAMP] as Long) RESOURCE_STATE_DURATION -> Duration.ofMillis(record[COL_DURATION] as Long) - RESOURCE_STATE_CPU_COUNT -> getInt(RESOURCE_STATE_CPU_COUNT) + RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) else -> throw IllegalArgumentException("Invalid column") } @@ -90,7 +90,7 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea override fun getInt(column: TableColumn): Int { val record = checkNotNull(record) { "Reader in invalid state" } return when (column) { - RESOURCE_STATE_CPU_COUNT -> record[COL_CPU_COUNT] as Int + RESOURCE_CPU_COUNT -> record[COL_CPU_COUNT] as Int else -> throw IllegalArgumentException("Invalid column") } } diff --git a/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt index 42eb369e..9fb6028d 100644 --- a/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt @@ -111,7 +111,7 @@ internal class OdcVmTraceFormatTest { assertAll( { assertTrue(reader.nextRow()) }, - { assertEquals("1019", reader.get(RESOURCE_STATE_ID)) }, + { assertEquals("1019", reader.get(RESOURCE_ID)) }, { assertEquals(1376314846, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) }, { assertEquals(0.0, reader.getDouble(RESOURCE_STATE_CPU_USAGE), 0.01) } ) diff --git a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt index 322464cd..0b089904 100644 --- a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt +++ b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt @@ -154,21 +154,21 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { var stopTime = Long.MIN_VALUE do { - id = reader.get(RESOURCE_STATE_ID) + id = reader.get(RESOURCE_ID) val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() startTime = min(startTime, timestamp) stopTime = max(stopTime, timestamp) - numCpus = max(numCpus, reader.getInt(RESOURCE_STATE_CPU_COUNT)) + numCpus = max(numCpus, reader.getInt(RESOURCE_CPU_COUNT)) - memCapacity = max(memCapacity, reader.getDouble(RESOURCE_STATE_MEM_CAPACITY)) + memCapacity = max(memCapacity, reader.getDouble(RESOURCE_MEM_CAPACITY)) if (reader.hasColumn(RESOURCE_STATE_MEM_USAGE)) { memUsage = max(memUsage, reader.getDouble(RESOURCE_STATE_MEM_USAGE)) } hasNextRow = reader.nextRow() - } while (hasNextRow && id == reader.get(RESOURCE_STATE_ID)) + } while (hasNextRow && id == reader.get(RESOURCE_ID)) // Sample only a fraction of the VMs if (random != null && random.nextDouble() > samplingFraction) { @@ -204,14 +204,14 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { var lastTimestamp = 0L while (hasNextRow) { - val id = reader.get(RESOURCE_STATE_ID) + val id = reader.get(RESOURCE_ID) if (id !in selectedVms) { hasNextRow = reader.nextRow() continue } - val cpuCount = reader.getInt(RESOURCE_STATE_CPU_COUNT) + val cpuCount = reader.getInt(RESOURCE_CPU_COUNT) val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) val startTimestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli() @@ -233,9 +233,9 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { break } - val shouldContinue = id == reader.get(RESOURCE_STATE_ID) && + val shouldContinue = id == reader.get(RESOURCE_ID) && abs(cpuUsage - reader.getDouble(RESOURCE_STATE_CPU_USAGE)) < 0.01 && - cpuCount == reader.getInt(RESOURCE_STATE_CPU_COUNT) + cpuCount == reader.getInt(RESOURCE_CPU_COUNT) } while (shouldContinue) val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) -- cgit v1.2.3 From 768bfa0d2ae763e359d74612385ce43c41afb432 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 20 Sep 2021 15:12:10 +0200 Subject: feat(trace): Support column lookup via index This change adds support for looking up the column value through the column index. This enables faster lookup when processing very large traces. --- .../main/kotlin/org/opendc/trace/TableReader.kt | 107 ++++++++++++++++- .../org/opendc/trace/util/CompositeTableReader.kt | 110 +++++++++++++++++ .../opendc/trace/azure/AzureResourceStateTable.kt | 54 +-------- .../trace/azure/AzureResourceStateTableReader.kt | 48 ++++---- .../opendc/trace/azure/AzureResourceTableReader.kt | 62 +++++----- .../bitbrains/BitbrainsExResourceStateTable.kt | 54 +-------- .../BitbrainsExResourceStateTableReader.kt | 94 +++++++-------- .../trace/bitbrains/BitbrainsResourceStateTable.kt | 54 +-------- .../bitbrains/BitbrainsResourceStateTableReader.kt | 104 ++++++++-------- .../bitbrains/BitbrainsResourceTableReader.kt | 33 +++--- .../org/opendc/trace/gwf/GwfTaskTableReader.kt | 69 ++++++----- .../trace/opendc/OdcVmResourceStateTableReader.kt | 82 +++++++------ .../trace/opendc/OdcVmResourceTableReader.kt | 82 +++++++------ .../org/opendc/trace/swf/SwfTaskTableReader.kt | 72 +++++------ .../trace/wfformat/WfFormatTaskTableReader.kt | 62 +++++----- opendc-trace/opendc-trace-wtf/build.gradle.kts | 2 + .../org/opendc/trace/wtf/WtfTaskTableReader.kt | 132 +++++++++++++++------ 17 files changed, 688 insertions(+), 533 deletions(-) create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt index b5e7669f..8a796e6c 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableReader.kt @@ -33,35 +33,130 @@ public interface TableReader : AutoCloseable { */ public fun nextRow(): Boolean + /** + * Resolve the index of the specified [column] for this reader. + * + * @param column The column to lookup. + * @return The zero-based index of the column or a negative value if the column is not present in this table. + */ + public fun resolve(column: TableColumn<*>): Int + /** * Determine whether the [TableReader] supports the specified [column]. */ - public fun hasColumn(column: TableColumn<*>): Boolean + public fun hasColumn(column: TableColumn<*>): Boolean = resolve(column) >= 0 + + /** + * Determine whether the specified [column] has a `null` value for the current row. + * + * @param index The zero-based index of the column to check for a null value. + * @throws IllegalArgumentException if the column index is not valid for this reader. + * @return `true` if the column value for the current value has a `null` value, `false` otherwise. + */ + public fun isNull(index: Int): Boolean + + /** + * Obtain the object value of the column with the specified [index]. + * + * @param index The zero-based index of the column to obtain the value for. + * @throws IllegalArgumentException if the column index is not valid for this reader. + * @return The object value of the column. + */ + public fun get(index: Int): Any? + + /** + * Obtain the boolean value of the column with the specified [index]. + * + * @param index The zero-based index of the column to obtain the value for. + * @throws IllegalArgumentException if the column index is not valid for this reader. + * @return The boolean value of the column or `false` if the column is `null`. + */ + public fun getBoolean(index: Int): Boolean + + /** + * Obtain the integer value of the column with the specified [index]. + * + * @param index The zero-based index of the column to obtain the value for. + * @throws IllegalArgumentException if the column index is not valid for this reader. + * @return The integer value of the column or `0` if the column is `null`. + */ + public fun getInt(index: Int): Int + + /** + * Obtain the double value of the column with the specified [index]. + * + * @param index The zero-based index of the column to obtain the value for. + * @throws IllegalArgumentException if the column index is not valid for this reader. + * @return The long value of the column or `0` if the column is `null`. + */ + public fun getLong(index: Int): Long + + /** + * Obtain the double value of the column with the specified [index]. + * + * @param index The zero-based index of the column to obtain the value for. + * @throws IllegalArgumentException if the column index is not valid for this reader. + * @return The double value of the column or [Double.NaN] if the column is `null`. + */ + public fun getDouble(index: Int): Double + + /** + * Determine whether the specified [column] has a `null` value for the current row. + * + * @param column The column to lookup. + * @throws IllegalArgumentException if the column is not valid for this table. + * @return `true` if the column value for the current value has a `null` value, `false` otherwise. + */ + public fun isNull(column: TableColumn<*>): Boolean = isNull(resolve(column)) /** * Obtain the value of the current column with type [T]. + * + * @param column The column to obtain the value for. + * @throws IllegalArgumentException if the column is not valid for this reader. + * @return The object value of the column. */ - public fun get(column: TableColumn): T + public fun get(column: TableColumn): T { + // This cast should always succeed since the resolve the index of the typed column + @Suppress("UNCHECKED_CAST") + return get(resolve(column)) as T + } /** * Read the specified [column] as boolean. + * + * @param column The column to obtain the value for. + * @throws IllegalArgumentException if the column is not valid for this reader. + * @return The boolean value of the column or `false` if the column is `null`. */ - public fun getBoolean(column: TableColumn): Boolean + public fun getBoolean(column: TableColumn): Boolean = getBoolean(resolve(column)) /** * Read the specified [column] as integer. + * + * @param column The column to obtain the value for. + * @throws IllegalArgumentException if the column is not valid for this reader. + * @return The integer value of the column or `0` if the column is `null`. */ - public fun getInt(column: TableColumn): Int + public fun getInt(column: TableColumn): Int = getInt(resolve(column)) /** * Read the specified [column] as long. + * + * @param column The column to obtain the value for. + * @throws IllegalArgumentException if the column is not valid for this reader. + * @return The long value of the column or `0` if the column is `null`. */ - public fun getLong(column: TableColumn): Long + public fun getLong(column: TableColumn): Long = getLong(resolve(column)) /** * Read the specified [column] as double. + * + * @param column The column to obtain the value for. + * @throws IllegalArgumentException if the column is not valid for this reader. + * @return The double value of the column or [Double.NaN] if the column is `null`. */ - public fun getDouble(column: TableColumn): Double + public fun getDouble(column: TableColumn): Double = getDouble(resolve(column)) /** * Closes the reader so that no further iteration or data access can be made. diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt new file mode 100644 index 00000000..dafc0798 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/util/CompositeTableReader.kt @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.util + +import org.opendc.trace.TableColumn +import org.opendc.trace.TableReader + +/** + * A helper class to chain multiple [TableReader]s. + */ +public abstract class CompositeTableReader : TableReader { + /** + * A flag to indicate that the reader has starting, meaning the user called [nextRow] at least once + * (and in turn [nextReader]). + */ + private var hasStarted = false + + /** + * The active [TableReader] instance. + */ + private var delegate: TableReader? = null + + /** + * Obtain the next [TableReader] instance to read from or `null` if there are no more readers to read from. + */ + protected abstract fun nextReader(): TableReader? + + override fun nextRow(): Boolean { + if (!hasStarted) { + assert(delegate == null) { "Duplicate initialization" } + delegate = nextReader() + hasStarted = true + } + + var delegate = delegate + + while (delegate != null) { + if (delegate.nextRow()) { + break + } + + delegate.close() + delegate = nextReader() + this.delegate = delegate + } + + return delegate != null + } + + override fun resolve(column: TableColumn<*>): Int { + val delegate = delegate + return delegate?.resolve(column) ?: -1 + } + + override fun isNull(index: Int): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.isNull(index) + } + + override fun get(index: Int): Any? { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.get(index) + } + + override fun getBoolean(index: Int): Boolean { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getBoolean(index) + } + + override fun getInt(index: Int): Int { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getInt(index) + } + + override fun getLong(index: Int): Long { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getLong(index) + } + + override fun getDouble(index: Int): Double { + val delegate = checkNotNull(delegate) { "Invalid reader state" } + return delegate.getDouble(index) + } + + override fun close() { + delegate?.close() + } + + override fun toString(): String = "CompositeTableReader" +} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt index e6b89465..8f2f5cc9 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt @@ -24,6 +24,7 @@ package org.opendc.trace.azure import com.fasterxml.jackson.dataformat.csv.CsvFactory import org.opendc.trace.* +import org.opendc.trace.util.CompositeTableReader import java.nio.file.Files import java.nio.file.Path import java.util.stream.Collectors @@ -55,57 +56,8 @@ internal class AzureResourceStateTable(private val factory: CsvFactory, path: Pa override fun newReader(): TableReader { val it = partitions.iterator() - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - this.delegate = delegate - } - - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { + return object : CompositeTableReader() { + override fun nextReader(): TableReader? { return if (it.hasNext()) { val (_, path) = it.next() return AzureResourceStateTableReader(factory.createParser(path.toFile())) diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt index 6c1cb770..da8181fe 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTableReader.kt @@ -60,42 +60,37 @@ internal class AzureResourceStateTableReader(private val parser: CsvParser) : Ta return true } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + require(index in 0..columns.size) { "Invalid column index" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> id - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - else -> throw IllegalArgumentException("Invalid column") + override fun get(index: Int): Any? { + return when (index) { + COL_ID -> id + COL_TIMESTAMP -> timestamp + COL_CPU_USAGE_PCT -> cpuUsagePct + else -> throw IllegalArgumentException("Invalid column index") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { + override fun getInt(index: Int): Int { throw IllegalArgumentException("Invalid column") } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct + override fun getDouble(index: Int): Double { + return when (index) { + COL_CPU_USAGE_PCT -> cpuUsagePct else -> throw IllegalArgumentException("Invalid column") } } @@ -133,6 +128,15 @@ internal class AzureResourceStateTableReader(private val parser: CsvParser) : Ta cpuUsagePct = Double.NaN } + private val COL_ID = 0 + private val COL_TIMESTAMP = 1 + private val COL_CPU_USAGE_PCT = 2 + private val columns = mapOf( + RESOURCE_ID to COL_ID, + RESOURCE_STATE_TIMESTAMP to COL_TIMESTAMP, + RESOURCE_STATE_CPU_USAGE_PCT to COL_CPU_USAGE_PCT + ) + companion object { /** * The [CsvSchema] that is used to parse the trace. diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt index 5ea97483..a6352613 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTableReader.kt @@ -62,49 +62,42 @@ internal class AzureResourceTableReader(private val parser: CsvParser) : TableRe return true } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_CPU_COUNT -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + require(index in 0..columns.size) { "Invalid column index" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> id - RESOURCE_START_TIME -> startTime - RESOURCE_STOP_TIME -> stopTime - RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) + override fun get(index: Int): Any? { + return when (index) { + COL_ID -> id + COL_START_TIME -> startTime + COL_STOP_TIME -> stopTime + COL_CPU_COUNT -> getInt(index) + COL_MEM_CAPACITY -> getDouble(index) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_CPU_COUNT -> cpuCores + override fun getInt(index: Int): Int { + return when (index) { + COL_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_MEM_CAPACITY -> memCapacity + override fun getDouble(index: Int): Double { + return when (index) { + COL_MEM_CAPACITY -> memCapacity else -> throw IllegalArgumentException("Invalid column") } } @@ -138,7 +131,7 @@ internal class AzureResourceTableReader(private val parser: CsvParser) : TableRe /** * Reset the state. */ - fun reset() { + private fun reset() { id = null startTime = null stopTime = null @@ -146,6 +139,19 @@ internal class AzureResourceTableReader(private val parser: CsvParser) : TableRe memCapacity = Double.NaN } + private val COL_ID = 0 + private val COL_START_TIME = 1 + private val COL_STOP_TIME = 2 + private val COL_CPU_COUNT = 3 + private val COL_MEM_CAPACITY = 4 + private val columns = mapOf( + RESOURCE_ID to COL_ID, + RESOURCE_START_TIME to COL_START_TIME, + RESOURCE_STOP_TIME to COL_STOP_TIME, + RESOURCE_CPU_COUNT to COL_CPU_COUNT, + RESOURCE_MEM_CAPACITY to COL_MEM_CAPACITY + ) + companion object { /** * The [CsvSchema] that is used to parse the trace. diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt index 44a6c26e..ab768608 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt @@ -23,6 +23,7 @@ package org.opendc.trace.bitbrains import org.opendc.trace.* +import org.opendc.trace.util.CompositeTableReader import java.nio.file.Files import java.nio.file.Path import java.util.stream.Collectors @@ -64,57 +65,8 @@ internal class BitbrainsExResourceStateTable(path: Path) : Table { override fun newReader(): TableReader { val it = partitions.iterator() - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - this.delegate = delegate - } - - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { + return object : CompositeTableReader() { + override fun nextReader(): TableReader? { return if (it.hasNext()) { val (_, path) = it.next() val reader = path.bufferedReader() diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt index 5619e839..c1b6f5ba 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTableReader.kt @@ -88,70 +88,53 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR return true } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_CLUSTER_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_CPU_COUNT -> true - RESOURCE_CPU_CAPACITY -> true - RESOURCE_STATE_CPU_USAGE -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_STATE_CPU_DEMAND -> true - RESOURCE_STATE_CPU_READY_PCT -> true - RESOURCE_MEM_CAPACITY -> true - RESOURCE_STATE_DISK_READ -> true - RESOURCE_STATE_DISK_WRITE -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + require(index in 0..COL_MAX) { "Invalid column index" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> id - RESOURCE_CLUSTER_ID -> cluster - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) - RESOURCE_CPU_CAPACITY -> getDouble(RESOURCE_CPU_CAPACITY) - RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) - RESOURCE_STATE_CPU_USAGE_PCT -> getDouble(RESOURCE_STATE_CPU_USAGE_PCT) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) - RESOURCE_STATE_DISK_READ -> getDouble(RESOURCE_STATE_DISK_READ) - RESOURCE_STATE_DISK_WRITE -> getDouble(RESOURCE_STATE_DISK_WRITE) + override fun get(index: Int): Any? { + return when (index) { + COL_ID -> id + COL_CLUSTER_ID -> cluster + COL_TIMESTAMP -> timestamp + COL_NCPUS -> getInt(index) + COL_POWERED_ON -> getInt(index) + COL_CPU_CAPACITY, COL_CPU_USAGE, COL_CPU_USAGE_PCT, COL_CPU_READY_PCT, COL_CPU_DEMAND, COL_MEM_CAPACITY, COL_DISK_READ, COL_DISK_WRITE -> getDouble(index) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { - return when (column) { - RESOURCE_STATE_POWERED_ON -> poweredOn + override fun getBoolean(index: Int): Boolean { + return when (index) { + COL_POWERED_ON -> poweredOn else -> throw IllegalArgumentException("Invalid column") } } - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_CPU_COUNT -> cpuCores + override fun getInt(index: Int): Int { + return when (index) { + COL_NCPUS -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_CPU_CAPACITY -> cpuCapacity - RESOURCE_STATE_CPU_USAGE -> cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsage / cpuCapacity - RESOURCE_STATE_CPU_DEMAND -> cpuDemand - RESOURCE_MEM_CAPACITY -> memCapacity - RESOURCE_STATE_DISK_READ -> diskRead - RESOURCE_STATE_DISK_WRITE -> diskWrite + override fun getDouble(index: Int): Double { + return when (index) { + COL_CPU_CAPACITY -> cpuCapacity + COL_CPU_USAGE -> cpuUsage + COL_CPU_USAGE_PCT -> cpuUsage / cpuCapacity + COL_CPU_READY_PCT -> cpuReadyPct + COL_CPU_DEMAND -> cpuDemand + COL_MEM_CAPACITY -> memCapacity + COL_DISK_READ -> diskRead + COL_DISK_WRITE -> diskWrite else -> throw IllegalArgumentException("Invalid column") } } @@ -209,4 +192,21 @@ internal class BitbrainsExResourceStateTableReader(private val reader: BufferedR private val COL_CPU_CAPACITY = 18 private val COL_ID = 19 private val COL_MEM_CAPACITY = 20 + private val COL_CPU_USAGE_PCT = 21 + private val COL_MAX = COL_CPU_USAGE_PCT + 1 + + private val columns = mapOf( + RESOURCE_ID to COL_ID, + RESOURCE_CLUSTER_ID to COL_CLUSTER_ID, + RESOURCE_STATE_TIMESTAMP to COL_TIMESTAMP, + RESOURCE_CPU_COUNT to COL_NCPUS, + RESOURCE_CPU_CAPACITY to COL_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE to COL_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT to COL_CPU_USAGE_PCT, + RESOURCE_STATE_CPU_DEMAND to COL_CPU_DEMAND, + RESOURCE_STATE_CPU_READY_PCT to COL_CPU_READY_PCT, + RESOURCE_MEM_CAPACITY to COL_MEM_CAPACITY, + RESOURCE_STATE_DISK_READ to COL_DISK_READ, + RESOURCE_STATE_DISK_WRITE to COL_DISK_WRITE + ) } diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index f68e61dc..6b6ac9da 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -24,6 +24,7 @@ package org.opendc.trace.bitbrains import com.fasterxml.jackson.dataformat.csv.CsvFactory import org.opendc.trace.* +import org.opendc.trace.util.CompositeTableReader import java.nio.file.Files import java.nio.file.Path import java.util.stream.Collectors @@ -65,57 +66,8 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path override fun newReader(): TableReader { val it = partitions.iterator() - return object : TableReader { - var delegate: TableReader? = nextDelegate() - - override fun nextRow(): Boolean { - var delegate = delegate - - while (delegate != null) { - if (delegate.nextRow()) { - break - } - - delegate.close() - delegate = nextDelegate() - this.delegate = delegate - } - - return delegate != null - } - - override fun hasColumn(column: TableColumn<*>): Boolean = delegate?.hasColumn(column) ?: false - - override fun get(column: TableColumn): T { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.get(column) - } - - override fun getBoolean(column: TableColumn): Boolean { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getBoolean(column) - } - - override fun getInt(column: TableColumn): Int { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getInt(column) - } - - override fun getLong(column: TableColumn): Long { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getLong(column) - } - - override fun getDouble(column: TableColumn): Double { - val delegate = checkNotNull(delegate) { "Invalid reader state" } - return delegate.getDouble(column) - } - - override fun close() { - delegate?.close() - } - - private fun nextDelegate(): TableReader? { + return object : CompositeTableReader() { + override fun nextReader(): TableReader? { return if (it.hasNext()) { val (partition, path) = it.next() return BitbrainsResourceStateTableReader(partition, factory.createParser(path.toFile())) diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt index 54be5dea..3a8839b4 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTableReader.kt @@ -111,71 +111,49 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, return true } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_CPU_COUNT -> true - RESOURCE_CPU_CAPACITY -> true - RESOURCE_STATE_CPU_USAGE -> true - RESOURCE_STATE_CPU_USAGE_PCT -> true - RESOURCE_MEM_CAPACITY -> true - RESOURCE_STATE_MEM_USAGE -> true - RESOURCE_STATE_DISK_READ -> true - RESOURCE_STATE_DISK_WRITE -> true - RESOURCE_STATE_NET_RX -> true - RESOURCE_STATE_NET_TX -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column index" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> partition - RESOURCE_STATE_TIMESTAMP -> timestamp - RESOURCE_CPU_COUNT -> cpuCores - RESOURCE_CPU_CAPACITY -> cpuCapacity - RESOURCE_STATE_CPU_USAGE -> cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - RESOURCE_MEM_CAPACITY -> memCapacity - RESOURCE_STATE_MEM_USAGE -> memUsage - RESOURCE_STATE_DISK_READ -> diskRead - RESOURCE_STATE_DISK_WRITE -> diskWrite - RESOURCE_STATE_NET_RX -> netReceived - RESOURCE_STATE_NET_TX -> netTransmitted + override fun get(index: Int): Any? { + return when (index) { + COL_ID -> partition + COL_TIMESTAMP -> timestamp + COL_CPU_COUNT -> getInt(index) + COL_CPU_CAPACITY, COL_CPU_USAGE, COL_CPU_USAGE_PCT, COL_MEM_CAPACITY, COL_MEM_USAGE, COL_DISK_READ, COL_DISK_WRITE, COL_NET_RX, COL_NET_TX -> getDouble(index) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { - return when (column) { - RESOURCE_CPU_COUNT -> cpuCores + override fun getInt(index: Int): Int { + return when (index) { + COL_CPU_COUNT -> cpuCores else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { - return when (column) { - RESOURCE_CPU_CAPACITY -> cpuCapacity - RESOURCE_STATE_CPU_USAGE -> cpuUsage - RESOURCE_STATE_CPU_USAGE_PCT -> cpuUsagePct - RESOURCE_MEM_CAPACITY -> memCapacity - RESOURCE_STATE_MEM_USAGE -> memUsage - RESOURCE_STATE_DISK_READ -> diskRead - RESOURCE_STATE_DISK_WRITE -> diskWrite - RESOURCE_STATE_NET_RX -> netReceived - RESOURCE_STATE_NET_TX -> netTransmitted + override fun getDouble(index: Int): Double { + return when (index) { + COL_CPU_CAPACITY -> cpuCapacity + COL_CPU_USAGE -> cpuUsage + COL_CPU_USAGE_PCT -> cpuUsagePct + COL_MEM_CAPACITY -> memCapacity + COL_MEM_USAGE -> memUsage + COL_DISK_READ -> diskRead + COL_DISK_WRITE -> diskWrite + COL_NET_RX -> netReceived + COL_NET_TX -> netTransmitted else -> throw IllegalArgumentException("Invalid column") } } @@ -249,6 +227,34 @@ internal class BitbrainsResourceStateTableReader(private val partition: String, netTransmitted = Double.NaN } + private val COL_TIMESTAMP = 0 + private val COL_CPU_COUNT = 1 + private val COL_CPU_CAPACITY = 2 + private val COL_CPU_USAGE = 3 + private val COL_CPU_USAGE_PCT = 4 + private val COL_MEM_CAPACITY = 5 + private val COL_MEM_USAGE = 6 + private val COL_DISK_READ = 7 + private val COL_DISK_WRITE = 8 + private val COL_NET_RX = 9 + private val COL_NET_TX = 10 + private val COL_ID = 11 + + private val columns = mapOf( + RESOURCE_ID to COL_ID, + RESOURCE_STATE_TIMESTAMP to COL_TIMESTAMP, + RESOURCE_CPU_COUNT to COL_CPU_COUNT, + RESOURCE_CPU_CAPACITY to COL_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE to COL_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT to COL_CPU_USAGE_PCT, + RESOURCE_MEM_CAPACITY to COL_MEM_CAPACITY, + RESOURCE_STATE_MEM_USAGE to COL_MEM_USAGE, + RESOURCE_STATE_DISK_READ to COL_DISK_READ, + RESOURCE_STATE_DISK_WRITE to COL_DISK_WRITE, + RESOURCE_STATE_NET_RX to COL_NET_RX, + RESOURCE_STATE_NET_TX to COL_NET_TX + ) + /** * The type of the timestamp in the trace. */ diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt index 146c04f0..3701994a 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTableReader.kt @@ -43,13 +43,14 @@ internal class BitbrainsResourceTableReader(private val factory: CsvFactory, vms val parser = factory.createParser(path.toFile()) val reader = BitbrainsResourceStateTableReader(name, parser) + val idCol = reader.resolve(RESOURCE_ID) try { if (!reader.nextRow()) { continue } - id = reader.get(RESOURCE_ID) + id = reader.get(idCol) as String return true } finally { reader.close() @@ -59,36 +60,33 @@ internal class BitbrainsResourceTableReader(private val factory: CsvFactory, vms return false } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column index" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - RESOURCE_ID -> id + override fun get(index: Int): Any? { + return when (index) { + COL_ID -> id else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { + override fun getInt(index: Int): Int { throw IllegalArgumentException("Invalid column") } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { throw IllegalArgumentException("Invalid column") } @@ -105,4 +103,7 @@ internal class BitbrainsResourceTableReader(private val factory: CsvFactory, vms private fun reset() { id = null } + + private val COL_ID = 0 + private val columns = mapOf(RESOURCE_ID to COL_ID) } diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt index 39eb5520..aa4c543b 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTableReader.kt @@ -67,52 +67,43 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { return true } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - TASK_WORKFLOW_ID -> true - TASK_ID -> true - TASK_SUBMIT_TIME -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_ALLOC_NCPUS -> true - TASK_PARENTS -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - TASK_WORKFLOW_ID -> workflowId - TASK_ID -> jobId - TASK_SUBMIT_TIME -> submitTime - TASK_RUNTIME -> runtime - TASK_REQ_NCPUS -> nProcs - TASK_ALLOC_NCPUS -> reqNProcs - TASK_PARENTS -> dependencies + override fun get(index: Int): Any? { + return when (index) { + COL_JOB_ID -> jobId + COL_WORKFLOW_ID -> workflowId + COL_SUBMIT_TIME -> submitTime + COL_RUNTIME -> runtime + COL_REQ_NPROC -> getInt(index) + COL_NPROC -> getInt(index) + COL_DEPS -> dependencies else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { - return when (column) { - TASK_REQ_NCPUS -> nProcs - TASK_ALLOC_NCPUS -> reqNProcs + override fun getInt(index: Int): Int { + return when (index) { + COL_REQ_NPROC -> reqNProcs + COL_NPROC -> nProcs else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { throw IllegalArgumentException("Invalid column") } @@ -180,6 +171,24 @@ internal class GwfTaskTableReader(private val parser: CsvParser) : TableReader { dependencies = emptySet() } + private val COL_WORKFLOW_ID = 0 + private val COL_JOB_ID = 1 + private val COL_SUBMIT_TIME = 2 + private val COL_RUNTIME = 3 + private val COL_NPROC = 4 + private val COL_REQ_NPROC = 5 + private val COL_DEPS = 6 + + private val columns = mapOf( + TASK_ID to COL_JOB_ID, + TASK_WORKFLOW_ID to COL_WORKFLOW_ID, + TASK_SUBMIT_TIME to COL_SUBMIT_TIME, + TASK_RUNTIME to COL_RUNTIME, + TASK_ALLOC_NCPUS to COL_NPROC, + TASK_REQ_NCPUS to COL_REQ_NPROC, + TASK_PARENTS to COL_DEPS + ) + companion object { /** * The [CsvSchema] that is used to parse the trace. diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt index e4b18735..b5043f82 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt @@ -55,54 +55,46 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea return record != null } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_STATE_TIMESTAMP -> true - RESOURCE_STATE_DURATION -> true - RESOURCE_CPU_COUNT -> true - RESOURCE_STATE_CPU_USAGE -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column index" } + return get(index) == null } - override fun get(column: TableColumn): T { + override fun get(index: Int): Any? { val record = checkNotNull(record) { "Reader in invalid state" } - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - RESOURCE_ID -> record[COL_ID].toString() - RESOURCE_STATE_TIMESTAMP -> Instant.ofEpochMilli(record[COL_TIMESTAMP] as Long) - RESOURCE_STATE_DURATION -> Duration.ofMillis(record[COL_DURATION] as Long) - RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) - RESOURCE_STATE_CPU_USAGE -> getDouble(RESOURCE_STATE_CPU_USAGE) + return when (index) { + COL_ID -> record[AVRO_COL_ID].toString() + COL_TIMESTAMP -> Instant.ofEpochMilli(record[AVRO_COL_TIMESTAMP] as Long) + COL_DURATION -> Duration.ofMillis(record[AVRO_COL_DURATION] as Long) + COL_CPU_COUNT -> getInt(index) + COL_CPU_USAGE -> getDouble(index) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { + override fun getInt(index: Int): Int { val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_CPU_COUNT -> record[COL_CPU_COUNT] as Int + return when (index) { + COL_CPU_COUNT -> record[AVRO_COL_CPU_COUNT] as Int else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_STATE_CPU_USAGE -> (record[COL_CPU_USAGE] as Number).toDouble() + return when (index) { + COL_CPU_USAGE -> (record[AVRO_COL_CPU_USAGE] as Number).toDouble() else -> throw IllegalArgumentException("Invalid column") } } @@ -118,20 +110,34 @@ internal class OdcVmResourceStateTableReader(private val reader: LocalParquetRea */ private fun initColumns(schema: Schema) { try { - COL_ID = schema.getField("id").pos() - COL_TIMESTAMP = (schema.getField("timestamp") ?: schema.getField("time")).pos() - COL_DURATION = schema.getField("duration").pos() - COL_CPU_COUNT = (schema.getField("cpu_count") ?: schema.getField("cores")).pos() - COL_CPU_USAGE = (schema.getField("cpu_usage") ?: schema.getField("cpuUsage")).pos() + AVRO_COL_ID = schema.getField("id").pos() + AVRO_COL_TIMESTAMP = (schema.getField("timestamp") ?: schema.getField("time")).pos() + AVRO_COL_DURATION = schema.getField("duration").pos() + AVRO_COL_CPU_COUNT = (schema.getField("cpu_count") ?: schema.getField("cores")).pos() + AVRO_COL_CPU_USAGE = (schema.getField("cpu_usage") ?: schema.getField("cpuUsage")).pos() } catch (e: NullPointerException) { // This happens when the field we are trying to access does not exist throw IllegalArgumentException("Invalid schema", e) } } - private var COL_ID = -1 - private var COL_TIMESTAMP = -1 - private var COL_DURATION = -1 - private var COL_CPU_COUNT = -1 - private var COL_CPU_USAGE = -1 + private var AVRO_COL_ID = -1 + private var AVRO_COL_TIMESTAMP = -1 + private var AVRO_COL_DURATION = -1 + private var AVRO_COL_CPU_COUNT = -1 + private var AVRO_COL_CPU_USAGE = -1 + + private val COL_ID = 0 + private val COL_TIMESTAMP = 1 + private val COL_DURATION = 2 + private val COL_CPU_COUNT = 3 + private val COL_CPU_USAGE = 4 + + private val columns = mapOf( + RESOURCE_ID to COL_ID, + RESOURCE_STATE_TIMESTAMP to COL_TIMESTAMP, + RESOURCE_STATE_DURATION to COL_DURATION, + RESOURCE_CPU_COUNT to COL_CPU_COUNT, + RESOURCE_STATE_CPU_USAGE to COL_CPU_USAGE, + ) } diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt index c52da62d..d93929aa 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt @@ -54,56 +54,48 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader): Boolean { - return when (column) { - RESOURCE_ID -> true - RESOURCE_START_TIME -> true - RESOURCE_STOP_TIME -> true - RESOURCE_CPU_COUNT -> true - RESOURCE_MEM_CAPACITY -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column index" } + return get(index) == null } - override fun get(column: TableColumn): T { + override fun get(index: Int): Any? { val record = checkNotNull(record) { "Reader in invalid state" } - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - RESOURCE_ID -> record[COL_ID].toString() - RESOURCE_START_TIME -> Instant.ofEpochMilli(record[COL_START_TIME] as Long) - RESOURCE_STOP_TIME -> Instant.ofEpochMilli(record[COL_STOP_TIME] as Long) - RESOURCE_CPU_COUNT -> getInt(RESOURCE_CPU_COUNT) - RESOURCE_MEM_CAPACITY -> getDouble(RESOURCE_MEM_CAPACITY) + return when (index) { + COL_ID -> record[AVRO_COL_ID].toString() + COL_START_TIME -> Instant.ofEpochMilli(record[AVRO_COL_START_TIME] as Long) + COL_STOP_TIME -> Instant.ofEpochMilli(record[AVRO_COL_STOP_TIME] as Long) + COL_CPU_COUNT -> getInt(index) + COL_MEM_CAPACITY -> getDouble(index) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { + override fun getInt(index: Int): Int { val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_CPU_COUNT -> record[COL_CPU_COUNT] as Int + return when (index) { + COL_CPU_COUNT -> record[AVRO_COL_CPU_COUNT] as Int else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - RESOURCE_MEM_CAPACITY -> (record[COL_MEM_CAPACITY] as Number).toDouble() + return when (index) { + COL_MEM_CAPACITY -> (record[AVRO_COL_MEM_CAPACITY] as Number).toDouble() else -> throw IllegalArgumentException("Invalid column") } } @@ -119,20 +111,34 @@ internal class OdcVmResourceTableReader(private val reader: LocalParquetReader): Boolean { - return when (column) { - TASK_ID -> true - TASK_SUBMIT_TIME -> true - TASK_WAIT_TIME -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_ALLOC_NCPUS -> true - TASK_PARENTS -> true - TASK_STATUS -> true - TASK_GROUP_ID -> true - TASK_USER_ID -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + require(index in columns.values) { "Invalid column index" } + return false } - override fun get(column: TableColumn): T { - val res: Any = when (column) { - TASK_ID -> fields[COL_JOB_ID] - TASK_SUBMIT_TIME -> Instant.ofEpochSecond(fields[COL_SUBMIT_TIME].toLong(10)) - TASK_WAIT_TIME -> Duration.ofSeconds(fields[COL_WAIT_TIME].toLong(10)) - TASK_RUNTIME -> Duration.ofSeconds(fields[COL_RUN_TIME].toLong(10)) - TASK_REQ_NCPUS -> getInt(TASK_REQ_NCPUS) - TASK_ALLOC_NCPUS -> getInt(TASK_ALLOC_NCPUS) - TASK_PARENTS -> { - val parent = fields[COL_PARENT_JOB].toLong(10) + override fun get(index: Int): Any? { + return when (index) { + COL_JOB_ID -> fields[index] + COL_SUBMIT_TIME -> Instant.ofEpochSecond(fields[index].toLong(10)) + COL_WAIT_TIME, COL_RUN_TIME -> Duration.ofSeconds(fields[index].toLong(10)) + COL_REQ_NCPUS, COL_ALLOC_NCPUS, COL_STATUS, COL_GROUP_ID, COL_USER_ID -> getInt(index) + COL_PARENT_JOB -> { + val parent = fields[index].toLong(10) if (parent < 0) emptySet() else setOf(parent) } - TASK_STATUS -> getInt(TASK_STATUS) - TASK_GROUP_ID -> getInt(TASK_GROUP_ID) - TASK_USER_ID -> getInt(TASK_USER_ID) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { - return when (column) { - TASK_REQ_NCPUS -> fields[COL_REQ_NCPUS].toInt(10) - TASK_ALLOC_NCPUS -> fields[COL_ALLOC_NCPUS].toInt(10) - TASK_STATUS -> fields[COL_STATUS].toInt(10) - TASK_GROUP_ID -> fields[COL_GROUP_ID].toInt(10) - TASK_USER_ID -> fields[COL_USER_ID].toInt(10) + override fun getInt(index: Int): Int { + return when (index) { + COL_REQ_NCPUS, COL_ALLOC_NCPUS, COL_STATUS, COL_GROUP_ID, COL_USER_ID -> fields[index].toInt(10) else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { throw IllegalArgumentException("Invalid column") } @@ -155,4 +134,17 @@ internal class SwfTaskTableReader(private val reader: BufferedReader) : TableRea private val COL_PART_NUM = 15 private val COL_PARENT_JOB = 16 private val COL_PARENT_THINK_TIME = 17 + + private val columns = mapOf( + TASK_ID to COL_JOB_ID, + TASK_SUBMIT_TIME to COL_SUBMIT_TIME, + TASK_WAIT_TIME to COL_WAIT_TIME, + TASK_RUNTIME to COL_RUN_TIME, + TASK_ALLOC_NCPUS to COL_ALLOC_NCPUS, + TASK_REQ_NCPUS to COL_REQ_NCPUS, + TASK_STATUS to COL_STATUS, + TASK_USER_ID to COL_USER_ID, + TASK_GROUP_ID to COL_GROUP_ID, + TASK_PARENTS to COL_PARENT_JOB + ) } diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt index 4408ba5c..7f378d80 100644 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTableReader.kt @@ -94,49 +94,41 @@ internal class WfFormatTaskTableReader(private val parser: JsonParser) : TableRe return hasJob } - override fun hasColumn(column: TableColumn<*>): Boolean { - return when (column) { - TASK_ID -> true - TASK_WORKFLOW_ID -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_PARENTS -> true - TASK_CHILDREN -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column value" } + return false } - override fun get(column: TableColumn): T { - val res: Any? = when (column) { - TASK_ID -> id - TASK_WORKFLOW_ID -> workflowId - TASK_RUNTIME -> runtime - TASK_PARENTS -> parents - TASK_CHILDREN -> children - TASK_REQ_NCPUS -> getInt(TASK_REQ_NCPUS) + override fun get(index: Int): Any? { + return when (index) { + COL_ID -> id + COL_WORKFLOW_ID -> workflowId + COL_RUNTIME -> runtime + COL_PARENTS -> parents + COL_CHILDREN -> children + COL_NPROC -> getInt(index) else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { - return when (column) { - TASK_REQ_NCPUS -> cores + override fun getInt(index: Int): Int { + return when (index) { + COL_NPROC -> cores else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { throw IllegalArgumentException("Invalid column") } @@ -231,4 +223,20 @@ internal class WfFormatTaskTableReader(private val parser: JsonParser) : TableRe children = null cores = -1 } + + private val COL_ID = 0 + private val COL_WORKFLOW_ID = 1 + private val COL_RUNTIME = 3 + private val COL_NPROC = 4 + private val COL_PARENTS = 5 + private val COL_CHILDREN = 6 + + private val columns = mapOf( + TASK_ID to COL_ID, + TASK_WORKFLOW_ID to COL_WORKFLOW_ID, + TASK_RUNTIME to COL_RUNTIME, + TASK_REQ_NCPUS to COL_NPROC, + TASK_PARENTS to COL_PARENTS, + TASK_CHILDREN to COL_CHILDREN, + ) } diff --git a/opendc-trace/opendc-trace-wtf/build.gradle.kts b/opendc-trace/opendc-trace-wtf/build.gradle.kts index 5051c7b0..e4f0ab3a 100644 --- a/opendc-trace/opendc-trace-wtf/build.gradle.kts +++ b/opendc-trace/opendc-trace-wtf/build.gradle.kts @@ -34,4 +34,6 @@ dependencies { api(projects.opendcTrace.opendcTraceApi) implementation(projects.opendcTrace.opendcTraceParquet) + + testRuntimeOnly(libs.slf4j.simple) } diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt index 5e2463f8..45ec25dd 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTableReader.kt @@ -22,6 +22,7 @@ package org.opendc.trace.wtf +import org.apache.avro.Schema import org.apache.avro.generic.GenericRecord import org.opendc.trace.* import org.opendc.trace.util.parquet.LocalParquetReader @@ -37,73 +38,126 @@ internal class WtfTaskTableReader(private val reader: LocalParquetReader): Boolean { - return when (column) { - TASK_ID -> true - TASK_WORKFLOW_ID -> true - TASK_SUBMIT_TIME -> true - TASK_WAIT_TIME -> true - TASK_RUNTIME -> true - TASK_REQ_NCPUS -> true - TASK_PARENTS -> true - TASK_CHILDREN -> true - TASK_GROUP_ID -> true - TASK_USER_ID -> true - else -> false - } + override fun resolve(column: TableColumn<*>): Int = columns[column] ?: -1 + + override fun isNull(index: Int): Boolean { + check(index in 0..columns.size) { "Invalid column index" } + return get(index) == null } - override fun get(column: TableColumn): T { + override fun get(index: Int): Any? { val record = checkNotNull(record) { "Reader in invalid state" } - @Suppress("UNCHECKED_CAST") - val res: Any = when (column) { - TASK_ID -> (record["id"] as Long).toString() - TASK_WORKFLOW_ID -> (record["workflow_id"] as Long).toString() - TASK_SUBMIT_TIME -> Instant.ofEpochMilli(record["ts_submit"] as Long) - TASK_WAIT_TIME -> Duration.ofMillis(record["wait_time"] as Long) - TASK_RUNTIME -> Duration.ofMillis(record["runtime"] as Long) - TASK_REQ_NCPUS -> (record["resource_amount_requested"] as Double).toInt() - TASK_PARENTS -> (record["parents"] as ArrayList).map { it["item"].toString() }.toSet() - TASK_CHILDREN -> (record["children"] as ArrayList).map { it["item"].toString() }.toSet() - TASK_GROUP_ID -> record["group_id"] - TASK_USER_ID -> record["user_id"] + return when (index) { + COL_ID -> (record[AVRO_COL_ID] as Long).toString() + COL_WORKFLOW_ID -> (record[AVRO_COL_WORKFLOW_ID] as Long).toString() + COL_SUBMIT_TIME -> Instant.ofEpochMilli(record[AVRO_COL_SUBMIT_TIME] as Long) + COL_WAIT_TIME -> Duration.ofMillis(record[AVRO_COL_WAIT_TIME] as Long) + COL_RUNTIME -> Duration.ofMillis(record[AVRO_COL_RUNTIME] as Long) + COL_REQ_NCPUS, COL_GROUP_ID, COL_USER_ID -> getInt(index) + COL_PARENTS -> (record[AVRO_COL_PARENTS] as ArrayList).map { it["item"].toString() }.toSet() + COL_CHILDREN -> (record[AVRO_COL_CHILDREN] as ArrayList).map { it["item"].toString() }.toSet() else -> throw IllegalArgumentException("Invalid column") } - - @Suppress("UNCHECKED_CAST") - return res as T } - override fun getBoolean(column: TableColumn): Boolean { + override fun getBoolean(index: Int): Boolean { throw IllegalArgumentException("Invalid column") } - override fun getInt(column: TableColumn): Int { + override fun getInt(index: Int): Int { val record = checkNotNull(record) { "Reader in invalid state" } - return when (column) { - TASK_REQ_NCPUS -> (record["resource_amount_requested"] as Double).toInt() - TASK_GROUP_ID -> record["group_id"] as Int - TASK_USER_ID -> record["user_id"] as Int + return when (index) { + COL_REQ_NCPUS -> (record[AVRO_COL_REQ_NCPUS] as Double).toInt() + COL_GROUP_ID -> record[AVRO_COL_GROUP_ID] as Int + COL_USER_ID -> record[AVRO_COL_USER_ID] as Int else -> throw IllegalArgumentException("Invalid column") } } - override fun getLong(column: TableColumn): Long { + override fun getLong(index: Int): Long { throw IllegalArgumentException("Invalid column") } - override fun getDouble(column: TableColumn): Double { + override fun getDouble(index: Int): Double { throw IllegalArgumentException("Invalid column") } override fun close() { reader.close() } + + /** + * Initialize the columns for the reader based on [schema]. + */ + private fun initColumns(schema: Schema) { + try { + AVRO_COL_ID = schema.getField("id").pos() + AVRO_COL_WORKFLOW_ID = schema.getField("workflow_id").pos() + AVRO_COL_SUBMIT_TIME = schema.getField("ts_submit").pos() + AVRO_COL_WAIT_TIME = schema.getField("wait_time").pos() + AVRO_COL_RUNTIME = schema.getField("runtime").pos() + AVRO_COL_REQ_NCPUS = schema.getField("resource_amount_requested").pos() + AVRO_COL_PARENTS = schema.getField("parents").pos() + AVRO_COL_CHILDREN = schema.getField("children").pos() + AVRO_COL_GROUP_ID = schema.getField("group_id").pos() + AVRO_COL_USER_ID = schema.getField("user_id").pos() + } catch (e: NullPointerException) { + // This happens when the field we are trying to access does not exist + throw IllegalArgumentException("Invalid schema", e) + } + } + + private var AVRO_COL_ID = -1 + private var AVRO_COL_WORKFLOW_ID = -1 + private var AVRO_COL_SUBMIT_TIME = -1 + private var AVRO_COL_WAIT_TIME = -1 + private var AVRO_COL_RUNTIME = -1 + private var AVRO_COL_REQ_NCPUS = -1 + private var AVRO_COL_PARENTS = -1 + private var AVRO_COL_CHILDREN = -1 + private var AVRO_COL_GROUP_ID = -1 + private var AVRO_COL_USER_ID = -1 + + private val COL_ID = 0 + private val COL_WORKFLOW_ID = 1 + private val COL_SUBMIT_TIME = 2 + private val COL_WAIT_TIME = 3 + private val COL_RUNTIME = 4 + private val COL_REQ_NCPUS = 5 + private val COL_PARENTS = 6 + private val COL_CHILDREN = 7 + private val COL_GROUP_ID = 8 + private val COL_USER_ID = 9 + + private val columns = mapOf( + TASK_ID to COL_ID, + TASK_WORKFLOW_ID to COL_WORKFLOW_ID, + TASK_SUBMIT_TIME to COL_SUBMIT_TIME, + TASK_WAIT_TIME to COL_WAIT_TIME, + TASK_RUNTIME to COL_RUNTIME, + TASK_REQ_NCPUS to COL_REQ_NCPUS, + TASK_PARENTS to COL_PARENTS, + TASK_CHILDREN to COL_CHILDREN, + TASK_GROUP_ID to COL_GROUP_ID, + TASK_USER_ID to COL_USER_ID, + ) } -- cgit v1.2.3 From e765316cfc089dd50602759ea7afbcc7a3cd4c00 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 20 Sep 2021 15:17:49 +0200 Subject: perf(compute): Use index lookup in trace loader This change updates the ComputeWorkloadLoader to use index column lookups in order to prevent having to lookup the index for every row. --- .../compute/workload/ComputeWorkloadLoader.kt | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index 8a2585ce..ab7f051f 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -27,6 +27,8 @@ import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.trace.* import org.opendc.trace.opendc.OdcVmTraceFormat import java.io.File +import java.time.Duration +import java.time.Instant import java.util.* import java.util.concurrent.ConcurrentHashMap import kotlin.math.roundToLong @@ -58,15 +60,21 @@ public class ComputeWorkloadLoader(private val baseDir: File) { private fun parseFragments(trace: Trace): Map> { val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() + val idCol = reader.resolve(RESOURCE_ID) + val timestampCol = reader.resolve(RESOURCE_STATE_TIMESTAMP) + val durationCol = reader.resolve(RESOURCE_STATE_DURATION) + val coresCol = reader.resolve(RESOURCE_CPU_COUNT) + val usageCol = reader.resolve(RESOURCE_STATE_CPU_USAGE) + val fragments = mutableMapOf>() return try { while (reader.nextRow()) { - val id = reader.get(RESOURCE_ID) - val time = reader.get(RESOURCE_STATE_TIMESTAMP) - val duration = reader.get(RESOURCE_STATE_DURATION) - val cores = reader.getInt(RESOURCE_CPU_COUNT) - val cpuUsage = reader.getDouble(RESOURCE_STATE_CPU_USAGE) + val id = reader.get(idCol) as String + val time = reader.get(timestampCol) as Instant + val duration = reader.get(durationCol) as Duration + val cores = reader.getInt(coresCol) + val cpuUsage = reader.getDouble(usageCol) val fragment = SimTraceWorkload.Fragment( time.toEpochMilli(), @@ -90,21 +98,27 @@ public class ComputeWorkloadLoader(private val baseDir: File) { private fun parseMeta(trace: Trace, fragments: Map>): List { val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() + val idCol = reader.resolve(RESOURCE_ID) + val startTimeCol = reader.resolve(RESOURCE_START_TIME) + val stopTimeCol = reader.resolve(RESOURCE_STOP_TIME) + val coresCol = reader.resolve(RESOURCE_CPU_COUNT) + val memCol = reader.resolve(RESOURCE_MEM_CAPACITY) + var counter = 0 val entries = mutableListOf() return try { while (reader.nextRow()) { - val id = reader.get(RESOURCE_ID) + val id = reader.get(idCol) as String if (!fragments.containsKey(id)) { continue } - val submissionTime = reader.get(RESOURCE_START_TIME) - val endTime = reader.get(RESOURCE_STOP_TIME) - val maxCores = reader.getInt(RESOURCE_CPU_COUNT) - val requiredMemory = reader.getDouble(RESOURCE_MEM_CAPACITY) / 1000.0 // Convert from KB to MB + val submissionTime = reader.get(startTimeCol) as Instant + val endTime = reader.get(stopTimeCol) as Instant + val maxCores = reader.getInt(coresCol) + val requiredMemory = reader.getDouble(memCol) / 1000.0 // Convert from KB to MB val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) val vmFragments = fragments.getValue(id).asSequence() -- cgit v1.2.3 From 140aafdaa711b0fdeacf99b9c7e70b706b8490f4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 20 Sep 2021 15:40:13 +0200 Subject: feat(trace): Add property for describing partition keys --- .../opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt | 5 +++++ .../main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt | 2 ++ .../src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt | 2 ++ .../org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt | 2 ++ .../kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt | 2 ++ .../main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt | 2 ++ .../src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt | 2 ++ .../main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt | 2 ++ .../src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt | 2 ++ .../src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt | 2 ++ .../src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt | 2 ++ .../src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt | 2 ++ 12 files changed, 27 insertions(+) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt index 6aca2051..164f5084 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt @@ -41,6 +41,11 @@ public interface Table { */ public val columns: List> + /** + * The columns by which the table is partitioned. + */ + public val partitionKeys: List> + /** * Open a [TableReader] for this table. */ diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt index 8f2f5cc9..285e7216 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt @@ -53,6 +53,8 @@ internal class AzureResourceStateTable(private val factory: CsvFactory, path: Pa RESOURCE_STATE_CPU_USAGE_PCT ) + override val partitionKeys: List> = listOf(RESOURCE_STATE_TIMESTAMP) + override fun newReader(): TableReader { val it = partitions.iterator() diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt index 96ee3158..ff7af172 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt @@ -42,6 +42,8 @@ internal class AzureResourceTable(private val factory: CsvFactory, private val p RESOURCE_MEM_CAPACITY ) + override val partitionKeys: List> = emptyList() + override fun newReader(): TableReader { return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) } diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt index ab768608..7cb58226 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt @@ -62,6 +62,8 @@ internal class BitbrainsExResourceStateTable(path: Path) : Table { RESOURCE_STATE_DISK_WRITE, ) + override val partitionKeys: List> = listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) + override fun newReader(): TableReader { val it = partitions.iterator() diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt index 6b6ac9da..7b08b8be 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt @@ -63,6 +63,8 @@ internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path RESOURCE_STATE_NET_TX, ) + override val partitionKeys: List> = listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) + override fun newReader(): TableReader { val it = partitions.iterator() diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt index bc4f0b7d..d024af2d 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt @@ -49,6 +49,8 @@ internal class BitbrainsResourceTable(private val factory: CsvFactory, path: Pat override val columns: List> = listOf(RESOURCE_ID) + override val partitionKeys: List> = emptyList() + override fun newReader(): TableReader { return BitbrainsResourceTableReader(factory, vms) } diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt index fd7bd068..ca720de4 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt @@ -44,6 +44,8 @@ internal class GwfTaskTable(private val factory: CsvFactory, private val url: UR TASK_PARENTS ) + override val partitionKeys: List> = listOf(TASK_WORKFLOW_ID) + override fun newReader(): TableReader { return GwfTaskTableReader(factory.createParser(url)) } diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt index 39613070..caacf192 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt @@ -42,6 +42,8 @@ internal class OdcVmResourceStateTable(private val path: Path) : Table { RESOURCE_STATE_CPU_USAGE, ) + override val partitionKeys: List> = listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) + override fun newReader(): TableReader { val reader = LocalParquetReader(path.resolve("trace.parquet")) return OdcVmResourceStateTableReader(reader) diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt index b1456560..653b28b8 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt @@ -42,6 +42,8 @@ internal class OdcVmResourceTable(private val path: Path) : Table { RESOURCE_MEM_CAPACITY, ) + override val partitionKeys: List> = emptyList() + override fun newReader(): TableReader { val reader = LocalParquetReader(path.resolve("meta.parquet")) return OdcVmResourceTableReader(reader) diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt index 7ec0d607..4898779d 100644 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt @@ -47,6 +47,8 @@ internal class SwfTaskTable(private val path: Path) : Table { TASK_USER_ID ) + override val partitionKeys: List> = emptyList() + override fun newReader(): TableReader { val reader = path.bufferedReader() return SwfTaskTableReader(reader) diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt index 7b7f979f..17aeee97 100644 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt @@ -43,6 +43,8 @@ internal class WfFormatTaskTable(private val factory: JsonFactory, private val p TASK_CHILDREN ) + override val partitionKeys: List> = emptyList() + override fun newReader(): TableReader { val parser = factory.createParser(path.toFile()) return WfFormatTaskTableReader(parser) diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt index 74202718..410bb347 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt @@ -48,6 +48,8 @@ internal class WtfTaskTable(private val path: Path) : Table { TASK_USER_ID ) + override val partitionKeys: List> = listOf(TASK_SUBMIT_TIME) + override fun newReader(): TableReader { val reader = LocalParquetReader(path.resolve("tasks/schema-1.0")) return WtfTaskTableReader(reader) -- cgit v1.2.3 From c7fff03408ee3109d0a39a96c043584a2d8f67ca Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 20 Sep 2021 22:04:23 +0200 Subject: refactor(trace): Simplify TraceFormat SPI interface This change simplifies the TraceFormat SPI interface by reducing the number of interfaces that implementors need to implement to only TraceFormat. --- .../compute/workload/ComputeWorkloadLoader.kt | 8 +- .../src/main/kotlin/org/opendc/trace/Table.kt | 10 --- .../src/main/kotlin/org/opendc/trace/Trace.kt | 19 ++--- .../kotlin/org/opendc/trace/internal/TableImpl.kt | 52 ++++++++++++ .../kotlin/org/opendc/trace/internal/TraceImpl.kt | 56 +++++++++++++ .../kotlin/org/opendc/trace/spi/TableDetails.kt | 37 +++++++++ .../kotlin/org/opendc/trace/spi/TraceFormat.kt | 33 ++++++-- .../opendc/trace/azure/AzureResourceStateTable.kt | 81 ------------------- .../org/opendc/trace/azure/AzureResourceTable.kt | 56 ------------- .../kotlin/org/opendc/trace/azure/AzureTrace.kt | 46 ----------- .../org/opendc/trace/azure/AzureTraceFormat.kt | 69 ++++++++++++++-- .../org/opendc/trace/azure/AzureTraceFormatTest.kt | 50 +++--------- .../bitbrains/BitbrainsExResourceStateTable.kt | 92 ---------------------- .../org/opendc/trace/bitbrains/BitbrainsExTrace.kt | 45 ----------- .../trace/bitbrains/BitbrainsExTraceFormat.kt | 69 ++++++++++++++-- .../trace/bitbrains/BitbrainsResourceStateTable.kt | 91 --------------------- .../trace/bitbrains/BitbrainsResourceTable.kt | 63 --------------- .../org/opendc/trace/bitbrains/BitbrainsTrace.kt | 46 ----------- .../opendc/trace/bitbrains/BitbrainsTraceFormat.kt | 76 ++++++++++++++++-- .../trace/bitbrains/BitbrainsExTraceFormatTest.kt | 44 +++-------- .../trace/bitbrains/BitbrainsTraceFormatTest.kt | 55 +++---------- .../kotlin/org/opendc/trace/gwf/GwfTaskTable.kt | 58 -------------- .../main/kotlin/org/opendc/trace/gwf/GwfTrace.kt | 46 ----------- .../kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt | 38 ++++++--- .../org/opendc/trace/gwf/GwfTraceFormatTest.kt | 61 +++----------- .../opendc/trace/opendc/OdcVmResourceStateTable.kt | 55 ------------- .../org/opendc/trace/opendc/OdcVmResourceTable.kt | 55 ------------- .../kotlin/org/opendc/trace/opendc/OdcVmTrace.kt | 49 ------------ .../org/opendc/trace/opendc/OdcVmTraceFormat.kt | 54 ++++++++++--- .../opendc/trace/opendc/OdcVmTraceFormatTest.kt | 47 +++-------- .../kotlin/org/opendc/trace/swf/SwfTaskTable.kt | 62 --------------- .../main/kotlin/org/opendc/trace/swf/SwfTrace.kt | 46 ----------- .../kotlin/org/opendc/trace/swf/SwfTraceFormat.kt | 39 +++++++-- .../org/opendc/trace/swf/SwfTraceFormatTest.kt | 53 +++---------- .../org/opendc/trace/tools/TraceConverter.kt | 11 +-- .../org/opendc/trace/wfformat/WfFormatTaskTable.kt | 58 -------------- .../org/opendc/trace/wfformat/WfFormatTrace.kt | 47 ----------- .../opendc/trace/wfformat/WfFormatTraceFormat.kt | 34 ++++++-- .../trace/wfformat/WfFormatTraceFormatTest.kt | 58 +++----------- .../kotlin/org/opendc/trace/wtf/WtfTaskTable.kt | 63 --------------- .../main/kotlin/org/opendc/trace/wtf/WtfTrace.kt | 47 ----------- .../kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt | 43 ++++++++-- .../org/opendc/trace/wtf/WtfTraceFormatTest.kt | 57 +++----------- .../opendc-workflow-service/build.gradle.kts | 3 +- .../opendc/workflow/service/WorkflowServiceTest.kt | 8 +- 45 files changed, 635 insertions(+), 1555 deletions(-) create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TraceImpl.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt delete mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt delete mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt delete mode 100644 opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt delete mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt delete mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt delete mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt delete mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt delete mode 100644 opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt delete mode 100644 opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt delete mode 100644 opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt delete mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt delete mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt delete mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt delete mode 100644 opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt delete mode 100644 opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt delete mode 100644 opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt delete mode 100644 opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt delete mode 100644 opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt delete mode 100644 opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index ab7f051f..6dba41e6 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -25,7 +25,6 @@ package org.opendc.compute.workload import mu.KotlinLogging import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.trace.* -import org.opendc.trace.opendc.OdcVmTraceFormat import java.io.File import java.time.Duration import java.time.Instant @@ -44,11 +43,6 @@ public class ComputeWorkloadLoader(private val baseDir: File) { */ private val logger = KotlinLogging.logger {} - /** - * The [OdcVmTraceFormat] instance to load the traces - */ - private val format = OdcVmTraceFormat() - /** * The cache of workloads. */ @@ -159,7 +153,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { logger.info { "Loading trace $it at $path" } - val trace = format.open(path.toURI().toURL()) + val trace = Trace.open(path, format = "opendc-vm") val fragments = parseFragments(trace) parseMeta(trace, fragments) } diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt index 164f5084..031ee269 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt @@ -31,11 +31,6 @@ public interface Table { */ public val name: String - /** - * A flag to indicate that the table is synthetic (derived from another table). - */ - public val isSynthetic: Boolean - /** * The list of columns supported in this table. */ @@ -50,9 +45,4 @@ public interface Table { * Open a [TableReader] for this table. */ public fun newReader(): TableReader - - /** - * Open a [TableReader] for [partition] of the table. - */ - public fun newReader(partition: String): TableReader } diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt index 0ae45e86..6d0014cb 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt @@ -22,9 +22,9 @@ package org.opendc.trace +import org.opendc.trace.internal.TraceImpl import org.opendc.trace.spi.TraceFormat import java.io.File -import java.net.URL import java.nio.file.Path /** @@ -47,32 +47,25 @@ public interface Trace { public fun getTable(name: String): Table? public companion object { - /** - * Open a [Trace] at the specified [url] in the given [format]. - * - * @throws IllegalArgumentException if [format] is not supported. - */ - public fun open(url: URL, format: String): Trace { - val provider = requireNotNull(TraceFormat.byName(format)) { "Unknown format $format" } - return provider.open(url) - } - /** * Open a [Trace] at the specified [path] in the given [format]. * + * @param path The path to the trace. * @throws IllegalArgumentException if [format] is not supported. */ public fun open(path: File, format: String): Trace { - return open(path.toURI().toURL(), format) + return open(path.toPath(), format) } /** * Open a [Trace] at the specified [path] in the given [format]. * + * @param path The [Path] to the trace. * @throws IllegalArgumentException if [format] is not supported. */ public fun open(path: Path, format: String): Trace { - return open(path.toUri().toURL(), format) + val provider = requireNotNull(TraceFormat.byName(format)) { "Unknown format $format" } + return TraceImpl(provider, path) } } } diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt new file mode 100644 index 00000000..fd0a0f04 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.internal + +import org.opendc.trace.Table +import org.opendc.trace.TableColumn +import org.opendc.trace.TableReader +import java.util.* + +/** + * Internal implementation of [Table]. + */ +internal class TableImpl(val trace: TraceImpl, override val name: String) : Table { + /** + * The details of this table. + */ + private val details = trace.format.getDetails(trace.path, name) + + override val columns: List> + get() = details.columns + + override val partitionKeys: List> + get() = details.partitionKeys + + override fun newReader(): TableReader = trace.format.newReader(trace.path, name) + + override fun toString(): String = "Table[name=$name]" + + override fun hashCode(): Int = Objects.hash(trace, name) + + override fun equals(other: Any?): Boolean = other is TableImpl && trace == other.trace && name == other.name +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TraceImpl.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TraceImpl.kt new file mode 100644 index 00000000..fd9536ab --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TraceImpl.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.internal + +import org.opendc.trace.Table +import org.opendc.trace.Trace +import org.opendc.trace.spi.TraceFormat +import java.nio.file.Path +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +/** + * Internal implementation of the [Trace] interface. + */ +internal class TraceImpl(val format: TraceFormat, val path: Path) : Trace { + /** + * A map containing the [TableImpl] instances associated with the trace. + */ + private val tableMap = ConcurrentHashMap() + + override val tables: List = format.getTables(path) + + init { + for (table in tables) { + tableMap.computeIfAbsent(table) { TableImpl(this, it) } + } + } + + override fun containsTable(name: String): Boolean = tableMap.containsKey(name) + + override fun getTable(name: String): Table? = tableMap[name] + + override fun hashCode(): Int = Objects.hash(format, path) + + override fun equals(other: Any?): Boolean = other is TraceImpl && format == other.format && path == other.path +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt new file mode 100644 index 00000000..1a9b9ee1 --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TableDetails.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.spi + +import org.opendc.trace.Table +import org.opendc.trace.TableColumn + +/** + * A class used by the [TraceFormat] interface for describing the metadata of a [Table]. + * + * @param columns The available columns in the table. + * @param partitionKeys The table columns that act as partition keys for the table. + */ +public data class TableDetails( + val columns: List>, + val partitionKeys: List> = emptyList() +) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt index 54029fcf..e04dd948 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt @@ -22,8 +22,8 @@ package org.opendc.trace.spi -import org.opendc.trace.Trace -import java.net.URL +import org.opendc.trace.TableReader +import java.nio.file.Path import java.util.* /** @@ -36,11 +36,32 @@ public interface TraceFormat { public val name: String /** - * Open a new [Trace] with this provider. + * Return the name of the tables available in the trace at the specified [path]. * - * @param url A reference to the trace. + * @param path The path to the trace. + * @return The list of tables available in the trace. */ - public fun open(url: URL): Trace + public fun getTables(path: Path): List + + /** + * Return the details of [table] in the trace at the specified [path]. + * + * @param path The path to the trace. + * @param table The name of the table to obtain the details for. + * @throws IllegalArgumentException If [table] does not exist. + * @return The [TableDetails] for the specified [table]. + */ + public fun getDetails(path: Path, table: String): TableDetails + + /** + * Open a [TableReader] for the specified [table]. + * + * @param path The path to the trace to open. + * @param table The name of the table to open a [TableReader] for. + * @throws IllegalArgumentException If [table] does not exist. + * @return A [TableReader] instance for the table. + */ + public fun newReader(path: Path, table: String): TableReader /** * A helper object for resolving providers. @@ -49,6 +70,7 @@ public interface TraceFormat { /** * A list of [TraceFormat] that are available on this system. */ + @JvmStatic public val installedProviders: List by lazy { val loader = ServiceLoader.load(TraceFormat::class.java) loader.toList() @@ -57,6 +79,7 @@ public interface TraceFormat { /** * Obtain a [TraceFormat] implementation by [name]. */ + @JvmStatic public fun byName(name: String): TraceFormat? = installedProviders.find { it.name == name } } } diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt deleted file mode 100644 index 285e7216..00000000 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceStateTable.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import org.opendc.trace.util.CompositeTableReader -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] for the Azure v1 VM traces. - */ -internal class AzureResourceStateTable(private val factory: CsvFactory, path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = Files.walk(path.resolve("vm_cpu_readings"), 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_CPU_USAGE_PCT - ) - - override val partitionKeys: List> = listOf(RESOURCE_STATE_TIMESTAMP) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : CompositeTableReader() { - override fun nextReader(): TableReader? { - return if (it.hasNext()) { - val (_, path) = it.next() - return AzureResourceStateTableReader(factory.createParser(path.toFile())) - } else { - null - } - } - - override fun toString(): String = "AzureCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - return AzureResourceStateTableReader(factory.createParser(path.toFile())) - } - - override fun toString(): String = "AzureResourceStateTable" -} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt deleted file mode 100644 index ff7af172..00000000 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureResourceTable.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * The resource [Table] for the Azure v1 VM traces. - */ -internal class AzureResourceTable(private val factory: CsvFactory, private val path: Path) : Table { - override val name: String = TABLE_RESOURCES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_START_TIME, - RESOURCE_STOP_TIME, - RESOURCE_CPU_COUNT, - RESOURCE_MEM_CAPACITY - ) - - override val partitionKeys: List> = emptyList() - - override fun newReader(): TableReader { - return AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("No partition $partition") - } - - override fun toString(): String = "AzureResourceTable" -} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt deleted file mode 100644 index c7e7dc36..00000000 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTrace.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.azure - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the Azure v1 VM traces. - */ -public class AzureTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = name in tables - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> AzureResourceTable(factory, path) - TABLE_RESOURCE_STATES -> AzureResourceStateTable(factory, path) - else -> null - } - } - - override fun toString(): String = "AzureTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt index 1230d857..77af0d81 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt @@ -24,10 +24,15 @@ package org.opendc.trace.azure import com.fasterxml.jackson.dataformat.csv.CsvFactory import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import org.opendc.trace.util.CompositeTableReader +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension /** * A format implementation for the Azure v1 format. @@ -45,12 +50,60 @@ public class AzureTraceFormat : TraceFormat { .enable(CsvParser.Feature.ALLOW_COMMENTS) .enable(CsvParser.Feature.TRIM_SPACES) + override fun getTables(path: Path): List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_RESOURCES -> TableDetails( + listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_CPU_COUNT, + RESOURCE_MEM_CAPACITY + ) + ) + TABLE_RESOURCE_STATES -> TableDetails( + listOf( + RESOURCE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_CPU_USAGE_PCT + ), + listOf(RESOURCE_STATE_TIMESTAMP) + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_RESOURCES -> AzureResourceTableReader(factory.createParser(path.resolve("vmtable/vmtable.csv").toFile())) + TABLE_RESOURCE_STATES -> newResourceStateReader(path) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + /** - * Open the trace file. + * Construct a [TableReader] for reading over all VM CPU readings. */ - override fun open(url: URL): AzureTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return AzureTrace(factory, path) + private fun newResourceStateReader(path: Path): TableReader { + val partitions = Files.walk(path.resolve("vm_cpu_readings"), 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + val it = partitions.iterator() + + return object : CompositeTableReader() { + override fun nextReader(): TableReader? { + return if (it.hasNext()) { + val (_, partPath) = it.next() + return AzureResourceStateTableReader(factory.createParser(partPath.toFile())) + } else { + null + } + } + + override fun toString(): String = "AzureCompositeTableReader" + } } } diff --git a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt index 2c1a2125..b73bb728 100644 --- a/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-azure/src/test/kotlin/org/opendc/trace/azure/AzureTraceFormatTest.kt @@ -26,8 +26,7 @@ import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.trace.* -import java.io.File -import java.net.URL +import java.nio.file.Paths /** * Test suite for the [AzureTraceFormat] class. @@ -35,55 +34,30 @@ import java.net.URL class AzureTraceFormatTest { private val format = AzureTraceFormat() - @Test - fun testTraceExists() { - val url = File("src/test/resources/trace").toURI().toURL() - assertDoesNotThrow { - format.open(url) - } - } - - @Test - fun testTraceDoesNotExists() { - val url = File("src/test/resources/trace").toURI().toURL() - assertThrows { - format.open(URL(url.toString() + "help")) - } - } - @Test fun testTables() { - val url = File("src/test/resources/trace").toURI().toURL() - val trace = format.open(url) + val path = Paths.get("src/test/resources/trace") - assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) + assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), format.getTables(path)) } @Test fun testTableExists() { - val url = File("src/test/resources/trace").toURI().toURL() - val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + val path = Paths.get("src/test/resources/trace") - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + assertDoesNotThrow { format.getDetails(path, TABLE_RESOURCE_STATES) } } @Test fun testTableDoesNotExist() { - val url = File("src/test/resources/trace").toURI().toURL() - val trace = format.open(url) - - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + val path = Paths.get("src/test/resources/trace") + assertThrows { format.getDetails(path, "test") } } @Test fun testResources() { - val url = File("src/test/resources/trace").toURI().toURL() - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() - + val path = Paths.get("src/test/resources/trace") + val reader = format.newReader(path, TABLE_RESOURCES) assertAll( { assertTrue(reader.nextRow()) }, { assertEquals("x/XsOfHO4ocsV99i4NluqKDuxctW2MMVmwqOPAlg4wp8mqbBOe3wxBlQo0+Qx+uf", reader.get(RESOURCE_ID)) }, @@ -96,10 +70,8 @@ class AzureTraceFormatTest { @Test fun testSmoke() { - val url = File("src/test/resources/trace").toURI().toURL() - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + val path = Paths.get("src/test/resources/trace") + val reader = format.newReader(path, TABLE_RESOURCE_STATES) assertAll( { assertTrue(reader.nextRow()) }, diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt deleted file mode 100644 index 7cb58226..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExResourceStateTable.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.bitbrains - -import org.opendc.trace.* -import org.opendc.trace.util.CompositeTableReader -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.bufferedReader -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] in the extended Bitbrains format. - */ -internal class BitbrainsExResourceStateTable(path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "txt" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_CLUSTER_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_CPU_COUNT, - RESOURCE_CPU_CAPACITY, - RESOURCE_STATE_CPU_USAGE, - RESOURCE_STATE_CPU_USAGE_PCT, - RESOURCE_STATE_CPU_DEMAND, - RESOURCE_STATE_CPU_READY_PCT, - RESOURCE_MEM_CAPACITY, - RESOURCE_STATE_DISK_READ, - RESOURCE_STATE_DISK_WRITE, - ) - - override val partitionKeys: List> = listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : CompositeTableReader() { - override fun nextReader(): TableReader? { - return if (it.hasNext()) { - val (_, path) = it.next() - val reader = path.bufferedReader() - return BitbrainsExResourceStateTableReader(reader) - } else { - null - } - } - - override fun toString(): String = "SvCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - val reader = path.bufferedReader() - return BitbrainsExResourceStateTableReader(reader) - } - - override fun toString(): String = "BitbrainsExResourceStateTable" -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt deleted file mode 100644 index f16c493d..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTrace.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.bitbrains - -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the extended Bitbrains format. - */ -public class BitbrainsExTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = TABLE_RESOURCE_STATES == name - - override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null - } - - return BitbrainsExResourceStateTable(path) - } - - override fun toString(): String = "BitbrainsExTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt index 06388a84..080b73de 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt @@ -22,10 +22,16 @@ package org.opendc.trace.bitbrains +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import org.opendc.trace.util.CompositeTableReader +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.bufferedReader +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension /** * A format implementation for the extended Bitbrains trace format. @@ -36,12 +42,59 @@ public class BitbrainsExTraceFormat : TraceFormat { */ override val name: String = "bitbrains-ex" + override fun getTables(path: Path): List = listOf(TABLE_RESOURCE_STATES) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_RESOURCE_STATES -> TableDetails( + listOf( + RESOURCE_ID, + RESOURCE_CLUSTER_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_CPU_COUNT, + RESOURCE_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT, + RESOURCE_STATE_CPU_DEMAND, + RESOURCE_STATE_CPU_READY_PCT, + RESOURCE_MEM_CAPACITY, + RESOURCE_STATE_DISK_READ, + RESOURCE_STATE_DISK_WRITE + ), + listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_RESOURCE_STATES -> newResourceStateReader(path) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + /** - * Open the trace file. + * Construct a [TableReader] for reading over all resource state partitions. */ - override fun open(url: URL): BitbrainsExTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return BitbrainsExTrace(path) + private fun newResourceStateReader(path: Path): TableReader { + val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "txt" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + val it = partitions.iterator() + + return object : CompositeTableReader() { + override fun nextReader(): TableReader? { + return if (it.hasNext()) { + val (_, partPath) = it.next() + return BitbrainsExResourceStateTableReader(partPath.bufferedReader()) + } else { + null + } + } + + override fun toString(): String = "BitbrainsExCompositeTableReader" + } } } diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt deleted file mode 100644 index 7b08b8be..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceStateTable.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.bitbrains - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import org.opendc.trace.util.CompositeTableReader -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resource state [Table] in the Bitbrains format. - */ -internal class BitbrainsResourceStateTable(private val factory: CsvFactory, path: Path) : Table { - /** - * The partitions that belong to the table. - */ - private val partitions = - Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCE_STATES - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_CPU_COUNT, - RESOURCE_CPU_CAPACITY, - RESOURCE_STATE_CPU_USAGE, - RESOURCE_STATE_CPU_USAGE_PCT, - RESOURCE_MEM_CAPACITY, - RESOURCE_STATE_MEM_USAGE, - RESOURCE_STATE_DISK_READ, - RESOURCE_STATE_DISK_WRITE, - RESOURCE_STATE_NET_RX, - RESOURCE_STATE_NET_TX, - ) - - override val partitionKeys: List> = listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) - - override fun newReader(): TableReader { - val it = partitions.iterator() - - return object : CompositeTableReader() { - override fun nextReader(): TableReader? { - return if (it.hasNext()) { - val (partition, path) = it.next() - return BitbrainsResourceStateTableReader(partition, factory.createParser(path.toFile())) - } else { - null - } - } - - override fun toString(): String = "BitbrainsCompositeTableReader" - } - } - - override fun newReader(partition: String): TableReader { - val path = requireNotNull(partitions[partition]) { "Invalid partition $partition" } - return BitbrainsResourceStateTableReader(partition, factory.createParser(path.toFile())) - } - - override fun toString(): String = "BitbrainsResourceStateTable" -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt deleted file mode 100644 index d024af2d..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsResourceTable.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.bitbrains - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.extension -import kotlin.io.path.nameWithoutExtension - -/** - * The resources [Table] in the Bitbrains format. - */ -internal class BitbrainsResourceTable(private val factory: CsvFactory, path: Path) : Table { - /** - * The VMs that belong to the table. - */ - private val vms = - Files.walk(path, 1) - .filter { !Files.isDirectory(it) && it.extension == "csv" } - .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) - .toSortedMap() - - override val name: String = TABLE_RESOURCES - - override val isSynthetic: Boolean = true - - override val columns: List> = listOf(RESOURCE_ID) - - override val partitionKeys: List> = emptyList() - - override fun newReader(): TableReader { - return BitbrainsResourceTableReader(factory, vms) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } - - override fun toString(): String = "BitbrainsResourceTable" -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt deleted file mode 100644 index bcd8dd52..00000000 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTrace.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.bitbrains - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * [Trace] implementation for the Bitbrains format. - */ -public class BitbrainsTrace internal constructor(private val factory: CsvFactory, private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = tables.contains(name) - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> BitbrainsResourceTable(factory, path) - TABLE_RESOURCE_STATES -> BitbrainsResourceStateTable(factory, path) - else -> null - } - } - - override fun toString(): String = "BitbrainsTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt index 55b11fe3..1573726f 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt @@ -24,10 +24,15 @@ package org.opendc.trace.bitbrains import com.fasterxml.jackson.dataformat.csv.CsvFactory import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import org.opendc.trace.util.CompositeTableReader +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension /** * A format implementation for the GWF trace format. @@ -45,12 +50,67 @@ public class BitbrainsTraceFormat : TraceFormat { .enable(CsvParser.Feature.ALLOW_COMMENTS) .enable(CsvParser.Feature.TRIM_SPACES) + override fun getTables(path: Path): List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_RESOURCES -> TableDetails(listOf(RESOURCE_ID)) + TABLE_RESOURCE_STATES -> TableDetails( + listOf( + RESOURCE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_CPU_COUNT, + RESOURCE_CPU_CAPACITY, + RESOURCE_STATE_CPU_USAGE, + RESOURCE_STATE_CPU_USAGE_PCT, + RESOURCE_MEM_CAPACITY, + RESOURCE_STATE_MEM_USAGE, + RESOURCE_STATE_DISK_READ, + RESOURCE_STATE_DISK_WRITE, + RESOURCE_STATE_NET_RX, + RESOURCE_STATE_NET_TX, + ), + listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_RESOURCES -> { + val vms = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + BitbrainsResourceTableReader(factory, vms) + } + TABLE_RESOURCE_STATES -> newResourceStateReader(path) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + /** - * Open a Bitbrains trace. + * Construct a [TableReader] for reading over all resource state partitions. */ - override fun open(url: URL): BitbrainsTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return BitbrainsTrace(factory, path) + private fun newResourceStateReader(path: Path): TableReader { + val partitions = Files.walk(path, 1) + .filter { !Files.isDirectory(it) && it.extension == "csv" } + .collect(Collectors.toMap({ it.nameWithoutExtension }, { it })) + .toSortedMap() + val it = partitions.iterator() + + return object : CompositeTableReader() { + override fun nextReader(): TableReader? { + return if (it.hasNext()) { + val (partition, partPath) = it.next() + return BitbrainsResourceStateTableReader(partition, factory.createParser(partPath.toFile())) + } else { + null + } + } + + override fun toString(): String = "BitbrainsCompositeTableReader" + } } } diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt index 2e4f176a..d734cf5f 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormatTest.kt @@ -26,62 +26,38 @@ import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.trace.* -import java.net.URL +import java.nio.file.Paths /** * Test suite for the [BitbrainsExTraceFormat] class. */ -class BitbrainsExTraceFormatTest { +internal class BitbrainsExTraceFormatTest { private val format = BitbrainsExTraceFormat() - @Test - fun testTraceExists() { - val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) - assertDoesNotThrow { - format.open(url) - } - } - - @Test - fun testTraceDoesNotExists() { - val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) - assertThrows { - format.open(URL(url.toString() + "help")) - } - } - @Test fun testTables() { - val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) - val trace = format.open(url) + val path = Paths.get("src/test/resources/vm.txt") - assertEquals(listOf(TABLE_RESOURCE_STATES), trace.tables) + assertEquals(listOf(TABLE_RESOURCE_STATES), format.getTables(path)) } @Test fun testTableExists() { - val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) - val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + val path = Paths.get("src/test/resources/vm.txt") - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + assertDoesNotThrow { format.getDetails(path, TABLE_RESOURCE_STATES) } } @Test fun testTableDoesNotExist() { - val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) - val trace = format.open(url) - - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + val path = Paths.get("src/test/resources/vm.txt") + assertThrows { format.getDetails(path, "test") } } @Test fun testSmoke() { - val url = checkNotNull(BitbrainsExTraceFormatTest::class.java.getResource("/vm.txt")) - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + val path = Paths.get("src/test/resources/vm.txt") + val reader = format.newReader(path, TABLE_RESOURCE_STATES) assertAll( { assertTrue(reader.nextRow()) }, diff --git a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt index ff4a33f8..41e7def2 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/test/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormatTest.kt @@ -26,66 +26,38 @@ import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.trace.* -import java.net.URL +import java.nio.file.Paths /** * Test suite for the [BitbrainsTraceFormat] class. */ class BitbrainsTraceFormatTest { - @Test - fun testTraceExists() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - assertDoesNotThrow { - format.open(url) - } - } - - @Test - fun testTraceDoesNotExists() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - assertThrows { - format.open(URL(url.toString() + "help")) - } - } + private val format = BitbrainsTraceFormat() @Test fun testTables() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - val trace = format.open(url) + val path = Paths.get("src/test/resources/bitbrains.csv") - assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) + assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), format.getTables(path)) } @Test fun testTableExists() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + val path = Paths.get("src/test/resources/bitbrains.csv") - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + assertDoesNotThrow { format.getDetails(path, TABLE_RESOURCE_STATES) } } @Test fun testTableDoesNotExist() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - val trace = format.open(url) - - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + val path = Paths.get("src/test/resources/bitbrains.csv") + assertThrows { format.getDetails(path, "test") } } @Test fun testResources() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() + val path = Paths.get("src/test/resources/bitbrains.csv") + val reader = format.newReader(path, TABLE_RESOURCES) assertAll( { assertTrue(reader.nextRow()) }, @@ -98,11 +70,8 @@ class BitbrainsTraceFormatTest { @Test fun testSmoke() { - val format = BitbrainsTraceFormat() - val url = checkNotNull(BitbrainsTraceFormatTest::class.java.getResource("/bitbrains.csv")) - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + val path = Paths.get("src/test/resources/bitbrains.csv") + val reader = format.newReader(path, TABLE_RESOURCE_STATES) assertAll( { assertTrue(reader.nextRow()) }, diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt deleted file mode 100644 index ca720de4..00000000 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTaskTable.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.gwf - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.net.URL - -/** - * A [Table] containing the tasks in a GWF trace. - */ -internal class GwfTaskTable(private val factory: CsvFactory, private val url: URL) : Table { - override val name: String = TABLE_TASKS - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - TASK_WORKFLOW_ID, - TASK_ID, - TASK_SUBMIT_TIME, - TASK_RUNTIME, - TASK_REQ_NCPUS, - TASK_ALLOC_NCPUS, - TASK_PARENTS - ) - - override val partitionKeys: List> = listOf(TASK_WORKFLOW_ID) - - override fun newReader(): TableReader { - return GwfTaskTableReader(factory.createParser(url)) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Invalid partition $partition") - } - - override fun toString(): String = "GwfTaskTable" -} diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt deleted file mode 100644 index 166c1e56..00000000 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTrace.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.gwf - -import com.fasterxml.jackson.dataformat.csv.CsvFactory -import org.opendc.trace.* -import java.net.URL - -/** - * [Trace] implementation for the GWF format. - */ -public class GwfTrace internal constructor(private val factory: CsvFactory, private val url: URL) : Trace { - override val tables: List = listOf(TABLE_TASKS) - - override fun containsTable(name: String): Boolean = TABLE_TASKS == name - - override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null - } - - return GwfTaskTable(factory, url) - } - - override fun toString(): String = "GwfTrace[$url]" -} diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt index 6d542503..0f7b9d6e 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt @@ -24,10 +24,10 @@ package org.opendc.trace.gwf import com.fasterxml.jackson.dataformat.csv.CsvFactory import com.fasterxml.jackson.dataformat.csv.CsvParser +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import java.nio.file.Path /** * A [TraceFormat] implementation for the GWF trace format. @@ -45,12 +45,30 @@ public class GwfTraceFormat : TraceFormat { .enable(CsvParser.Feature.ALLOW_COMMENTS) .enable(CsvParser.Feature.TRIM_SPACES) - /** - * Read the tasks in the GWF trace. - */ - public override fun open(url: URL): GwfTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return GwfTrace(factory, url) + override fun getTables(path: Path): List = listOf(TABLE_TASKS) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_TASKS -> TableDetails( + listOf( + TASK_WORKFLOW_ID, + TASK_ID, + TASK_SUBMIT_TIME, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_ALLOC_NCPUS, + TASK_PARENTS, + ), + listOf(TASK_WORKFLOW_ID) + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_TASKS -> GwfTaskTableReader(factory.createParser(path.toFile())) + else -> throw IllegalArgumentException("Table $table not supported") + } } } diff --git a/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt b/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt index b209b979..7fe403b2 100644 --- a/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-gwf/src/test/kotlin/org/opendc/trace/gwf/GwfTraceFormatTest.kt @@ -22,13 +22,10 @@ package org.opendc.trace.gwf +import org.junit.jupiter.api.* import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.junit.jupiter.api.assertDoesNotThrow -import org.junit.jupiter.api.assertThrows import org.opendc.trace.* -import java.net.URL +import java.nio.file.Paths import java.time.Duration import java.time.Instant @@ -36,59 +33,32 @@ import java.time.Instant * Test suite for the [GwfTraceFormat] class. */ internal class GwfTraceFormatTest { - @Test - fun testTraceExists() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - assertDoesNotThrow { - format.open(input) - } - } - - @Test - fun testTraceDoesNotExists() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - assertThrows { - format.open(URL(input.toString() + "help")) - } - } + private val format = GwfTraceFormat() @Test fun testTables() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - val trace = format.open(input) + val path = Paths.get(checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")).toURI()) - assertEquals(listOf(TABLE_TASKS), trace.tables) + assertEquals(listOf(TABLE_TASKS), format.getTables(path)) } @Test fun testTableExists() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS) - - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + val path = Paths.get(checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")).toURI()) + assertDoesNotThrow { format.getDetails(path, TABLE_TASKS) } } @Test fun testTableDoesNotExist() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - val trace = format.open(input) + val path = Paths.get(checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")).toURI()) - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + assertThrows { format.getDetails(path, "test") } } @Test fun testTableReader() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS)!! - val reader = table.newReader() + val path = Paths.get(checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")).toURI()) + val reader = format.newReader(path, TABLE_TASKS) assertAll( { assertTrue(reader.nextRow()) }, @@ -99,13 +69,4 @@ internal class GwfTraceFormatTest { { assertEquals(emptySet(), reader.get(TASK_PARENTS)) }, ) } - - @Test - fun testTableReaderPartition() { - val input = checkNotNull(GwfTraceFormatTest::class.java.getResource("/trace.gwf")) - val format = GwfTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS)!! - - assertThrows { table.newReader("test") } - } } diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt deleted file mode 100644 index caacf192..00000000 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.opendc - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * The resource state [Table] in the OpenDC virtual machine trace format. - */ -internal class OdcVmResourceStateTable(private val path: Path) : Table { - override val name: String = TABLE_RESOURCE_STATES - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_STATE_TIMESTAMP, - RESOURCE_STATE_DURATION, - RESOURCE_CPU_COUNT, - RESOURCE_STATE_CPU_USAGE, - ) - - override val partitionKeys: List> = listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("trace.parquet")) - return OdcVmResourceStateTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } -} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt deleted file mode 100644 index 653b28b8..00000000 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.opendc - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * The resource [Table] for the OpenDC virtual machine trace format. - */ -internal class OdcVmResourceTable(private val path: Path) : Table { - override val name: String = TABLE_RESOURCES - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - RESOURCE_ID, - RESOURCE_START_TIME, - RESOURCE_STOP_TIME, - RESOURCE_CPU_COUNT, - RESOURCE_MEM_CAPACITY, - ) - - override val partitionKeys: List> = emptyList() - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("meta.parquet")) - return OdcVmResourceTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Unknown partition $partition") - } -} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt deleted file mode 100644 index 3e5029b4..00000000 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.opendc - -import org.opendc.trace.TABLE_RESOURCES -import org.opendc.trace.TABLE_RESOURCE_STATES -import org.opendc.trace.Table -import org.opendc.trace.Trace -import java.nio.file.Path - -/** - * A [Trace] in the OpenDC virtual machine trace format. - */ -public class OdcVmTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) - - override fun containsTable(name: String): Boolean = - name == TABLE_RESOURCES || name == TABLE_RESOURCE_STATES - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_RESOURCES -> OdcVmResourceTable(path) - TABLE_RESOURCE_STATES -> OdcVmResourceStateTable(path) - else -> null - } - } - - override fun toString(): String = "OdcVmTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt index 8edba725..29818147 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt @@ -24,11 +24,13 @@ package org.opendc.trace.opendc import org.apache.avro.Schema import org.apache.avro.SchemaBuilder +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat +import org.opendc.trace.util.parquet.LocalParquetReader import org.opendc.trace.util.parquet.TIMESTAMP_SCHEMA -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import java.nio.file.Path /** * A [TraceFormat] implementation of the OpenDC virtual machine trace format. @@ -39,13 +41,45 @@ public class OdcVmTraceFormat : TraceFormat { */ override val name: String = "opendc-vm" - /** - * Open a Bitbrains Parquet trace. - */ - override fun open(url: URL): OdcVmTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return OdcVmTrace(path) + override fun getTables(path: Path): List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_RESOURCES -> TableDetails( + listOf( + RESOURCE_ID, + RESOURCE_START_TIME, + RESOURCE_STOP_TIME, + RESOURCE_CPU_COUNT, + RESOURCE_MEM_CAPACITY, + ) + ) + TABLE_RESOURCE_STATES -> TableDetails( + listOf( + RESOURCE_ID, + RESOURCE_STATE_TIMESTAMP, + RESOURCE_STATE_DURATION, + RESOURCE_CPU_COUNT, + RESOURCE_STATE_CPU_USAGE, + ), + listOf(RESOURCE_ID, RESOURCE_STATE_TIMESTAMP) + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_RESOURCES -> { + val reader = LocalParquetReader(path.resolve("meta.parquet")) + OdcVmResourceTableReader(reader) + } + TABLE_RESOURCE_STATES -> { + val reader = LocalParquetReader(path.resolve("trace.parquet")) + OdcVmResourceStateTableReader(reader) + } + else -> throw IllegalArgumentException("Table $table not supported") + } } public companion object { diff --git a/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt index 9fb6028d..bfe0f881 100644 --- a/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt @@ -29,8 +29,7 @@ import org.junit.jupiter.api.assertThrows import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import org.opendc.trace.* -import java.io.File -import java.net.URL +import java.nio.file.Paths /** * Test suite for the [OdcVmTraceFormat] implementation. @@ -38,53 +37,31 @@ import java.net.URL internal class OdcVmTraceFormatTest { private val format = OdcVmTraceFormat() - @Test - fun testTraceExists() { - val url = File("src/test/resources/trace-v2.1").toURI().toURL() - assertDoesNotThrow { format.open(url) } - } - - @Test - fun testTraceDoesNotExists() { - val url = File("src/test/resources/trace-v2.1").toURI().toURL() - assertThrows { - format.open(URL(url.toString() + "help")) - } - } - @Test fun testTables() { - val url = File("src/test/resources/trace-v2.1").toURI().toURL() - val trace = format.open(url) + val path = Paths.get("src/test/resources/trace-v2.1") - assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables) + assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), format.getTables(path)) } @Test fun testTableExists() { - val url = File("src/test/resources/trace-v2.1").toURI().toURL() - val table = format.open(url).getTable(TABLE_RESOURCE_STATES) + val path = Paths.get("src/test/resources/trace-v2.1") - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + assertDoesNotThrow { format.getDetails(path, TABLE_RESOURCE_STATES) } } @Test fun testTableDoesNotExist() { - val url = File("src/test/resources/trace-v2.1").toURI().toURL() - val trace = format.open(url) - - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + val path = Paths.get("src/test/resources/trace-v2.1") + assertThrows { format.getDetails(path, "test") } } @ParameterizedTest @ValueSource(strings = ["trace-v2.0", "trace-v2.1"]) fun testResources(name: String) { - val url = File("src/test/resources/$name").toURI().toURL() - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCES)!!.newReader() + val path = Paths.get("src/test/resources/$name") + val reader = format.newReader(path, TABLE_RESOURCES) assertAll( { assertTrue(reader.nextRow()) }, @@ -104,10 +81,8 @@ internal class OdcVmTraceFormatTest { @ParameterizedTest @ValueSource(strings = ["trace-v2.0", "trace-v2.1"]) fun testSmoke(name: String) { - val url = File("src/test/resources/$name").toURI().toURL() - val trace = format.open(url) - - val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader() + val path = Paths.get("src/test/resources/$name") + val reader = format.newReader(path, TABLE_RESOURCE_STATES) assertAll( { assertTrue(reader.nextRow()) }, diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt deleted file mode 100644 index 4898779d..00000000 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTaskTable.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.swf - -import org.opendc.trace.* -import java.nio.file.Path -import kotlin.io.path.bufferedReader - -/** - * A [Table] containing the tasks in a SWF trace. - */ -internal class SwfTaskTable(private val path: Path) : Table { - override val name: String = TABLE_TASKS - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - TASK_ID, - TASK_SUBMIT_TIME, - TASK_WAIT_TIME, - TASK_RUNTIME, - TASK_REQ_NCPUS, - TASK_ALLOC_NCPUS, - TASK_PARENTS, - TASK_STATUS, - TASK_GROUP_ID, - TASK_USER_ID - ) - - override val partitionKeys: List> = emptyList() - - override fun newReader(): TableReader { - val reader = path.bufferedReader() - return SwfTaskTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Invalid partition $partition") - } - - override fun toString(): String = "SwfTaskTable" -} diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt deleted file mode 100644 index d4da735e..00000000 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTrace.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.swf - -import org.opendc.trace.TABLE_TASKS -import org.opendc.trace.Table -import org.opendc.trace.Trace -import java.nio.file.Path - -/** - * [Trace] implementation for the SWF format. - */ -public class SwfTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_TASKS) - - override fun containsTable(name: String): Boolean = TABLE_TASKS == name - - override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null - } - return SwfTaskTable(path) - } - - override fun toString(): String = "SwfTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt index 36c3122e..4cb7e49e 100644 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt @@ -22,10 +22,11 @@ package org.opendc.trace.swf +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import java.nio.file.Path +import kotlin.io.path.bufferedReader /** * Support for the Standard Workload Format (SWF) in OpenDC. @@ -35,9 +36,33 @@ import kotlin.io.path.exists public class SwfTraceFormat : TraceFormat { override val name: String = "swf" - override fun open(url: URL): SwfTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return SwfTrace(path) + override fun getTables(path: Path): List = listOf(TABLE_TASKS) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_TASKS -> TableDetails( + listOf( + TASK_ID, + TASK_SUBMIT_TIME, + TASK_WAIT_TIME, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_ALLOC_NCPUS, + TASK_PARENTS, + TASK_STATUS, + TASK_GROUP_ID, + TASK_USER_ID + ), + emptyList() + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_TASKS -> SwfTaskTableReader(path.bufferedReader()) + else -> throw IllegalArgumentException("Table $table not supported") + } } } diff --git a/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt index 828c2bfa..4dcd43f6 100644 --- a/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-swf/src/test/kotlin/org/opendc/trace/swf/SwfTraceFormatTest.kt @@ -27,61 +27,38 @@ import org.junit.jupiter.api.Assertions.* import org.opendc.trace.TABLE_TASKS import org.opendc.trace.TASK_ALLOC_NCPUS import org.opendc.trace.TASK_ID -import java.net.URL +import java.nio.file.Paths /** * Test suite for the [SwfTraceFormat] class. */ internal class SwfTraceFormatTest { - @Test - fun testTraceExists() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val format = SwfTraceFormat() - assertDoesNotThrow { - format.open(input) - } - } - - @Test - fun testTraceDoesNotExists() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val format = SwfTraceFormat() - assertThrows { - format.open(URL(input.toString() + "help")) - } - } + private val format = SwfTraceFormat() @Test fun testTables() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val trace = SwfTraceFormat().open(input) + val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI()) - assertEquals(listOf(TABLE_TASKS), trace.tables) + assertEquals(listOf(TABLE_TASKS), format.getTables(path)) } @Test fun testTableExists() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val table = SwfTraceFormat().open(input).getTable(TABLE_TASKS) - - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI()) + assertDoesNotThrow { format.getDetails(path, TABLE_TASKS) } } @Test fun testTableDoesNotExist() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val trace = SwfTraceFormat().open(input) + val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI()) - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + assertThrows { format.getDetails(path, "test") } } @Test fun testReader() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val trace = SwfTraceFormat().open(input) - val reader = trace.getTable(TABLE_TASKS)!!.newReader() + val path = Paths.get(checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")).toURI()) + val reader = format.newReader(path, TABLE_TASKS) assertAll( { assertTrue(reader.nextRow()) }, @@ -94,14 +71,4 @@ internal class SwfTraceFormatTest { reader.close() } - - @Test - fun testReaderPartition() { - val input = checkNotNull(SwfTraceFormatTest::class.java.getResource("/trace.swf")) - val trace = SwfTraceFormat().open(input) - - assertThrows { - trace.getTable(TABLE_TASKS)!!.newReader("test") - } - } } diff --git a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt index 0b089904..cd5d287f 100644 --- a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt +++ b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt @@ -35,9 +35,6 @@ import org.apache.parquet.avro.AvroParquetWriter import org.apache.parquet.hadoop.ParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.trace.* -import org.opendc.trace.azure.AzureTraceFormat -import org.opendc.trace.bitbrains.BitbrainsExTraceFormat -import org.opendc.trace.bitbrains.BitbrainsTraceFormat import org.opendc.trace.opendc.OdcVmTraceFormat import org.opendc.trace.util.parquet.LocalOutputFile import java.io.File @@ -78,11 +75,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { * The input format of the trace. */ private val format by option("-f", "--format", help = "input format of trace") - .choice( - "solvinity" to BitbrainsExTraceFormat(), - "bitbrains" to BitbrainsTraceFormat(), - "azure" to AzureTraceFormat() - ) + .choice("bitbrains-ex", "bitbrains", "azure") .required() /** @@ -101,7 +94,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { traceParquet.delete() } - val trace = format.open(input.toURI().toURL()) + val trace = Trace.open(input, format = format) logger.info { "Building resources table" } diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt deleted file mode 100644 index 17aeee97..00000000 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTaskTable.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.wfformat - -import com.fasterxml.jackson.core.JsonFactory -import org.opendc.trace.* -import java.nio.file.Path - -/** - * A [Table] containing the tasks in a WfCommons workload trace. - */ -internal class WfFormatTaskTable(private val factory: JsonFactory, private val path: Path) : Table { - override val name: String = TABLE_TASKS - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - TASK_ID, - TASK_WORKFLOW_ID, - TASK_RUNTIME, - TASK_REQ_NCPUS, - TASK_PARENTS, - TASK_CHILDREN - ) - - override val partitionKeys: List> = emptyList() - - override fun newReader(): TableReader { - val parser = factory.createParser(path.toFile()) - return WfFormatTaskTableReader(parser) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Invalid partition $partition") - } - - override fun toString(): String = "WfFormatTaskTable" -} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt deleted file mode 100644 index 2d9c79fb..00000000 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTrace.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.wfformat - -import com.fasterxml.jackson.core.JsonFactory -import org.opendc.trace.TABLE_TASKS -import org.opendc.trace.Table -import org.opendc.trace.Trace -import java.nio.file.Path - -/** - * [Trace] implementation for the WfCommons workload trace format. - */ -public class WfFormatTrace internal constructor(private val factory: JsonFactory, private val path: Path) : Trace { - override val tables: List = listOf(TABLE_TASKS) - - override fun containsTable(name: String): Boolean = TABLE_TASKS == name - - override fun getTable(name: String): Table? { - return when (name) { - TABLE_TASKS -> WfFormatTaskTable(factory, path) - else -> null - } - } - - override fun toString(): String = "WfFormatTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt index ff8d054c..825c3d6d 100644 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt @@ -23,10 +23,10 @@ package org.opendc.trace.wfformat import com.fasterxml.jackson.core.JsonFactory +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import java.nio.file.Path /** * A [TraceFormat] implementation for the WfCommons workload trace format. @@ -39,9 +39,29 @@ public class WfFormatTraceFormat : TraceFormat { override val name: String = "wfformat" - override fun open(url: URL): WfFormatTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return WfFormatTrace(factory, path) + override fun getTables(path: Path): List = listOf(TABLE_TASKS) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_TASKS -> TableDetails( + listOf( + TASK_ID, + TASK_WORKFLOW_ID, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_PARENTS, + TASK_CHILDREN + ), + emptyList() + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_TASKS -> WfFormatTaskTableReader(factory.createParser(path.toFile())) + else -> throw IllegalArgumentException("Table $table not supported") + } } } diff --git a/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt b/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt index 0bfc8840..217b175d 100644 --- a/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-wfformat/src/test/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormatTest.kt @@ -22,59 +22,38 @@ package org.opendc.trace.wfformat +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opendc.trace.* -import java.io.File -import java.net.URL +import java.nio.file.Paths /** * Test suite for the [WfFormatTraceFormat] class. */ class WfFormatTraceFormatTest { - @Test - fun testTraceExists() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val format = WfFormatTraceFormat() - assertDoesNotThrow { format.open(input) } - } - - @Test - fun testTraceDoesNotExists() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val format = WfFormatTraceFormat() - assertThrows { format.open(URL(input.toString() + "help")) } - } + private val format = WfFormatTraceFormat() @Test fun testTables() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val format = WfFormatTraceFormat() - val trace = format.open(input) + val path = Paths.get("src/test/resources/trace.json") - assertEquals(listOf(TABLE_TASKS), trace.tables) + assertEquals(listOf(TABLE_TASKS), format.getTables(path)) } @Test fun testTableExists() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val format = WfFormatTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS) - - assertNotNull(table) - assertDoesNotThrow { table!!.newReader() } + val path = Paths.get("src/test/resources/trace.json") + Assertions.assertDoesNotThrow { format.getDetails(path, TABLE_TASKS) } } @Test fun testTableDoesNotExist() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val format = WfFormatTraceFormat() - val trace = format.open(input) + val path = Paths.get("src/test/resources/trace.json") - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + assertThrows { format.getDetails(path, "test") } } /** @@ -82,9 +61,8 @@ class WfFormatTraceFormatTest { */ @Test fun testTableReader() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val trace = WfFormatTraceFormat().open(input) - val reader = trace.getTable(TABLE_TASKS)!!.newReader() + val path = Paths.get("src/test/resources/trace.json") + val reader = format.newReader(path, TABLE_TASKS) assertAll( { assertTrue(reader.nextRow()) }, @@ -110,9 +88,8 @@ class WfFormatTraceFormatTest { */ @Test fun testTableReaderFull() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val trace = WfFormatTraceFormat().open(input) - val reader = trace.getTable(TABLE_TASKS)!!.newReader() + val path = Paths.get("src/test/resources/trace.json") + val reader = format.newReader(path, TABLE_TASKS) assertDoesNotThrow { while (reader.nextRow()) { @@ -121,13 +98,4 @@ class WfFormatTraceFormatTest { reader.close() } } - - @Test - fun testTableReaderPartition() { - val input = File("src/test/resources/trace.json").toURI().toURL() - val format = WfFormatTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS)!! - - assertThrows { table.newReader("test") } - } } diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt deleted file mode 100644 index 410bb347..00000000 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTaskTable.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.wtf - -import org.apache.avro.generic.GenericRecord -import org.opendc.trace.* -import org.opendc.trace.util.parquet.LocalParquetReader -import java.nio.file.Path - -/** - * A [Table] containing the tasks in a GWF trace. - */ -internal class WtfTaskTable(private val path: Path) : Table { - override val name: String = TABLE_TASKS - - override val isSynthetic: Boolean = false - - override val columns: List> = listOf( - TASK_ID, - TASK_WORKFLOW_ID, - TASK_SUBMIT_TIME, - TASK_WAIT_TIME, - TASK_RUNTIME, - TASK_REQ_NCPUS, - TASK_PARENTS, - TASK_CHILDREN, - TASK_GROUP_ID, - TASK_USER_ID - ) - - override val partitionKeys: List> = listOf(TASK_SUBMIT_TIME) - - override fun newReader(): TableReader { - val reader = LocalParquetReader(path.resolve("tasks/schema-1.0")) - return WtfTaskTableReader(reader) - } - - override fun newReader(partition: String): TableReader { - throw IllegalArgumentException("Invalid partition $partition") - } - - override fun toString(): String = "WtfTaskTable" -} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt deleted file mode 100644 index a755a107..00000000 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTrace.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.trace.wtf - -import org.opendc.trace.TABLE_TASKS -import org.opendc.trace.Table -import org.opendc.trace.Trace -import java.nio.file.Path - -/** - * [Trace] implementation for the WTF format. - */ -public class WtfTrace internal constructor(private val path: Path) : Trace { - override val tables: List = listOf(TABLE_TASKS) - - override fun containsTable(name: String): Boolean = TABLE_TASKS == name - - override fun getTable(name: String): Table? { - if (!containsTable(name)) { - return null - } - - return WtfTaskTable(path) - } - - override fun toString(): String = "WtfTrace[$path]" -} diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt index 781cb335..2f17694f 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt @@ -22,10 +22,12 @@ package org.opendc.trace.wtf +import org.apache.avro.generic.GenericRecord +import org.opendc.trace.* +import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat -import java.net.URL -import java.nio.file.Paths -import kotlin.io.path.exists +import org.opendc.trace.util.parquet.LocalParquetReader +import java.nio.file.Path /** * A [TraceFormat] implementation for the Workflow Trace Format (WTF). @@ -33,9 +35,36 @@ import kotlin.io.path.exists public class WtfTraceFormat : TraceFormat { override val name: String = "wtf" - override fun open(url: URL): WtfTrace { - val path = Paths.get(url.toURI()) - require(path.exists()) { "URL $url does not exist" } - return WtfTrace(path) + override fun getTables(path: Path): List = listOf(TABLE_TASKS) + + override fun getDetails(path: Path, table: String): TableDetails { + return when (table) { + TABLE_TASKS -> TableDetails( + listOf( + TASK_ID, + TASK_WORKFLOW_ID, + TASK_SUBMIT_TIME, + TASK_WAIT_TIME, + TASK_RUNTIME, + TASK_REQ_NCPUS, + TASK_PARENTS, + TASK_CHILDREN, + TASK_GROUP_ID, + TASK_USER_ID + ), + listOf(TASK_SUBMIT_TIME) + ) + else -> throw IllegalArgumentException("Table $table not supported") + } + } + + override fun newReader(path: Path, table: String): TableReader { + return when (table) { + TABLE_TASKS -> { + val reader = LocalParquetReader(path.resolve("tasks/schema-1.0")) + WtfTaskTableReader(reader) + } + else -> throw IllegalArgumentException("Table $table not supported") + } } } diff --git a/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt b/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt index b155f265..09c3703a 100644 --- a/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt +++ b/opendc-trace/opendc-trace-wtf/src/test/kotlin/org/opendc/trace/wtf/WtfTraceFormatTest.kt @@ -26,8 +26,7 @@ import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.trace.* -import java.io.File -import java.net.URL +import java.nio.file.Paths import java.time.Duration import java.time.Instant @@ -35,51 +34,25 @@ import java.time.Instant * Test suite for the [WtfTraceFormat] class. */ class WtfTraceFormatTest { - @Test - fun testTraceExists() { - val input = File("src/test/resources/wtf-trace").toURI().toURL() - val format = WtfTraceFormat() - org.junit.jupiter.api.assertDoesNotThrow { - format.open(input) - } - } - - @Test - fun testTraceDoesNotExists() { - val input = File("src/test/resources/wtf-trace").toURI().toURL() - val format = WtfTraceFormat() - assertThrows { - format.open(URL(input.toString() + "help")) - } - } + private val format = WtfTraceFormat() @Test fun testTables() { - val input = File("src/test/resources/wtf-trace").toURI().toURL() - val format = WtfTraceFormat() - val trace = format.open(input) - - assertEquals(listOf(TABLE_TASKS), trace.tables) + val path = Paths.get("src/test/resources/wtf-trace") + assertEquals(listOf(TABLE_TASKS), format.getTables(path)) } @Test fun testTableExists() { - val input = File("src/test/resources/wtf-trace").toURI().toURL() - val format = WtfTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS) - - assertNotNull(table) - org.junit.jupiter.api.assertDoesNotThrow { table!!.newReader() } + val path = Paths.get("src/test/resources/wtf-trace") + assertDoesNotThrow { format.getDetails(path, TABLE_TASKS) } } @Test fun testTableDoesNotExist() { - val input = File("src/test/resources/wtf-trace").toURI().toURL() - val format = WtfTraceFormat() - val trace = format.open(input) + val path = Paths.get("src/test/resources/wtf-trace") - assertFalse(trace.containsTable("test")) - assertNull(trace.getTable("test")) + assertThrows { format.getDetails(path, "test") } } /** @@ -87,9 +60,8 @@ class WtfTraceFormatTest { */ @Test fun testTableReader() { - val input = File("src/test/resources/wtf-trace") - val trace = WtfTraceFormat().open(input.toURI().toURL()) - val reader = trace.getTable(TABLE_TASKS)!!.newReader() + val path = Paths.get("src/test/resources/wtf-trace") + val reader = format.newReader(path, TABLE_TASKS) assertAll( { assertTrue(reader.nextRow()) }, @@ -111,13 +83,4 @@ class WtfTraceFormatTest { reader.close() } - - @Test - fun testTableReaderPartition() { - val input = File("src/test/resources/wtf-trace").toURI().toURL() - val format = WtfTraceFormat() - val table = format.open(input).getTable(TABLE_TASKS)!! - - assertThrows { table.newReader("test") } - } } diff --git a/opendc-workflow/opendc-workflow-service/build.gradle.kts b/opendc-workflow/opendc-workflow-service/build.gradle.kts index 941202d2..43b64b15 100644 --- a/opendc-workflow/opendc-workflow-service/build.gradle.kts +++ b/opendc-workflow/opendc-workflow-service/build.gradle.kts @@ -39,7 +39,8 @@ dependencies { testImplementation(projects.opendcSimulator.opendcSimulatorCore) testImplementation(projects.opendcCompute.opendcComputeSimulator) - testImplementation(projects.opendcTrace.opendcTraceGwf) + testImplementation(projects.opendcTrace.opendcTraceApi) testImplementation(projects.opendcTelemetry.opendcTelemetrySdk) + testRuntimeOnly(projects.opendcTrace.opendcTraceGwf) testRuntimeOnly(libs.log4j.slf4j) } diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt index 74316437..728dfd99 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt @@ -44,13 +44,14 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.sdk.toOtelClock -import org.opendc.trace.gwf.GwfTraceFormat +import org.opendc.trace.Trace import org.opendc.workflow.service.internal.WorkflowServiceImpl import org.opendc.workflow.service.scheduler.WorkflowSchedulerMode import org.opendc.workflow.service.scheduler.job.NullJobAdmissionPolicy import org.opendc.workflow.service.scheduler.job.SubmissionTimeJobOrderPolicy import org.opendc.workflow.service.scheduler.task.NullTaskEligibilityPolicy import org.opendc.workflow.service.scheduler.task.SubmissionTimeTaskOrderPolicy +import java.nio.file.Paths import java.time.Duration import java.util.* @@ -105,7 +106,10 @@ internal class WorkflowServiceTest { taskOrderPolicy = SubmissionTimeTaskOrderPolicy(), ) - val trace = GwfTraceFormat().open(checkNotNull(WorkflowServiceTest::class.java.getResource("/trace.gwf"))) + val trace = Trace.open( + Paths.get(checkNotNull(WorkflowServiceTest::class.java.getResource("/trace.gwf")).toURI()), + format = "gwf" + ) val replayer = TraceReplayer(trace) replayer.replay(clock, scheduler) -- cgit v1.2.3 From 68ef3700ed2f69bcf0118bb69eda71e6b1f4d54f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 21 Sep 2021 11:34:34 +0200 Subject: feat(trace): Add support for writing traces This change adds a new API for writing traces in a trace format. Currently, writing is only supported by the OpenDC VM format, but over time the other formats will also have support for writing added. --- .../opendc-compute-workload/build.gradle.kts | 2 +- .../opendc/compute/workload/ComputeSchedulers.kt | 86 ++++++++++++ .../compute/workload/ComputeWorkloadLoader.kt | 6 +- .../opendc/compute/workload/ComputeWorkloads.kt | 2 +- .../workload/internal/TraceComputeWorkload.kt | 4 +- .../opendc-experiments-capelin/build.gradle.kts | 4 +- .../org/opendc/experiments/capelin/Portfolio.kt | 2 +- .../experiments/capelin/util/ComputeSchedulers.kt | 86 ------------ .../src/main/kotlin/org/opendc/trace/Table.kt | 7 + .../main/kotlin/org/opendc/trace/TableWriter.kt | 151 +++++++++++++++++++++ .../src/main/kotlin/org/opendc/trace/Trace.kt | 30 +++- .../kotlin/org/opendc/trace/internal/TableImpl.kt | 3 + .../kotlin/org/opendc/trace/spi/TraceFormat.kt | 21 +++ .../org/opendc/trace/azure/AzureTraceFormat.kt | 8 ++ .../trace/bitbrains/BitbrainsExTraceFormat.kt | 8 ++ .../opendc/trace/bitbrains/BitbrainsTraceFormat.kt | 8 ++ .../kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt | 8 ++ .../trace/opendc/OdcVmResourceStateTableWriter.kt | 123 +++++++++++++++++ .../trace/opendc/OdcVmResourceTableWriter.kt | 106 +++++++++++++++ .../org/opendc/trace/opendc/OdcVmTraceFormat.kt | 43 ++++++ .../kotlin/org/opendc/trace/swf/SwfTraceFormat.kt | 8 ++ opendc-trace/opendc-trace-tools/build.gradle.kts | 11 +- .../org/opendc/trace/tools/TraceConverter.kt | 82 +++++------ .../opendc/trace/wfformat/WfFormatTraceFormat.kt | 8 ++ .../kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt | 8 ++ opendc-web/opendc-web-runner/build.gradle.kts | 4 +- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 6 +- 27 files changed, 677 insertions(+), 158 deletions(-) create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeSchedulers.kt delete mode 100644 opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt create mode 100644 opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableWriter.kt create mode 100644 opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableWriter.kt diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts index e82cf203..28a5e1da 100644 --- a/opendc-compute/opendc-compute-workload/build.gradle.kts +++ b/opendc-compute/opendc-compute-workload/build.gradle.kts @@ -32,7 +32,7 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeSimulator) - implementation(projects.opendcTrace.opendcTraceOpendc) + implementation(projects.opendcTrace.opendcTraceApi) implementation(projects.opendcTrace.opendcTraceParquet) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeSchedulers.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeSchedulers.kt new file mode 100644 index 00000000..c94f30e4 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeSchedulers.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@file:JvmName("ComputeSchedulers") +package org.opendc.compute.workload + +import org.opendc.compute.service.scheduler.ComputeScheduler +import org.opendc.compute.service.scheduler.FilterScheduler +import org.opendc.compute.service.scheduler.ReplayScheduler +import org.opendc.compute.service.scheduler.filters.ComputeFilter +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher +import org.opendc.compute.service.scheduler.weights.RamWeigher +import org.opendc.compute.service.scheduler.weights.VCpuWeigher +import java.util.* + +/** + * Create a [ComputeScheduler] for the experiment. + */ +public fun createComputeScheduler(name: String, seeder: Random, placements: Map = emptyMap()): ComputeScheduler { + val cpuAllocationRatio = 16.0 + val ramAllocationRatio = 1.5 + return when (name) { + "mem" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(RamWeigher(multiplier = 1.0)) + ) + "mem-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(RamWeigher(multiplier = -1.0)) + ) + "core-mem" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) + "core-mem-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(CoreRamWeigher(multiplier = -1.0)) + ) + "active-servers" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(InstanceCountWeigher(multiplier = -1.0)) + ) + "active-servers-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(InstanceCountWeigher(multiplier = 1.0)) + ) + "provisioned-cores" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)) + ) + "provisioned-cores-inv" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)) + ) + "random" -> FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), + weighers = emptyList(), + subsetSize = Int.MAX_VALUE, + random = Random(seeder.nextLong()) + ) + "replay" -> ReplayScheduler(placements) + else -> throw IllegalArgumentException("Unknown policy $name") + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index 6dba41e6..7c579e39 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -145,15 +145,15 @@ public class ComputeWorkloadLoader(private val baseDir: File) { } /** - * Load the trace with the specified [name]. + * Load the trace with the specified [name] and [format]. */ - public fun get(name: String): List { + public fun get(name: String, format: String): List { return cache.computeIfAbsent(name) { val path = baseDir.resolve(it) logger.info { "Loading trace $it at $path" } - val trace = Trace.open(path, format = "opendc-vm") + val trace = Trace.open(path, format) val fragments = parseFragments(trace) parseMeta(trace, fragments) } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt index f58ce587..2f4935ca 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt @@ -31,7 +31,7 @@ import org.opendc.compute.workload.internal.TraceComputeWorkload /** * Construct a workload from a trace. */ -public fun trace(name: String): ComputeWorkload = TraceComputeWorkload(name) +public fun trace(name: String, format: String = "opendc-vm"): ComputeWorkload = TraceComputeWorkload(name, format) /** * Construct a composite workload with the specified fractions. diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt index d657ff01..c20cb8f3 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt @@ -30,8 +30,8 @@ import java.util.* /** * A [ComputeWorkload] from a trace. */ -internal class TraceComputeWorkload(val name: String) : ComputeWorkload { +internal class TraceComputeWorkload(val name: String, val format: String) : ComputeWorkload { override fun resolve(loader: ComputeWorkloadLoader, random: Random): List { - return loader.get(name) + return loader.get(name, format) } } diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 4bcbaf61..23a3e4a7 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -33,8 +33,6 @@ dependencies { api(projects.opendcHarness.opendcHarnessApi) api(projects.opendcCompute.opendcComputeWorkload) - implementation(projects.opendcTrace.opendcTraceParquet) - implementation(projects.opendcTrace.opendcTraceBitbrains) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcSimulator.opendcSimulatorCompute) implementation(projects.opendcCompute.opendcComputeSimulator) @@ -49,5 +47,7 @@ dependencies { implementation(kotlin("reflect")) implementation(libs.opentelemetry.semconv) + runtimeOnly(projects.opendcTrace.opendcTraceOpendc) + testImplementation(libs.log4j.slf4j) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 630b76c4..2201a6b4 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -26,6 +26,7 @@ import com.typesafe.config.ConfigFactory import mu.KotlinLogging import org.opendc.compute.workload.ComputeWorkloadLoader import org.opendc.compute.workload.ComputeWorkloadRunner +import org.opendc.compute.workload.createComputeScheduler import org.opendc.compute.workload.export.parquet.ParquetExportMonitor import org.opendc.compute.workload.grid5000 import org.opendc.compute.workload.topology.apply @@ -34,7 +35,6 @@ import org.opendc.experiments.capelin.model.OperationalPhenomena import org.opendc.experiments.capelin.model.Topology import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.topology.clusterTopology -import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt deleted file mode 100644 index 3b7c3f0f..00000000 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/util/ComputeSchedulers.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@file:JvmName("ComputeSchedulers") -package org.opendc.experiments.capelin.util - -import org.opendc.compute.service.scheduler.ComputeScheduler -import org.opendc.compute.service.scheduler.FilterScheduler -import org.opendc.compute.service.scheduler.ReplayScheduler -import org.opendc.compute.service.scheduler.filters.ComputeFilter -import org.opendc.compute.service.scheduler.filters.RamFilter -import org.opendc.compute.service.scheduler.filters.VCpuFilter -import org.opendc.compute.service.scheduler.weights.CoreRamWeigher -import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher -import org.opendc.compute.service.scheduler.weights.RamWeigher -import org.opendc.compute.service.scheduler.weights.VCpuWeigher -import java.util.* - -/** - * Create a [ComputeScheduler] for the experiment. - */ -fun createComputeScheduler(allocationPolicy: String, seeder: Random, vmPlacements: Map = emptyMap()): ComputeScheduler { - val cpuAllocationRatio = 16.0 - val ramAllocationRatio = 1.5 - return when (allocationPolicy) { - "mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(RamWeigher(multiplier = 1.0)) - ) - "mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(RamWeigher(multiplier = -1.0)) - ) - "core-mem" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) - "core-mem-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(CoreRamWeigher(multiplier = -1.0)) - ) - "active-servers" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(InstanceCountWeigher(multiplier = -1.0)) - ) - "active-servers-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(InstanceCountWeigher(multiplier = 1.0)) - ) - "provisioned-cores" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)) - ) - "provisioned-cores-inv" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)) - ) - "random" -> FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), - weighers = emptyList(), - subsetSize = Int.MAX_VALUE, - random = Random(seeder.nextLong()) - ) - "replay" -> ReplayScheduler(vmPlacements) - else -> throw IllegalArgumentException("Unknown policy $allocationPolicy") - } -} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt index 031ee269..b0181cbc 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Table.kt @@ -45,4 +45,11 @@ public interface Table { * Open a [TableReader] for this table. */ public fun newReader(): TableReader + + /** + * Open a [TableWriter] for this table. + * + * @throws UnsupportedOperationException if writing is not supported by the table. + */ + public fun newWriter(): TableWriter } diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt new file mode 100644 index 00000000..423ce86a --- /dev/null +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/TableWriter.kt @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace + +/** + * Base class for writing workload traces. + */ +public interface TableWriter : AutoCloseable { + /** + * Start a new row in the table. + */ + public fun startRow() + + /** + * Flush the current row to the table. + */ + public fun endRow() + + /** + * Resolve the index of the specified [column] for this writer. + * + * @param column The column to lookup. + * @return The zero-based index of the column or a negative value if the column is not present in this table. + */ + public fun resolve(column: TableColumn<*>): Int + + /** + * Determine whether the [TableReader] supports the specified [column]. + */ + public fun hasColumn(column: TableColumn<*>): Boolean = resolve(column) >= 0 + + /** + * Set [column] to [value]. + * + * @param index The zero-based index of the column to set the value for. + * @param value The value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun set(index: Int, value: Any) + + /** + * Set [column] to boolean [value]. + * + * @param index The zero-based index of the column to set the value for. + * @param value The boolean value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setBoolean(index: Int, value: Boolean) + + /** + * Set [column] to integer [value]. + * + * @param index The zero-based index of the column to set the value for. + * @param value The integer value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setInt(index: Int, value: Int) + + /** + * Set [column] to long [value]. + * + * @param index The zero-based index of the column to set the value for. + * @param value The long value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setLong(index: Int, value: Long) + + /** + * Set [column] to double [value]. + * + * @param index The zero-based index of the column to set the value for. + * @param value The double value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setDouble(index: Int, value: Double) + + /** + * Set [column] to [value]. + * + * @param column The column to set the value for. + * @param value The value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun set(column: TableColumn, value: T): Unit = set(resolve(column), value) + + /** + * Set [column] to boolean [value]. + * + * @param column The column to set the value for. + * @param value The boolean value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setBoolean(column: TableColumn, value: Boolean): Unit = setBoolean(resolve(column), value) + + /** + * Set [column] to integer [value]. + * + * @param column The column to set the value for. + * @param value The integer value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setInt(column: TableColumn, value: Int): Unit = setInt(resolve(column), value) + + /** + * Set [column] to long [value]. + * + * @param column The column to set the value for. + * @param value The long value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setLong(column: TableColumn, value: Long): Unit = setLong(resolve(column), value) + + /** + * Set [column] to double [value]. + * + * @param column The column to set the value for. + * @param value The double value to set the column to. + * @throws IllegalArgumentException if the column is not valid for this method. + */ + public fun setDouble(column: TableColumn, value: Double): Unit = setDouble(resolve(column), value) + + /** + * Flush any buffered content to the underlying target. + */ + public fun flush() + + /** + * Close the writer so that no more rows can be written. + */ + public override fun close() +} diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt index 6d0014cb..64e8f272 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/Trace.kt @@ -51,21 +51,45 @@ public interface Trace { * Open a [Trace] at the specified [path] in the given [format]. * * @param path The path to the trace. + * @param format The format of the trace to open. * @throws IllegalArgumentException if [format] is not supported. */ - public fun open(path: File, format: String): Trace { - return open(path.toPath(), format) - } + @JvmStatic + public fun open(path: File, format: String): Trace = open(path.toPath(), format) /** * Open a [Trace] at the specified [path] in the given [format]. * * @param path The [Path] to the trace. + * @param format The format of the trace to open. * @throws IllegalArgumentException if [format] is not supported. */ + @JvmStatic public fun open(path: Path, format: String): Trace { val provider = requireNotNull(TraceFormat.byName(format)) { "Unknown format $format" } return TraceImpl(provider, path) } + + /** + * Create a [Trace] at the specified [path] in the given [format]. + * + * @param path The [Path] to the trace. + * @param format The format of the trace to create. + */ + @JvmStatic + public fun create(path: File, format: String): Trace = create(path.toPath(), format) + + /** + * Create a [Trace] at the specified [path] in the given [format]. + * + * @param path The [Path] to the trace. + * @param format The format of the trace to create. + */ + @JvmStatic + public fun create(path: Path, format: String): Trace { + val provider = requireNotNull(TraceFormat.byName(format)) { "Unknown format $format" } + provider.create(path) + return TraceImpl(provider, path) + } } } diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt index fd0a0f04..24551edb 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/internal/TableImpl.kt @@ -25,6 +25,7 @@ package org.opendc.trace.internal import org.opendc.trace.Table import org.opendc.trace.TableColumn import org.opendc.trace.TableReader +import org.opendc.trace.TableWriter import java.util.* /** @@ -44,6 +45,8 @@ internal class TableImpl(val trace: TraceImpl, override val name: String) : Tabl override fun newReader(): TableReader = trace.format.newReader(trace.path, name) + override fun newWriter(): TableWriter = trace.format.newWriter(trace.path, name) + override fun toString(): String = "Table[name=$name]" override fun hashCode(): Int = Objects.hash(trace, name) diff --git a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt index e04dd948..f2e610db 100644 --- a/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt +++ b/opendc-trace/opendc-trace-api/src/main/kotlin/org/opendc/trace/spi/TraceFormat.kt @@ -23,6 +23,7 @@ package org.opendc.trace.spi import org.opendc.trace.TableReader +import org.opendc.trace.TableWriter import java.nio.file.Path import java.util.* @@ -35,6 +36,15 @@ public interface TraceFormat { */ public val name: String + /** + * Construct an empty trace at [path]. + * + * @param path The path where to create the empty trace. + * @throws IllegalArgumentException If [path] is invalid. + * @throws UnsupportedOperationException If the table does not support trace creation. + */ + public fun create(path: Path) + /** * Return the name of the tables available in the trace at the specified [path]. * @@ -63,6 +73,17 @@ public interface TraceFormat { */ public fun newReader(path: Path, table: String): TableReader + /** + * Open a [TableWriter] for the specified [table]. + * + * @param path The path to the trace to open. + * @param table The name of the table to open a [TableWriter] for. + * @throws IllegalArgumentException If [table] does not exist. + * @throws UnsupportedOperationException If the format does not support writing. + * @return A [TableWriter] instance for the table. + */ + public fun newWriter(path: Path, table: String): TableWriter + /** * A helper object for resolving providers. */ diff --git a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt index 77af0d81..253c7057 100644 --- a/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt +++ b/opendc-trace/opendc-trace-azure/src/main/kotlin/org/opendc/trace/azure/AzureTraceFormat.kt @@ -50,6 +50,10 @@ public class AzureTraceFormat : TraceFormat { .enable(CsvParser.Feature.ALLOW_COMMENTS) .enable(CsvParser.Feature.TRIM_SPACES) + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) override fun getDetails(path: Path, table: String): TableDetails { @@ -83,6 +87,10 @@ public class AzureTraceFormat : TraceFormat { } } + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } + /** * Construct a [TableReader] for reading over all VM CPU readings. */ diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt index 080b73de..20222c8a 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsExTraceFormat.kt @@ -42,6 +42,10 @@ public class BitbrainsExTraceFormat : TraceFormat { */ override val name: String = "bitbrains-ex" + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_RESOURCE_STATES) override fun getDetails(path: Path, table: String): TableDetails { @@ -74,6 +78,10 @@ public class BitbrainsExTraceFormat : TraceFormat { } } + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } + /** * Construct a [TableReader] for reading over all resource state partitions. */ diff --git a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt index 1573726f..3885c931 100644 --- a/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt +++ b/opendc-trace/opendc-trace-bitbrains/src/main/kotlin/org/opendc/trace/bitbrains/BitbrainsTraceFormat.kt @@ -50,6 +50,10 @@ public class BitbrainsTraceFormat : TraceFormat { .enable(CsvParser.Feature.ALLOW_COMMENTS) .enable(CsvParser.Feature.TRIM_SPACES) + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) override fun getDetails(path: Path, table: String): TableDetails { @@ -90,6 +94,10 @@ public class BitbrainsTraceFormat : TraceFormat { } } + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } + /** * Construct a [TableReader] for reading over all resource state partitions. */ diff --git a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt index 0f7b9d6e..d4287420 100644 --- a/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt +++ b/opendc-trace/opendc-trace-gwf/src/main/kotlin/org/opendc/trace/gwf/GwfTraceFormat.kt @@ -45,6 +45,10 @@ public class GwfTraceFormat : TraceFormat { .enable(CsvParser.Feature.ALLOW_COMMENTS) .enable(CsvParser.Feature.TRIM_SPACES) + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_TASKS) override fun getDetails(path: Path, table: String): TableDetails { @@ -71,4 +75,8 @@ public class GwfTraceFormat : TraceFormat { else -> throw IllegalArgumentException("Table $table not supported") } } + + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } } diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableWriter.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableWriter.kt new file mode 100644 index 00000000..15a8cb85 --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableWriter.kt @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.Schema +import org.apache.avro.generic.GenericRecord +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.hadoop.ParquetWriter +import org.opendc.trace.* +import java.time.Duration +import java.time.Instant + +/** + * A [TableWriter] implementation for the OpenDC virtual machine trace format. + */ +internal class OdcVmResourceStateTableWriter( + private val writer: ParquetWriter, + private val schema: Schema +) : TableWriter { + /** + * The current builder for the record that is being written. + */ + private var builder: GenericRecordBuilder? = null + + /** + * The fields belonging to the resource state schema. + */ + private val fields = schema.fields + + override fun startRow() { + builder = GenericRecordBuilder(schema) + } + + override fun endRow() { + val builder = checkNotNull(builder) { "No active row" } + this.builder = null + + val record = builder.build() + val id = record[COL_ID] as String + val timestamp = record[COL_TIMESTAMP] as Long + + check(lastId != id || timestamp >= lastTimestamp) { "Records need to be ordered by (id, timestamp)" } + + writer.write(builder.build()) + + lastId = id + lastTimestamp = timestamp + } + + override fun resolve(column: TableColumn<*>): Int { + val schema = schema + return when (column) { + RESOURCE_ID -> schema.getField("id").pos() + RESOURCE_STATE_TIMESTAMP -> (schema.getField("timestamp") ?: schema.getField("time")).pos() + RESOURCE_STATE_DURATION -> schema.getField("duration").pos() + RESOURCE_CPU_COUNT -> (schema.getField("cpu_count") ?: schema.getField("cores")).pos() + RESOURCE_STATE_CPU_USAGE -> (schema.getField("cpu_usage") ?: schema.getField("cpuUsage")).pos() + else -> -1 + } + } + + override fun set(index: Int, value: Any) { + val builder = checkNotNull(builder) { "No active row" } + + builder.set( + fields[index], + when (index) { + COL_TIMESTAMP -> (value as Instant).toEpochMilli() + COL_DURATION -> (value as Duration).toMillis() + else -> value + } + ) + } + + override fun setBoolean(index: Int, value: Boolean) = set(index, value) + + override fun setInt(index: Int, value: Int) = set(index, value) + + override fun setLong(index: Int, value: Long) = set(index, value) + + override fun setDouble(index: Int, value: Double) = set(index, value) + + override fun flush() { + // Not available + } + + override fun close() { + writer.close() + } + + /** + * Last column values that are used to check for correct partitioning. + */ + private var lastId: String? = null + private var lastTimestamp: Long = Long.MIN_VALUE + + /** + * Columns with special behavior. + */ + private val COL_ID = resolve(RESOURCE_ID) + private val COL_TIMESTAMP = resolve(RESOURCE_STATE_TIMESTAMP) + private val COL_DURATION = resolve(RESOURCE_STATE_DURATION) +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableWriter.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableWriter.kt new file mode 100644 index 00000000..9cc6ca7d --- /dev/null +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableWriter.kt @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.trace.opendc + +import org.apache.avro.Schema +import org.apache.avro.generic.GenericRecord +import org.apache.avro.generic.GenericRecordBuilder +import org.apache.parquet.hadoop.ParquetWriter +import org.opendc.trace.* +import java.time.Instant +import kotlin.math.roundToLong + +/** + * A [TableWriter] implementation for the OpenDC virtual machine trace format. + */ +internal class OdcVmResourceTableWriter( + private val writer: ParquetWriter, + private val schema: Schema +) : TableWriter { + /** + * The current builder for the record that is being written. + */ + private var builder: GenericRecordBuilder? = null + + /** + * The fields belonging to the resource schema. + */ + private val fields = schema.fields + + override fun startRow() { + builder = GenericRecordBuilder(schema) + } + + override fun endRow() { + val builder = checkNotNull(builder) { "No active row" } + this.builder = null + writer.write(builder.build()) + } + + override fun resolve(column: TableColumn<*>): Int { + val schema = schema + return when (column) { + RESOURCE_ID -> schema.getField("id").pos() + RESOURCE_START_TIME -> (schema.getField("start_time") ?: schema.getField("submissionTime")).pos() + RESOURCE_STOP_TIME -> (schema.getField("stop_time") ?: schema.getField("endTime")).pos() + RESOURCE_CPU_COUNT -> (schema.getField("cpu_count") ?: schema.getField("maxCores")).pos() + RESOURCE_MEM_CAPACITY -> (schema.getField("mem_capacity") ?: schema.getField("requiredMemory")).pos() + else -> -1 + } + } + + override fun set(index: Int, value: Any) { + val builder = checkNotNull(builder) { "No active row" } + builder.set( + fields[index], + when (index) { + COL_START_TIME, COL_STOP_TIME -> (value as Instant).toEpochMilli() + COL_MEM_CAPACITY -> (value as Double).roundToLong() + else -> value + } + ) + } + + override fun setBoolean(index: Int, value: Boolean) = set(index, value) + + override fun setInt(index: Int, value: Int) = set(index, value) + + override fun setLong(index: Int, value: Long) = set(index, value) + + override fun setDouble(index: Int, value: Double) = set(index, value) + + override fun flush() { + // Not available + } + + override fun close() { + writer.close() + } + + /** + * Columns with special behavior. + */ + private val COL_START_TIME = resolve(RESOURCE_START_TIME) + private val COL_STOP_TIME = resolve(RESOURCE_STOP_TIME) + private val COL_MEM_CAPACITY = resolve(RESOURCE_MEM_CAPACITY) +} diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt index 29818147..9b32f8fd 100644 --- a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt +++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt @@ -25,11 +25,16 @@ package org.opendc.trace.opendc import org.apache.avro.Schema import org.apache.avro.SchemaBuilder import org.apache.avro.generic.GenericRecord +import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.hadoop.ParquetFileWriter +import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.trace.* import org.opendc.trace.spi.TableDetails import org.opendc.trace.spi.TraceFormat +import org.opendc.trace.util.parquet.LocalOutputFile import org.opendc.trace.util.parquet.LocalParquetReader import org.opendc.trace.util.parquet.TIMESTAMP_SCHEMA +import java.nio.file.Files import java.nio.file.Path /** @@ -41,6 +46,18 @@ public class OdcVmTraceFormat : TraceFormat { */ override val name: String = "opendc-vm" + override fun create(path: Path) { + // Construct directory containing the trace files + Files.createDirectory(path) + + val tables = getTables(path) + + for (table in tables) { + val writer = newWriter(path, table) + writer.close() + } + } + override fun getTables(path: Path): List = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES) override fun getDetails(path: Path, table: String): TableDetails { @@ -82,6 +99,32 @@ public class OdcVmTraceFormat : TraceFormat { } } + override fun newWriter(path: Path, table: String): TableWriter { + return when (table) { + TABLE_RESOURCES -> { + val schema = RESOURCES_SCHEMA + val writer = AvroParquetWriter.builder(LocalOutputFile(path.resolve("meta.parquet"))) + .withSchema(schema) + .withCompressionCodec(CompressionCodecName.ZSTD) + .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) + .build() + OdcVmResourceTableWriter(writer, schema) + } + TABLE_RESOURCE_STATES -> { + val schema = RESOURCE_STATES_SCHEMA + val writer = AvroParquetWriter.builder(LocalOutputFile(path.resolve("trace.parquet"))) + .withSchema(schema) + .withCompressionCodec(CompressionCodecName.ZSTD) + .withDictionaryEncoding("id", true) + .withBloomFilterEnabled("id", true) + .withWriteMode(ParquetFileWriter.Mode.OVERWRITE) + .build() + OdcVmResourceStateTableWriter(writer, schema) + } + else -> throw IllegalArgumentException("Table $table not supported") + } + } + public companion object { /** * Schema for the resources table in the trace. diff --git a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt index 4cb7e49e..1fd076d5 100644 --- a/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt +++ b/opendc-trace/opendc-trace-swf/src/main/kotlin/org/opendc/trace/swf/SwfTraceFormat.kt @@ -36,6 +36,10 @@ import kotlin.io.path.bufferedReader public class SwfTraceFormat : TraceFormat { override val name: String = "swf" + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_TASKS) override fun getDetails(path: Path, table: String): TableDetails { @@ -65,4 +69,8 @@ public class SwfTraceFormat : TraceFormat { else -> throw IllegalArgumentException("Table $table not supported") } } + + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } } diff --git a/opendc-trace/opendc-trace-tools/build.gradle.kts b/opendc-trace/opendc-trace-tools/build.gradle.kts index 35190dba..14a0fc7c 100644 --- a/opendc-trace/opendc-trace-tools/build.gradle.kts +++ b/opendc-trace/opendc-trace-tools/build.gradle.kts @@ -29,19 +29,18 @@ plugins { } application { - mainClass.set("org.opendc.trace.tools.TraceConverterKt") + mainClass.set("org.opendc.trace.tools.TraceConverter") } dependencies { api(platform(projects.opendcPlatform)) - implementation(projects.opendcTrace.opendcTraceParquet) - implementation(projects.opendcTrace.opendcTraceOpendc) - implementation(projects.opendcTrace.opendcTraceAzure) - implementation(projects.opendcTrace.opendcTraceBitbrains) - + implementation(projects.opendcTrace.opendcTraceApi) implementation(libs.kotlin.logging) implementation(libs.clikt) + runtimeOnly(projects.opendcTrace.opendcTraceOpendc) + runtimeOnly(projects.opendcTrace.opendcTraceBitbrains) + runtimeOnly(projects.opendcTrace.opendcTraceAzure) runtimeOnly(libs.log4j.slf4j) } diff --git a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt index cd5d287f..6fad43be 100644 --- a/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt +++ b/opendc-trace/opendc-trace-tools/src/main/kotlin/org/opendc/trace/tools/TraceConverter.kt @@ -20,6 +20,7 @@ * SOFTWARE. */ +@file:JvmName("TraceConverter") package org.opendc.trace.tools import com.github.ajalt.clikt.core.CliktCommand @@ -29,25 +30,19 @@ import com.github.ajalt.clikt.parameters.groups.cooccurring import com.github.ajalt.clikt.parameters.options.* import com.github.ajalt.clikt.parameters.types.* import mu.KotlinLogging -import org.apache.avro.generic.GenericData -import org.apache.avro.generic.GenericRecordBuilder -import org.apache.parquet.avro.AvroParquetWriter -import org.apache.parquet.hadoop.ParquetWriter -import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.opendc.trace.* -import org.opendc.trace.opendc.OdcVmTraceFormat -import org.opendc.trace.util.parquet.LocalOutputFile import java.io.File +import java.time.Duration +import java.time.Instant import java.util.* import kotlin.math.abs import kotlin.math.max import kotlin.math.min -import kotlin.math.roundToLong /** * A script to convert a trace in text format into a Parquet trace. */ -public fun main(args: Array): Unit = TraceConverterCli().main(args) +fun main(args: Array): Unit = TraceConverterCli().main(args) /** * Represents the command for converting traces @@ -74,10 +69,15 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { /** * The input format of the trace. */ - private val format by option("-f", "--format", help = "input format of trace") - .choice("bitbrains-ex", "bitbrains", "azure") + private val inputFormat by option("-f", "--input-format", help = "format of output trace") .required() + /** + * The format of the output trace. + */ + private val outputFormat by option("--output-format", help = "format of output trace") + .default("opendc-vm") + /** * The sampling options. */ @@ -94,17 +94,14 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { traceParquet.delete() } - val trace = Trace.open(input, format = format) + val inputTrace = Trace.open(input, format = inputFormat) + val outputTrace = Trace.create(output, format = outputFormat) logger.info { "Building resources table" } - val metaWriter = AvroParquetWriter.builder(LocalOutputFile(metaParquet)) - .withSchema(OdcVmTraceFormat.RESOURCES_SCHEMA) - .withCompressionCodec(CompressionCodecName.ZSTD) - .enablePageWriteChecksum() - .build() + val metaWriter = outputTrace.getTable(TABLE_RESOURCES)!!.newWriter() - val selectedVms = metaWriter.use { convertResources(trace, it) } + val selectedVms = metaWriter.use { convertResources(inputTrace, it) } if (selectedVms.isEmpty()) { logger.warn { "No VMs selected" } @@ -114,23 +111,16 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { logger.info { "Wrote ${selectedVms.size} rows" } logger.info { "Building resource states table" } - val writer = AvroParquetWriter.builder(LocalOutputFile(traceParquet)) - .withSchema(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) - .withCompressionCodec(CompressionCodecName.ZSTD) - .withDictionaryEncoding("id", true) - .withBloomFilterEnabled("id", true) - .withBloomFilterNDV("id", selectedVms.size.toLong()) - .enableValidation() - .build() + val writer = outputTrace.getTable(TABLE_RESOURCE_STATES)!!.newWriter() - val statesCount = writer.use { convertResourceStates(trace, it, selectedVms) } + val statesCount = writer.use { convertResourceStates(inputTrace, it, selectedVms) } logger.info { "Wrote $statesCount rows" } } /** * Convert the resources table for the trace. */ - private fun convertResources(trace: Trace, writer: ParquetWriter): Set { + private fun convertResources(trace: Trace, writer: TableWriter): Set { val random = samplingOptions?.let { Random(it.seed) } val samplingFraction = samplingOptions?.fraction ?: 1.0 val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() @@ -168,18 +158,16 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { continue } - val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCES_SCHEMA) - - builder["id"] = id - builder["start_time"] = startTime - builder["stop_time"] = stopTime - builder["cpu_count"] = numCpus - builder["mem_capacity"] = max(memCapacity, memUsage).roundToLong() - logger.info { "Selecting VM $id" } - - writer.write(builder.build()) selectedVms.add(id) + + writer.startRow() + writer.set(RESOURCE_ID, id) + writer.set(RESOURCE_START_TIME, Instant.ofEpochMilli(startTime)) + writer.set(RESOURCE_STOP_TIME, Instant.ofEpochMilli(stopTime)) + writer.setInt(RESOURCE_CPU_COUNT, numCpus) + writer.setDouble(RESOURCE_MEM_CAPACITY, max(memCapacity, memUsage)) + writer.endRow() } return selectedVms @@ -188,7 +176,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { /** * Convert the resource states table for the trace. */ - private fun convertResourceStates(trace: Trace, writer: ParquetWriter, selectedVms: Set): Int { + private fun convertResourceStates(trace: Trace, writer: TableWriter, selectedVms: Set): Int { val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() var hasNextRow = reader.nextRow() @@ -231,15 +219,13 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") { cpuCount == reader.getInt(RESOURCE_CPU_COUNT) } while (shouldContinue) - val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA) - - builder["id"] = id - builder["timestamp"] = startTimestamp - builder["duration"] = duration - builder["cpu_count"] = cpuCount - builder["cpu_usage"] = cpuUsage - - writer.write(builder.build()) + writer.startRow() + writer.set(RESOURCE_ID, id) + writer.set(RESOURCE_STATE_TIMESTAMP, Instant.ofEpochMilli(startTimestamp)) + writer.set(RESOURCE_STATE_DURATION, Duration.ofMillis(duration)) + writer.setInt(RESOURCE_CPU_COUNT, cpuCount) + writer.setDouble(RESOURCE_STATE_CPU_USAGE, cpuUsage) + writer.endRow() count++ diff --git a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt index 825c3d6d..c75e3cbb 100644 --- a/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt +++ b/opendc-trace/opendc-trace-wfformat/src/main/kotlin/org/opendc/trace/wfformat/WfFormatTraceFormat.kt @@ -39,6 +39,10 @@ public class WfFormatTraceFormat : TraceFormat { override val name: String = "wfformat" + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_TASKS) override fun getDetails(path: Path, table: String): TableDetails { @@ -64,4 +68,8 @@ public class WfFormatTraceFormat : TraceFormat { else -> throw IllegalArgumentException("Table $table not supported") } } + + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } } diff --git a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt index 2f17694f..ef88d295 100644 --- a/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt +++ b/opendc-trace/opendc-trace-wtf/src/main/kotlin/org/opendc/trace/wtf/WtfTraceFormat.kt @@ -35,6 +35,10 @@ import java.nio.file.Path public class WtfTraceFormat : TraceFormat { override val name: String = "wtf" + override fun create(path: Path) { + throw UnsupportedOperationException("Writing not supported for this format") + } + override fun getTables(path: Path): List = listOf(TABLE_TASKS) override fun getDetails(path: Path, table: String): TableDetails { @@ -67,4 +71,8 @@ public class WtfTraceFormat : TraceFormat { else -> throw IllegalArgumentException("Table $table not supported") } } + + override fun newWriter(path: Path, table: String): TableWriter { + throw UnsupportedOperationException("Writing not supported for this format") + } } diff --git a/opendc-web/opendc-web-runner/build.gradle.kts b/opendc-web/opendc-web-runner/build.gradle.kts index bfbb1687..810f512f 100644 --- a/opendc-web/opendc-web-runner/build.gradle.kts +++ b/opendc-web/opendc-web-runner/build.gradle.kts @@ -36,10 +36,11 @@ application { dependencies { api(platform(projects.opendcPlatform)) implementation(projects.opendcCompute.opendcComputeSimulator) - implementation(projects.opendcExperiments.opendcExperimentsCapelin) + implementation(projects.opendcCompute.opendcComputeWorkload) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcTelemetry.opendcTelemetrySdk) implementation(projects.opendcTelemetry.opendcTelemetryCompute) + implementation(projects.opendcTrace.opendcTraceApi) implementation(libs.kotlin.logging) implementation(libs.clikt) @@ -50,6 +51,7 @@ dependencies { implementation(libs.jackson.datatype.jsr310) implementation(kotlin("reflect")) + runtimeOnly(projects.opendcTrace.opendcTraceOpendc) runtimeOnly(libs.log4j.slf4j) testImplementation(libs.ktor.client.mock) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 1b518fee..40a7ea62 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -33,8 +33,6 @@ import org.opendc.compute.workload.topology.HostSpec import org.opendc.compute.workload.topology.Topology import org.opendc.compute.workload.topology.apply import org.opendc.compute.workload.util.PerformanceInterferenceReader -import org.opendc.experiments.capelin.model.Workload -import org.opendc.experiments.capelin.util.createComputeScheduler import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit @@ -181,7 +179,7 @@ class RunnerCli : CliktCommand(name = "runner") { val operational = scenario.operationalPhenomena val computeScheduler = createComputeScheduler(operational.schedulerName, seeder) - val workload = Workload(workloadName, trace(workloadName).sampleByLoad(workloadFraction)) + val workload = trace(workloadName).sampleByLoad(workloadFraction) val failureModel = if (operational.failuresEnabled) @@ -203,7 +201,7 @@ class RunnerCli : CliktCommand(name = "runner") { // Instantiate the topology onto the simulator simulator.apply(topology) // Run workload trace - simulator.run(workload.source.resolve(workloadLoader, seeder), seeder.nextLong()) + simulator.run(workload.resolve(workloadLoader, seeder), seeder.nextLong()) } finally { simulator.close() metricReader.close() -- cgit v1.2.3 From 993c65d9c287d8db2db9ff1f95abb414803a502c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Sep 2021 12:18:28 +0200 Subject: build(ui): Bump semver-regex from 3.1.2 to 3.1.3. Bumps [semver-regex](https://github.com/sindresorhus/semver-regex) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/sindresorhus/semver-regex/releases) - [Commits](https://github.com/sindresorhus/semver-regex/commits) --- updated-dependencies: - dependency-name: semver-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- opendc-web/opendc-web-ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opendc-web/opendc-web-ui/yarn.lock b/opendc-web/opendc-web-ui/yarn.lock index 704213f0..1c898dd9 100644 --- a/opendc-web/opendc-web-ui/yarn.lock +++ b/opendc-web/opendc-web-ui/yarn.lock @@ -3826,9 +3826,9 @@ semver-compare@^1.0.0: integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= semver-regex@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" - integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.3.tgz#b2bcc6f97f63269f286994e297e229b6245d0dc3" + integrity sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ== "semver@2 || 3 || 4 || 5": version "5.7.1" -- cgit v1.2.3 From 5fa0cf915ecf643e94a0de972125e8f862308f80 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 22 Sep 2021 11:22:00 +0200 Subject: fix(telemetry): Ensure shutdown of exporter is called This change updates the CoroutineMetricReader to ensure that the exporter is shutdown when the metric reader fails or is shutdown. --- .../sdk/metrics/export/CoroutineMetricReader.kt | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt b/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt index 07f0ff7f..1de235e7 100644 --- a/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt +++ b/opendc-telemetry/opendc-telemetry-sdk/src/main/kotlin/org/opendc/telemetry/sdk/metrics/export/CoroutineMetricReader.kt @@ -22,7 +22,6 @@ package org.opendc.telemetry.sdk.metrics.export -import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* @@ -54,24 +53,25 @@ public class CoroutineMetricReader( private val job = scope.launch { val intervalMs = exportInterval.toMillis() - while (isActive) { - delay(intervalMs) + try { + while (isActive) { + delay(intervalMs) - val metrics = mutableListOf() - for (producer in producers) { - metrics.addAll(producer.collectAllMetrics()) - } + val metrics = producers.flatMap(MetricProducer::collectAllMetrics) - try { - val result = exporter.export(metrics) - result.whenComplete { - if (!result.isSuccess) { - logger.trace { "Exporter failed" } + try { + val result = exporter.export(metrics) + result.whenComplete { + if (!result.isSuccess) { + logger.warn { "Exporter failed" } + } } + } catch (cause: Throwable) { + logger.warn(cause) { "Exporter threw an Exception" } } - } catch (cause: Throwable) { - logger.warn(cause) { "Exporter threw an Exception" } } + } finally { + exporter.shutdown() } } -- cgit v1.2.3 From 30cd010f1f98262aa7f264bb3c3eb6028b8495c5 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 22 Sep 2021 12:43:01 +0200 Subject: refactor(telemetry): Do not require clock for ComputeMetricExporter This change drops the requirement for a clock parameter when constructing a ComputeMetricExporter, since it will now derive the timestamp from the recorded metrics. --- .../org/opendc/compute/simulator/SimHostTest.kt | 41 +++--- .../export/parquet/ParquetComputeMetricExporter.kt | 71 +++++++++++ .../export/parquet/ParquetExportMonitor.kt | 67 ---------- .../org/opendc/experiments/capelin/Portfolio.kt | 10 +- .../experiments/capelin/CapelinIntegrationTest.kt | 59 +++++---- .../telemetry/compute/ComputeMetricAggregator.kt | 52 ++++++-- .../telemetry/compute/ComputeMetricExporter.kt | 6 +- .../kotlin/org/opendc/telemetry/compute/Helpers.kt | 15 +-- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 13 +- .../org/opendc/web/runner/ScenarioManager.kt | 2 +- .../opendc/web/runner/WebComputeMetricExporter.kt | 137 +++++++++++++++++++++ .../org/opendc/web/runner/WebComputeMonitor.kt | 136 -------------------- 12 files changed, 316 insertions(+), 293 deletions(-) create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetComputeMetricExporter.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt create mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMetricExporter.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 9c879e5e..e75c31a0 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -43,7 +43,6 @@ import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.compute.ComputeMetricExporter -import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.compute.HOST_ID import org.opendc.telemetry.compute.table.HostData import org.opendc.telemetry.compute.table.ServerData @@ -138,16 +137,13 @@ internal class SimHostTest { // Setup metric reader val reader = CoroutineMetricReader( this, listOf(meterProvider as MetricProducer), - ComputeMetricExporter( - clock, - object : ComputeMonitor { - override fun record(data: HostData) { - activeTime += data.cpuActiveTime - idleTime += data.cpuIdleTime - stealTime += data.cpuStealTime - } + object : ComputeMetricExporter() { + override fun record(data: HostData) { + activeTime += data.cpuActiveTime + idleTime += data.cpuIdleTime + stealTime += data.cpuStealTime } - ), + }, exportInterval = Duration.ofSeconds(duration) ) @@ -237,22 +233,19 @@ internal class SimHostTest { // Setup metric reader val reader = CoroutineMetricReader( this, listOf(meterProvider as MetricProducer), - ComputeMetricExporter( - clock, - object : ComputeMonitor { - override fun record(data: HostData) { - activeTime += data.cpuActiveTime - idleTime += data.cpuIdleTime - uptime += data.uptime - downtime += data.downtime - } + object : ComputeMetricExporter() { + override fun record(data: HostData) { + activeTime += data.cpuActiveTime + idleTime += data.cpuIdleTime + uptime += data.uptime + downtime += data.downtime + } - override fun record(data: ServerData) { - guestUptime += data.uptime - guestDowntime += data.downtime - } + override fun record(data: ServerData) { + guestUptime += data.uptime + guestDowntime += data.downtime } - ), + }, exportInterval = Duration.ofSeconds(duration) ) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetComputeMetricExporter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetComputeMetricExporter.kt new file mode 100644 index 00000000..ad182d67 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetComputeMetricExporter.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.compute.workload.export.parquet + +import io.opentelemetry.sdk.common.CompletableResultCode +import org.opendc.telemetry.compute.ComputeMetricExporter +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServerData +import org.opendc.telemetry.compute.table.ServiceData +import java.io.File + +/** + * A [ComputeMonitor] that logs the events to a Parquet file. + */ +public class ParquetComputeMetricExporter(base: File, partition: String, bufferSize: Int) : ComputeMetricExporter() { + private val serverWriter = ParquetServerDataWriter( + File(base, "server/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + private val hostWriter = ParquetHostDataWriter( + File(base, "host/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + private val serviceWriter = ParquetServiceDataWriter( + File(base, "service/$partition/data.parquet").also { it.parentFile.mkdirs() }, + bufferSize + ) + + override fun record(data: ServerData) { + serverWriter.write(data) + } + + override fun record(data: HostData) { + hostWriter.write(data) + } + + override fun record(data: ServiceData) { + serviceWriter.write(data) + } + + override fun shutdown(): CompletableResultCode { + hostWriter.close() + serviceWriter.close() + serverWriter.close() + + return CompletableResultCode.ofSuccess() + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt deleted file mode 100644 index f41a2241..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetExportMonitor.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.compute.workload.export.parquet - -import org.opendc.telemetry.compute.ComputeMonitor -import org.opendc.telemetry.compute.table.HostData -import org.opendc.telemetry.compute.table.ServerData -import org.opendc.telemetry.compute.table.ServiceData -import java.io.File - -/** - * A [ComputeMonitor] that logs the events to a Parquet file. - */ -public class ParquetExportMonitor(base: File, partition: String, bufferSize: Int) : ComputeMonitor, AutoCloseable { - private val serverWriter = ParquetServerDataWriter( - File(base, "server/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - private val hostWriter = ParquetHostDataWriter( - File(base, "host/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - private val serviceWriter = ParquetServiceDataWriter( - File(base, "service/$partition/data.parquet").also { it.parentFile.mkdirs() }, - bufferSize - ) - - override fun record(data: ServerData) { - serverWriter.write(data) - } - - override fun record(data: HostData) { - hostWriter.write(data) - } - - override fun record(data: ServiceData) { - serviceWriter.write(data) - } - - override fun close() { - hostWriter.close() - serviceWriter.close() - serverWriter.close() - } -} diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 2201a6b4..21ff3ab0 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -27,7 +27,7 @@ import mu.KotlinLogging import org.opendc.compute.workload.ComputeWorkloadLoader import org.opendc.compute.workload.ComputeWorkloadRunner import org.opendc.compute.workload.createComputeScheduler -import org.opendc.compute.workload.export.parquet.ParquetExportMonitor +import org.opendc.compute.workload.export.parquet.ParquetComputeMetricExporter import org.opendc.compute.workload.grid5000 import org.opendc.compute.workload.topology.apply import org.opendc.compute.workload.util.PerformanceInterferenceReader @@ -39,7 +39,6 @@ import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.collectServiceMetrics import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import java.io.File @@ -120,12 +119,12 @@ abstract class Portfolio(name: String) : Experiment(name) { performanceInterferenceModel ) - val monitor = ParquetExportMonitor( + val exporter = ParquetComputeMetricExporter( File(config.getString("output-path")), "portfolio_id=$name/scenario_id=$id/run_id=$repeat", 4096 ) - val metricReader = CoroutineMetricReader(this, runner.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, runner.producers, exporter) val topology = clusterTopology(File(config.getString("env-path"), "${topology.name}.txt")) try { @@ -137,10 +136,9 @@ abstract class Portfolio(name: String) : Experiment(name) { } finally { runner.close() metricReader.close() - monitor.close() } - val monitorResults = collectServiceMetrics(clock.instant(), runner.producers[0]) + val monitorResults = collectServiceMetrics(runner.producers[0]) logger.debug { "Scheduler " + "Success=${monitorResults.attemptsSuccess} " + diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index ac2ea646..30cc1466 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -39,7 +39,6 @@ import org.opendc.experiments.capelin.topology.clusterTopology import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.compute.ComputeMetricExporter -import org.opendc.telemetry.compute.ComputeMonitor import org.opendc.telemetry.compute.collectServiceMetrics import org.opendc.telemetry.compute.table.HostData import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader @@ -54,7 +53,7 @@ class CapelinIntegrationTest { /** * The monitor used to keep track of the metrics. */ - private lateinit var monitor: TestExperimentReporter + private lateinit var exporter: TestComputeMetricExporter /** * The [FilterScheduler] to use for all experiments. @@ -71,7 +70,7 @@ class CapelinIntegrationTest { */ @BeforeEach fun setUp() { - monitor = TestExperimentReporter() + exporter = TestComputeMetricExporter() computeScheduler = FilterScheduler( filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), weighers = listOf(CoreRamWeigher(multiplier = 1.0)) @@ -91,7 +90,7 @@ class CapelinIntegrationTest { computeScheduler ) val topology = createTopology() - val metricReader = CoroutineMetricReader(this, runner.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, runner.producers, exporter) try { runner.apply(topology) @@ -101,7 +100,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.instant(), runner.producers[0]) + val serviceMetrics = collectServiceMetrics(runner.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -117,11 +116,11 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, - { assertEquals(223331032, monitor.idleTime) { "Incorrect idle time" } }, - { assertEquals(67006568, monitor.activeTime) { "Incorrect active time" } }, - { assertEquals(3159379, monitor.stealTime) { "Incorrect steal time" } }, - { assertEquals(0, monitor.lostTime) { "Incorrect lost time" } }, - { assertEquals(5.841120890240688E9, monitor.energyUsage, 0.01) { "Incorrect power draw" } }, + { assertEquals(223331032, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, + { assertEquals(67006568, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, + { assertEquals(3159379, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, + { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Incorrect lost time" } }, + { assertEquals(5.841120890240688E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, ) } @@ -139,7 +138,7 @@ class CapelinIntegrationTest { computeScheduler ) val topology = createTopology("single") - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, simulator.producers, exporter) try { simulator.apply(topology) @@ -149,7 +148,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -161,10 +160,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(10998110, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(9740290, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(0, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } } + { assertEquals(10998110, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9740290, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(0, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } @@ -188,7 +187,7 @@ class CapelinIntegrationTest { interferenceModel = performanceInterferenceModel ) val topology = createTopology("single") - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, simulator.producers, exporter) try { simulator.apply(topology) @@ -198,7 +197,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -210,10 +209,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(6013899, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(14724501, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(12530742, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(473394, monitor.lostTime) { "Lost time incorrect" } } + { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(473394, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } @@ -231,7 +230,7 @@ class CapelinIntegrationTest { ) val topology = createTopology("single") val workload = createTestWorkload(0.25, seed) - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor)) + val metricReader = CoroutineMetricReader(this, simulator.producers, exporter) try { simulator.apply(topology) @@ -241,7 +240,7 @@ class CapelinIntegrationTest { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(simulator.producers[0]) println( "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -253,11 +252,11 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(11134319, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(9604081, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(0, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, - { assertEquals(2559005056, monitor.uptime) { "Uptime incorrect" } } + { assertEquals(11134319, exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9604081, exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(0, exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(0, exporter.lostTime) { "Lost time incorrect" } }, + { assertEquals(2559005056, exporter.uptime) { "Uptime incorrect" } } ) } @@ -277,7 +276,7 @@ class CapelinIntegrationTest { return stream.use { clusterTopology(stream) } } - class TestExperimentReporter : ComputeMonitor { + class TestComputeMetricExporter : ComputeMetricExporter() { var idleTime = 0L var activeTime = 0L var stealTime = 0L diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt index e9449634..679d5944 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt @@ -55,6 +55,9 @@ public class ComputeMetricAggregator { // ComputeService "scheduler.hosts" -> { for (point in metric.longSumData.points) { + // Record the timestamp for the service + service.recordTimestamp(point) + when (point.attributes[STATE_KEY]) { "up" -> service.hostsUp = point.value.toInt() "down" -> service.hostsDown = point.value.toInt() @@ -163,12 +166,16 @@ public class ComputeMetricAggregator { val server = getServer(servers, point) if (server != null) { + server.recordTimestamp(point) + when (point.attributes[STATE_KEY]) { "up" -> server.uptime = point.value "down" -> server.downtime = point.value } server.host = agg.host } else { + agg.recordTimestamp(point) + when (point.attributes[STATE_KEY]) { "up" -> agg.uptime = point.value "down" -> agg.downtime = point.value @@ -197,15 +204,15 @@ public class ComputeMetricAggregator { /** * Collect the data via the [monitor]. */ - public fun collect(now: Instant, monitor: ComputeMonitor) { - monitor.record(_service.collect(now)) + public fun collect(monitor: ComputeMonitor) { + monitor.record(_service.collect()) for (host in _hosts.values) { - monitor.record(host.collect(now)) + monitor.record(host.collect()) } for (server in _servers.values) { - monitor.record(server.collect(now)) + monitor.record(server.collect()) } } @@ -237,6 +244,8 @@ public class ComputeMetricAggregator { * An aggregator for service metrics before they are reported. */ internal class ServiceAggregator { + private var timestamp = Long.MIN_VALUE + @JvmField var hostsUp = 0 @JvmField var hostsDown = 0 @@ -250,7 +259,10 @@ public class ComputeMetricAggregator { /** * Finish the aggregation for this cycle. */ - fun collect(now: Instant): ServiceData = toServiceData(now) + fun collect(): ServiceData { + val now = Instant.ofEpochMilli(timestamp) + return toServiceData(now) + } /** * Convert the aggregator state to an immutable [ServiceData]. @@ -258,6 +270,13 @@ public class ComputeMetricAggregator { private fun toServiceData(now: Instant): ServiceData { return ServiceData(now, hostsUp, hostsDown, serversPending, serversActive, attemptsSuccess, attemptsFailure, attemptsError) } + + /** + * Record the timestamp of a [point] for this aggregator. + */ + fun recordTimestamp(point: PointData) { + timestamp = point.epochNanos / 1_000_000L // ns to ms + } } /** @@ -275,6 +294,8 @@ public class ComputeMetricAggregator { resource.attributes[HOST_MEM_CAPACITY] ?: 0, ) + private var timestamp = Long.MIN_VALUE + @JvmField var guestsTerminated = 0 @JvmField var guestsRunning = 0 @JvmField var guestsError = 0 @@ -307,7 +328,8 @@ public class ComputeMetricAggregator { /** * Finish the aggregation for this cycle. */ - fun collect(now: Instant): HostData { + fun collect(): HostData { + val now = Instant.ofEpochMilli(timestamp) val data = toHostData(now) // Reset intermediate state for next aggregation @@ -360,6 +382,13 @@ public class ComputeMetricAggregator { if (bootTime != Long.MIN_VALUE) Instant.ofEpochMilli(bootTime) else null ) } + + /** + * Record the timestamp of a [point] for this aggregator. + */ + fun recordTimestamp(point: PointData) { + timestamp = point.epochNanos / 1_000_000L // ns to ms + } } /** @@ -385,6 +414,7 @@ public class ComputeMetricAggregator { */ var host: HostInfo? = null + private var timestamp = Long.MIN_VALUE @JvmField var uptime: Long = 0 private var previousUptime = 0L @JvmField var downtime: Long = 0 @@ -404,7 +434,8 @@ public class ComputeMetricAggregator { /** * Finish the aggregation for this cycle. */ - fun collect(now: Instant): ServerData { + fun collect(): ServerData { + val now = Instant.ofEpochMilli(timestamp) val data = toServerData(now) previousUptime = uptime @@ -439,6 +470,13 @@ public class ComputeMetricAggregator { cpuLostTime - previousCpuLostTime ) } + + /** + * Record the timestamp of a [point] for this aggregator. + */ + fun recordTimestamp(point: PointData) { + timestamp = point.epochNanos / 1_000_000L // ns to ms + } } private companion object { diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt index ea96f721..580cc6fb 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt @@ -25,12 +25,11 @@ package org.opendc.telemetry.compute import io.opentelemetry.sdk.common.CompletableResultCode import io.opentelemetry.sdk.metrics.data.* import io.opentelemetry.sdk.metrics.export.MetricExporter -import java.time.Clock /** * A [MetricExporter] that redirects data to a [ComputeMonitor] implementation. */ -public class ComputeMetricExporter(private val clock: Clock, private val monitor: ComputeMonitor) : MetricExporter { +public abstract class ComputeMetricExporter : MetricExporter, ComputeMonitor { /** * A [ComputeMetricAggregator] that actually performs the aggregation. */ @@ -39,7 +38,8 @@ public class ComputeMetricExporter(private val clock: Clock, private val monitor override fun export(metrics: Collection): CompletableResultCode { return try { agg.process(metrics) - agg.collect(clock.instant(), monitor) + agg.collect(this) + CompletableResultCode.ofSuccess() } catch (e: Throwable) { CompletableResultCode.ofFailure() diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt index 25d346fb..ce89061b 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/Helpers.kt @@ -22,22 +22,13 @@ package org.opendc.telemetry.compute -import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricProducer import org.opendc.telemetry.compute.table.ServiceData -import java.time.Instant /** * Collect the metrics of the compute service. */ -public fun collectServiceMetrics(timestamp: Instant, metricProducer: MetricProducer): ServiceData { - return extractServiceMetrics(timestamp, metricProducer.collectAllMetrics()) -} - -/** - * Extract a [ServiceData] object from the specified list of metric data. - */ -public fun extractServiceMetrics(timestamp: Instant, metrics: Collection): ServiceData { +public fun collectServiceMetrics(metricProducer: MetricProducer): ServiceData { lateinit var serviceData: ServiceData val agg = ComputeMetricAggregator() val monitor = object : ComputeMonitor { @@ -46,7 +37,7 @@ public fun extractServiceMetrics(timestamp: Instant, metrics: Collection { + private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, topology: Topology): List { val id = scenario.id logger.info { "Constructing performance interference model" } @@ -167,8 +166,8 @@ class RunnerCli : CliktCommand(name = "runner") { topology: Topology, workloadLoader: ComputeWorkloadLoader, interferenceModel: VmInterferenceModel? - ): WebComputeMonitor.Result { - val monitor = WebComputeMonitor() + ): WebComputeMetricExporter.Result { + val exporter = WebComputeMetricExporter() try { runBlockingSimulation { @@ -195,7 +194,7 @@ class RunnerCli : CliktCommand(name = "runner") { interferenceModel.takeIf { operational.performanceInterferenceEnabled } ) - val metricReader = CoroutineMetricReader(this, simulator.producers, ComputeMetricExporter(clock, monitor), exportInterval = Duration.ofHours(1)) + val metricReader = CoroutineMetricReader(this, simulator.producers, exporter, exportInterval = Duration.ofHours(1)) try { // Instantiate the topology onto the simulator @@ -207,7 +206,7 @@ class RunnerCli : CliktCommand(name = "runner") { metricReader.close() } - val serviceMetrics = collectServiceMetrics(clock.instant(), simulator.producers[0]) + val serviceMetrics = collectServiceMetrics(simulator.producers[0]) logger.debug { "Scheduler " + "Success=${serviceMetrics.attemptsSuccess} " + @@ -221,7 +220,7 @@ class RunnerCli : CliktCommand(name = "runner") { logger.warn(cause) { "Experiment failed" } } - return monitor.getResult() + return exporter.getResult() } private val POLL_INTERVAL = 30000L // ms = 30 s diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt index a0c281e8..1ee835a6 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt @@ -61,7 +61,7 @@ public class ScenarioManager(private val client: ApiClient) { /** * Persist the specified results. */ - public suspend fun finish(id: String, results: List) { + public suspend fun finish(id: String, results: List) { client.updateJob( id, SimulationState.FINISHED, mapOf( diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMetricExporter.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMetricExporter.kt new file mode 100644 index 00000000..7913660d --- /dev/null +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMetricExporter.kt @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.web.runner + +import org.opendc.telemetry.compute.ComputeMetricExporter +import org.opendc.telemetry.compute.ComputeMonitor +import org.opendc.telemetry.compute.table.HostData +import org.opendc.telemetry.compute.table.ServiceData +import kotlin.math.max +import kotlin.math.roundToLong + +/** + * A [ComputeMonitor] that tracks the aggregate metrics for each repeat. + */ +class WebComputeMetricExporter : ComputeMetricExporter() { + override fun record(data: HostData) { + val slices = data.downtime / SLICE_LENGTH + + hostAggregateMetrics = AggregateHostMetrics( + hostAggregateMetrics.totalActiveTime + data.cpuActiveTime, + hostAggregateMetrics.totalIdleTime + data.cpuIdleTime, + hostAggregateMetrics.totalStealTime + data.cpuStealTime, + hostAggregateMetrics.totalLostTime + data.cpuLostTime, + hostAggregateMetrics.totalPowerDraw + data.powerTotal, + hostAggregateMetrics.totalFailureSlices + slices, + hostAggregateMetrics.totalFailureVmSlices + data.guestsRunning * slices + ) + + hostMetrics.compute(data.host.id) { _, prev -> + HostMetrics( + data.cpuUsage + (prev?.cpuUsage ?: 0.0), + data.cpuDemand + (prev?.cpuDemand ?: 0.0), + data.guestsRunning + (prev?.instanceCount ?: 0), + 1 + (prev?.count ?: 0) + ) + } + } + + private var hostAggregateMetrics: AggregateHostMetrics = AggregateHostMetrics() + private val hostMetrics: MutableMap = mutableMapOf() + private val SLICE_LENGTH: Long = 5 * 60L + + data class AggregateHostMetrics( + val totalActiveTime: Long = 0L, + val totalIdleTime: Long = 0L, + val totalStealTime: Long = 0L, + val totalLostTime: Long = 0L, + val totalPowerDraw: Double = 0.0, + val totalFailureSlices: Double = 0.0, + val totalFailureVmSlices: Double = 0.0, + ) + + data class HostMetrics( + val cpuUsage: Double, + val cpuDemand: Double, + val instanceCount: Long, + val count: Long + ) + + private var serviceMetrics: AggregateServiceMetrics = AggregateServiceMetrics() + + override fun record(data: ServiceData) { + serviceMetrics = AggregateServiceMetrics( + max(data.attemptsSuccess, serviceMetrics.vmTotalCount), + max(data.serversPending, serviceMetrics.vmWaitingCount), + max(data.serversActive, serviceMetrics.vmActiveCount), + max(0, serviceMetrics.vmInactiveCount), + max(data.attemptsFailure, serviceMetrics.vmFailedCount), + ) + } + + data class AggregateServiceMetrics( + val vmTotalCount: Int = 0, + val vmWaitingCount: Int = 0, + val vmActiveCount: Int = 0, + val vmInactiveCount: Int = 0, + val vmFailedCount: Int = 0 + ) + + fun getResult(): Result { + return Result( + hostAggregateMetrics.totalActiveTime, + hostAggregateMetrics.totalIdleTime, + hostAggregateMetrics.totalStealTime, + hostAggregateMetrics.totalLostTime, + hostMetrics.map { it.value.cpuUsage / it.value.count }.average(), + hostMetrics.map { it.value.cpuDemand / it.value.count }.average(), + hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.average(), + hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.maxOrNull() ?: 0.0, + hostAggregateMetrics.totalPowerDraw, + hostAggregateMetrics.totalFailureSlices.roundToLong(), + hostAggregateMetrics.totalFailureVmSlices.roundToLong(), + serviceMetrics.vmTotalCount, + serviceMetrics.vmWaitingCount, + serviceMetrics.vmInactiveCount, + serviceMetrics.vmFailedCount, + ) + } + + data class Result( + val totalActiveTime: Long, + val totalIdleTime: Long, + val totalStealTime: Long, + val totalLostTime: Long, + val meanCpuUsage: Double, + val meanCpuDemand: Double, + val meanNumDeployedImages: Double, + val maxNumDeployedImages: Double, + val totalPowerDraw: Double, + val totalFailureSlices: Long, + val totalFailureVmSlices: Long, + val totalVmsSubmitted: Int, + val totalVmsQueued: Int, + val totalVmsFinished: Int, + val totalVmsFailed: Int + ) +} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt deleted file mode 100644 index bb412738..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/WebComputeMonitor.kt +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.runner - -import org.opendc.telemetry.compute.ComputeMonitor -import org.opendc.telemetry.compute.table.HostData -import org.opendc.telemetry.compute.table.ServiceData -import kotlin.math.max -import kotlin.math.roundToLong - -/** - * A [ComputeMonitor] that tracks the aggregate metrics for each repeat. - */ -class WebComputeMonitor : ComputeMonitor { - override fun record(data: HostData) { - val slices = data.downtime / SLICE_LENGTH - - hostAggregateMetrics = AggregateHostMetrics( - hostAggregateMetrics.totalActiveTime + data.cpuActiveTime, - hostAggregateMetrics.totalIdleTime + data.cpuIdleTime, - hostAggregateMetrics.totalStealTime + data.cpuStealTime, - hostAggregateMetrics.totalLostTime + data.cpuLostTime, - hostAggregateMetrics.totalPowerDraw + data.powerTotal, - hostAggregateMetrics.totalFailureSlices + slices, - hostAggregateMetrics.totalFailureVmSlices + data.guestsRunning * slices - ) - - hostMetrics.compute(data.host.id) { _, prev -> - HostMetrics( - data.cpuUsage + (prev?.cpuUsage ?: 0.0), - data.cpuDemand + (prev?.cpuDemand ?: 0.0), - data.guestsRunning + (prev?.instanceCount ?: 0), - 1 + (prev?.count ?: 0) - ) - } - } - - private var hostAggregateMetrics: AggregateHostMetrics = AggregateHostMetrics() - private val hostMetrics: MutableMap = mutableMapOf() - private val SLICE_LENGTH: Long = 5 * 60 - - data class AggregateHostMetrics( - val totalActiveTime: Long = 0L, - val totalIdleTime: Long = 0L, - val totalStealTime: Long = 0L, - val totalLostTime: Long = 0L, - val totalPowerDraw: Double = 0.0, - val totalFailureSlices: Double = 0.0, - val totalFailureVmSlices: Double = 0.0, - ) - - data class HostMetrics( - val cpuUsage: Double, - val cpuDemand: Double, - val instanceCount: Long, - val count: Long - ) - - private var serviceMetrics: AggregateServiceMetrics = AggregateServiceMetrics() - - override fun record(data: ServiceData) { - serviceMetrics = AggregateServiceMetrics( - max(data.attemptsSuccess, serviceMetrics.vmTotalCount), - max(data.serversPending, serviceMetrics.vmWaitingCount), - max(data.serversActive, serviceMetrics.vmActiveCount), - max(0, serviceMetrics.vmInactiveCount), - max(data.attemptsFailure, serviceMetrics.vmFailedCount), - ) - } - - data class AggregateServiceMetrics( - val vmTotalCount: Int = 0, - val vmWaitingCount: Int = 0, - val vmActiveCount: Int = 0, - val vmInactiveCount: Int = 0, - val vmFailedCount: Int = 0 - ) - - fun getResult(): Result { - return Result( - hostAggregateMetrics.totalActiveTime, - hostAggregateMetrics.totalIdleTime, - hostAggregateMetrics.totalStealTime, - hostAggregateMetrics.totalLostTime, - hostMetrics.map { it.value.cpuUsage / it.value.count }.average(), - hostMetrics.map { it.value.cpuDemand / it.value.count }.average(), - hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.average(), - hostMetrics.map { it.value.instanceCount.toDouble() / it.value.count }.maxOrNull() ?: 0.0, - hostAggregateMetrics.totalPowerDraw, - hostAggregateMetrics.totalFailureSlices.roundToLong(), - hostAggregateMetrics.totalFailureVmSlices.roundToLong(), - serviceMetrics.vmTotalCount, - serviceMetrics.vmWaitingCount, - serviceMetrics.vmInactiveCount, - serviceMetrics.vmFailedCount, - ) - } - - data class Result( - val totalActiveTime: Long, - val totalIdleTime: Long, - val totalStealTime: Long, - val totalLostTime: Long, - val meanCpuUsage: Double, - val meanCpuDemand: Double, - val meanNumDeployedImages: Double, - val maxNumDeployedImages: Double, - val totalPowerDraw: Double, - val totalFailureSlices: Long, - val totalFailureVmSlices: Long, - val totalVmsSubmitted: Int, - val totalVmsQueued: Int, - val totalVmsFinished: Int, - val totalVmsFailed: Int - ) -} -- cgit v1.2.3 From 3b928a66d992ec32ff28bfd4c11b0c7b2ac631ca Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 23 Sep 2021 14:44:46 +0200 Subject: fix(compute): Do not recover guests in non-error state --- .../main/kotlin/org/opendc/compute/simulator/SimHost.kt | 4 ++-- .../kotlin/org/opendc/compute/simulator/internal/Guest.kt | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index ff55c585..fdb3f1dc 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -262,7 +262,7 @@ public class SimHost( } override suspend fun delete(server: Server) { - val guest = guests.remove(server) ?: return + val guest = guests[server] ?: return guest.terminate() } @@ -296,7 +296,7 @@ public class SimHost( _bootTime = clock.millis() for (guest in guests.values) { - guest.start() + guest.recover() } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index 90562e2f..7f33154a 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -96,8 +96,8 @@ internal class Guest( } ServerState.RUNNING -> return ServerState.DELETED -> { - logger.warn { "User tried to start terminated server" } - throw IllegalArgumentException("Server is terminated") + logger.warn { "User tried to start deleted server" } + throw IllegalArgumentException("Server is deleted") } else -> assert(false) { "Invalid state transition" } } @@ -143,6 +143,17 @@ internal class Guest( doStop(ServerState.ERROR) } + /** + * Recover the guest if it is in an error state. + */ + suspend fun recover() { + if (state != ServerState.ERROR) { + return + } + + doStart() + } + /** * The [Job] representing the current active virtual machine instance or `null` if no virtual machine is active. */ -- cgit v1.2.3 From 6e0ea49e4d88a79db576dd281a8d4f17b819e5ae Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 23 Sep 2021 14:45:18 +0200 Subject: fix(compute): Write null values explicitly in Parquet exporter --- .../opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt | 4 +--- .../opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt index 37066a0d..98a0739e 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetHostDataWriter.kt @@ -54,9 +54,7 @@ public class ParquetHostDataWriter(path: File, bufferSize: Int) : builder["uptime"] = data.uptime builder["downtime"] = data.downtime val bootTime = data.bootTime - if (bootTime != null) { - builder["boot_time"] = bootTime.toEpochMilli() - } + builder["boot_time"] = bootTime?.toEpochMilli() builder["cpu_count"] = data.host.cpuCount builder["cpu_limit"] = data.cpuLimit diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt index bea23d32..0d11ec23 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/export/parquet/ParquetServerDataWriter.kt @@ -56,9 +56,7 @@ public class ParquetServerDataWriter(path: File, bufferSize: Int) : builder["uptime"] = data.uptime builder["downtime"] = data.downtime val bootTime = data.bootTime - if (bootTime != null) { - builder["boot_time"] = bootTime.toEpochMilli() - } + builder["boot_time"] = bootTime?.toEpochMilli() builder["scheduling_latency"] = data.schedulingLatency builder["cpu_count"] = data.server.cpuCount -- cgit v1.2.3 From 94d8ee69e52dcd375a662a08c198aa29670362fb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 23 Sep 2021 14:46:57 +0200 Subject: fix(telemetry): Report cause of compute exporter failure --- .../kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt | 2 +- .../kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt index 679d5944..738ec38b 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricAggregator.kt @@ -412,7 +412,7 @@ public class ComputeMetricAggregator { /** * The [HostInfo] of the host on which the server is hosted. */ - var host: HostInfo? = null + @JvmField var host: HostInfo? = null private var timestamp = Long.MIN_VALUE @JvmField var uptime: Long = 0 diff --git a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt index 580cc6fb..3ab6c7b2 100644 --- a/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt +++ b/opendc-telemetry/opendc-telemetry-compute/src/main/kotlin/org/opendc/telemetry/compute/ComputeMetricExporter.kt @@ -25,11 +25,17 @@ package org.opendc.telemetry.compute import io.opentelemetry.sdk.common.CompletableResultCode import io.opentelemetry.sdk.metrics.data.* import io.opentelemetry.sdk.metrics.export.MetricExporter +import mu.KotlinLogging /** * A [MetricExporter] that redirects data to a [ComputeMonitor] implementation. */ public abstract class ComputeMetricExporter : MetricExporter, ComputeMonitor { + /** + * The logging instance for this exporter. + */ + private val logger = KotlinLogging.logger {} + /** * A [ComputeMetricAggregator] that actually performs the aggregation. */ @@ -42,6 +48,7 @@ public abstract class ComputeMetricExporter : MetricExporter, ComputeMonitor { CompletableResultCode.ofSuccess() } catch (e: Throwable) { + logger.warn(e) { "Failed to export results" } CompletableResultCode.ofFailure() } } -- cgit v1.2.3 From 54bccf522e169d5cba6489291217f3307ae71094 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 28 Sep 2021 11:26:47 +0200 Subject: build: Increase Java requirement to version 11 This change updates the Gradle configuration to target Java 11 (instead of Java 8) as the lowest denominator when building OpenDC. Since the project has not yet been adopted by (many) other applications, we should not restrict the project to such an old Java version. --- .github/workflows/build.yml | 2 +- buildSrc/src/main/kotlin/Libs.kt | 2 +- docs/toolchain.md | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ff1ee85f..9bd42254 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - java: [8, 16] + java: [11, 16] include: - os: windows-latest java: 16 diff --git a/buildSrc/src/main/kotlin/Libs.kt b/buildSrc/src/main/kotlin/Libs.kt index 9567845a..f538b1ad 100644 --- a/buildSrc/src/main/kotlin/Libs.kt +++ b/buildSrc/src/main/kotlin/Libs.kt @@ -58,6 +58,6 @@ public class Libs(project: Project) { /** * The JVM version to target. */ - val jvmTarget = JavaVersion.VERSION_1_8 + val jvmTarget = JavaVersion.VERSION_11 } } diff --git a/docs/toolchain.md b/docs/toolchain.md index 4b029ebc..016c8201 100644 --- a/docs/toolchain.md +++ b/docs/toolchain.md @@ -12,13 +12,13 @@ Follow the steps below to get it all set up! ## Contents 1. [Installing Java](#1-installing-java) -1. [Building and Developing](#2-building-and-developing) - 1. [Setup with IntelliJ IDEA](#21-setup-with-intellij-idea) - 1. [Setup with Command Line](#22-setup-with-command-line) +2. [Building and Developing](#2-building-and-developing) +3. [Setup with IntelliJ IDEA](#21-setup-with-intellij-idea) +4. [Setup with Command Line](#22-setup-with-command-line) ## 1. Installing Java -Kotlin requires a Java installation of version 8 or higher. Make sure to install +OpenDC requires a Java installation of version 11 or higher. Make sure to install the [JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html), not only the JRE (the JDK also includes a JRE). -- cgit v1.2.3 From 83e6c19681a5cae4b80773f95a66b6753b0bcd7e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 10:28:46 +0200 Subject: build: Migrate from kotlinx-benchmark to jmh-gradle This change updates the project to use jmh-gradle for benchmarking as opposed to kotlinx-benchmark. Both plugins use JMH under the hood, but jmh-gradle offers more options for profiling and seems to be beter maintained. --- buildSrc/build.gradle.kts | 2 +- .../main/kotlin/benchmark-conventions.gradle.kts | 38 +++------------------- gradle/libs.versions.toml | 4 --- .../opendc-simulator-resources/build.gradle.kts | 1 - 4 files changed, 6 insertions(+), 39 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index a5e99bfa..4eb8ac31 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -34,7 +34,7 @@ dependencies { implementation(kotlin("gradle-plugin", version = "1.5.30")) implementation("org.jlleitschuh.gradle:ktlint-gradle:10.1.0") implementation("org.jetbrains.kotlin:kotlin-allopen:1.5.30") - implementation("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.3.1") + implementation("me.champeau.jmh:jmh-gradle-plugin:0.6.6") implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.5.0") implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:7.0.0") } diff --git a/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts b/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts index 590f51cf..65608e8f 100644 --- a/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/benchmark-conventions.gradle.kts @@ -20,49 +20,21 @@ * SOFTWARE. */ -import kotlinx.benchmark.gradle.* import org.jetbrains.kotlin.allopen.gradle.* plugins { - id("org.jetbrains.kotlinx.benchmark") `java-library` kotlin("plugin.allopen") -} - -sourceSets { - register("jmh") { - compileClasspath += sourceSets["main"].output - runtimeClasspath += sourceSets["main"].output - } -} - -configurations { - named("jmhImplementation") { - extendsFrom(configurations["implementation"]) - } + id("me.champeau.jmh") } configure { annotation("org.openjdk.jmh.annotations.State") } -benchmark { - targets { - register("jmh") { - this as JvmBenchmarkTarget - jmhVersion = "1.33" - } - } -} - -dependencies { - val libs = Libs(project) - implementation(libs["kotlinx.benchmark.runtime.jvm"]) -} +jmh { + jmhVersion.set("1.33") -// Workaround for https://github.com/Kotlin/kotlinx-benchmark/issues/39 -afterEvaluate { - tasks.named("jmhBenchmarkJar") { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - } + profilers.add("stack") + profilers.add("gc") } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 82da905c..03402b9a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,6 @@ jackson = "2.12.5" junit-jupiter = "5.7.2" junit-platform = "1.7.2" kotlin-logging = "2.0.11" -kotlinx-benchmark = "0.3.1" kotlinx-coroutines = "1.5.1" ktor = "1.6.3" log4j = "2.14.1" @@ -65,9 +64,6 @@ ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } ktor-client-jackson = { module = "io.ktor:ktor-client-jackson", version.ref = "ktor" } ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } -# Benchmark -kotlinx-benchmark-runtime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime-jvm", version.ref = "kotlinx-benchmark" } - # Other classgraph = { module = "io.github.classgraph:classgraph", version.ref = "classgraph" } hadoop-common = { module = "org.apache.hadoop:hadoop-common", version.ref = "hadoop" } diff --git a/opendc-simulator/opendc-simulator-resources/build.gradle.kts b/opendc-simulator/opendc-simulator-resources/build.gradle.kts index e4ffc3ff..68047d5c 100644 --- a/opendc-simulator/opendc-simulator-resources/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-resources/build.gradle.kts @@ -34,6 +34,5 @@ dependencies { api(libs.kotlinx.coroutines) implementation(projects.opendcUtils) - jmhImplementation(projects.opendcSimulator.opendcSimulatorCore) testImplementation(projects.opendcSimulator.opendcSimulatorCore) } -- cgit v1.2.3 From 0ffd93933228e87a205c9839d1bf04cd0e178e8c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 12:14:42 +0200 Subject: test(simulator): Use longer traces for benchmarks This change updates the JMH benchmarks to use longer traces in order to measure the overhead of running the flow simulation as opposed to setting up the benchmark. --- .../org/opendc/simulator/compute/SimMachineBenchmarks.kt | 16 +++++----------- .../opendc/simulator/resources/SimResourceBenchmarks.kt | 14 ++++---------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index 30797089..88ad7286 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -38,6 +38,7 @@ import org.opendc.simulator.core.SimulationCoroutineScope import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter import org.openjdk.jmh.annotations.* +import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.TimeUnit @State(Scope.Thread) @@ -63,22 +64,15 @@ class SimMachineBenchmarks { ) } - @State(Scope.Benchmark) + @State(Scope.Thread) class Workload { lateinit var trace: Sequence @Setup fun setUp() { - trace = sequenceOf( - SimTraceWorkload.Fragment(0, 1000, 28.0, 1), - SimTraceWorkload.Fragment(1000, 1000, 3500.0, 1), - SimTraceWorkload.Fragment(2000, 1000, 0.0, 1), - SimTraceWorkload.Fragment(3000, 1000, 183.0, 1), - SimTraceWorkload.Fragment(4000, 1000, 400.0, 1), - SimTraceWorkload.Fragment(5000, 1000, 100.0, 1), - SimTraceWorkload.Fragment(6000, 1000, 3000.0, 1), - SimTraceWorkload.Fragment(7000, 1000, 4500.0, 1), - ) + val random = ThreadLocalRandom.current() + val entries = List(10000) { SimTraceWorkload.Fragment(it * 1000L, 1000, random.nextDouble(0.0, 4500.0), 1) } + trace = entries.asSequence() } } diff --git a/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt b/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt index b45b2a2f..fbc3f319 100644 --- a/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt @@ -28,6 +28,7 @@ import org.opendc.simulator.core.SimulationCoroutineScope import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimTraceConsumer import org.openjdk.jmh.annotations.* +import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.TimeUnit @State(Scope.Thread) @@ -51,16 +52,9 @@ class SimResourceBenchmarks { @Setup fun setUp() { - trace = sequenceOf( - SimTraceConsumer.Fragment(1000, 28.0), - SimTraceConsumer.Fragment(1000, 3500.0), - SimTraceConsumer.Fragment(1000, 0.0), - SimTraceConsumer.Fragment(1000, 183.0), - SimTraceConsumer.Fragment(1000, 400.0), - SimTraceConsumer.Fragment(1000, 100.0), - SimTraceConsumer.Fragment(1000, 3000.0), - SimTraceConsumer.Fragment(1000, 4500.0), - ) + val random = ThreadLocalRandom.current() + val entries = List(10000) { SimTraceConsumer.Fragment(1000, random.nextDouble(0.0, 4500.0)) } + trace = entries.asSequence() } } -- cgit v1.2.3 From a4a611c45dfd5f9e379434f1dc459128cb437338 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 23 Sep 2021 14:45:56 +0200 Subject: perf(simulator): Use direct field access for perf-sensitive code This change updates the SimResourceDistributorMaxMin implementation to use direct field accesses in the perf-sensitive code. --- .../resources/SimResourceDistributorMaxMin.kt | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index 6c1e134b..63cfbdac 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -162,6 +162,8 @@ public class SimResourceDistributorMaxMin( return SimResourceCommand.Idle() } + val now = interpreter.clock.millis() + val capacity = ctx.capacity var duration: Double = Double.MAX_VALUE var deadline: Long = Long.MAX_VALUE @@ -171,7 +173,7 @@ public class SimResourceDistributorMaxMin( // Pull in the work of the outputs val outputIterator = activeOutputs.listIterator() for (output in outputIterator) { - output.pull() + output.pull(now) // Remove outputs that have finished if (!output.isActive) { @@ -206,7 +208,7 @@ public class SimResourceDistributorMaxMin( duration = min(duration, output.work / grantedSpeed) } - val targetDuration = min(duration, (deadline - interpreter.clock.millis()) / 1000.0) + val targetDuration = min(duration, (deadline - now) / 1000.0) var totalRequestedWork = 0.0 var totalAllocatedWork = 0.0 for (output in activeOutputs) { @@ -219,7 +221,7 @@ public class SimResourceDistributorMaxMin( } } - assert(deadline >= interpreter.clock.millis()) { "Deadline already passed" } + assert(deadline >= now) { "Deadline already passed" } this.totalRequestedSpeed = totalRequestedSpeed this.totalAllocatedWork = totalAllocatedWork @@ -254,27 +256,27 @@ public class SimResourceDistributorMaxMin( /** * The current requested work. */ - var work: Double = 0.0 + @JvmField var work: Double = 0.0 /** * The requested limit. */ - var limit: Double = 0.0 + @JvmField var limit: Double = 0.0 /** * The current deadline. */ - var deadline: Long = Long.MAX_VALUE + @JvmField var deadline: Long = Long.MAX_VALUE /** * The processing speed that is allowed by the model constraints. */ - var allowedSpeed: Double = 0.0 + @JvmField var allowedSpeed: Double = 0.0 /** * The actual processing speed. */ - var actualSpeed: Double = 0.0 + @JvmField var actualSpeed: Double = 0.0 /** * The timestamp at which we received the last command. @@ -363,9 +365,9 @@ public class SimResourceDistributorMaxMin( /** * Pull the next command if necessary. */ - fun pull() { + fun pull(now: Long) { val ctx = ctx - if (ctx != null && lastCommandTimestamp < ctx.clock.millis()) { + if (ctx != null && lastCommandTimestamp < now) { ctx.flush() } } -- cgit v1.2.3 From d575bed5418be222e1d3ad39af862e2390596d61 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 26 Sep 2021 13:11:10 +0200 Subject: refactor(simulator): Combine work and deadline to duration This change removes the work and deadline properties from the SimResourceCommand.Consume class and introduces a new property duration. This property is now used in conjunction with the limit to compute the amount of work processed by a resource provider. Previously, we used both work and deadline to compute the duration and the amount of remaining work at the end of a consumption. However, with this change, we ensure that a resource consumption always runs at the same speed once establishing, drastically simplifying the computation for the amount of work processed during the consumption. --- .../experiments/capelin/CapelinIntegrationTest.kt | 6 +- .../opendc/experiments/tf20/core/SimTFDevice.kt | 15 ++- .../org/opendc/simulator/compute/device/SimPsu.kt | 6 +- .../simulator/compute/workload/SimTraceWorkload.kt | 12 +- .../compute/kernel/SimSpaceSharedHypervisorTest.kt | 2 + .../org/opendc/simulator/network/SimNetworkSink.kt | 2 +- .../kotlin/org/opendc/simulator/power/SimPdu.kt | 14 +-- .../kotlin/org/opendc/simulator/power/SimUps.kt | 14 +-- .../resources/SimAbstractResourceAggregator.kt | 40 +++---- .../resources/SimAbstractResourceProvider.kt | 22 +++- .../resources/SimResourceAggregatorMaxMin.kt | 15 +-- .../simulator/resources/SimResourceCommand.kt | 16 +-- .../simulator/resources/SimResourceConsumer.kt | 4 +- .../simulator/resources/SimResourceContext.kt | 5 - .../resources/SimResourceDistributorMaxMin.kt | 129 +++++++-------------- .../resources/SimResourceProviderLogic.kt | 48 +++----- .../simulator/resources/SimResourceSource.kt | 31 ++--- .../simulator/resources/SimResourceTransformer.kt | 28 ++--- .../resources/consumer/SimSpeedConsumerAdapter.kt | 4 +- .../resources/consumer/SimTraceConsumer.kt | 13 +-- .../resources/consumer/SimWorkConsumer.kt | 22 ++-- .../resources/impl/SimResourceContextImpl.kt | 83 +++---------- .../resources/SimResourceAggregatorMaxMinTest.kt | 19 ++- .../simulator/resources/SimResourceCommandTest.kt | 31 +---- .../simulator/resources/SimResourceContextTest.kt | 50 +++----- .../simulator/resources/SimResourceSourceTest.kt | 54 +++------ .../resources/SimResourceSwitchExclusiveTest.kt | 11 +- .../resources/SimResourceSwitchMaxMinTest.kt | 4 +- .../resources/SimResourceTransformerTest.kt | 19 ++- .../simulator/resources/SimWorkConsumerTest.kt | 2 - .../opendc/workflow/service/WorkflowServiceTest.kt | 2 +- 31 files changed, 243 insertions(+), 480 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 30cc1466..ffc50ad8 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -118,7 +118,7 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, { assertEquals(223331032, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, { assertEquals(67006568, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, - { assertEquals(3159379, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, + { assertEquals(3088047, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Incorrect lost time" } }, { assertEquals(5.841120890240688E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, ) @@ -211,8 +211,8 @@ class CapelinIntegrationTest { assertAll( { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, - { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(473394, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(12027839, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(477664, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index 0873aac9..bfc5fc6f 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -41,6 +41,7 @@ import java.util.* import kotlin.coroutines.Continuation import kotlin.coroutines.CoroutineContext import kotlin.coroutines.resume +import kotlin.math.roundToLong /** * A [TFDevice] implementation using simulated components. @@ -127,13 +128,16 @@ public class SimTFDevice( } } - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + val consumedWork = ctx.speed * delta / 1000.0 + val activeWork = activeWork if (activeWork != null) { - if (activeWork.consume(activeWork.flops - ctx.remainingWork)) { + if (activeWork.consume(consumedWork)) { this.activeWork = null } else { - return SimResourceCommand.Consume(activeWork.flops, ctx.capacity) + val duration = (activeWork.flops / ctx.capacity * 1000).roundToLong() + return SimResourceCommand.Consume(ctx.capacity, duration) } } @@ -141,9 +145,10 @@ public class SimTFDevice( val head = queue.poll() return if (head != null) { this.activeWork = head - SimResourceCommand.Consume(head.flops, ctx.capacity) + val duration = (head.flops / ctx.capacity * 1000).roundToLong() + SimResourceCommand.Consume(ctx.capacity, duration) } else { - SimResourceCommand.Idle() + SimResourceCommand.Consume(0.0) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index 0a7dc40f..34ac4418 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -83,13 +83,13 @@ public class SimPsu( } override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { val powerDraw = computePowerDraw(_driver?.computePower() ?: 0.0) return if (powerDraw > 0.0) - SimResourceCommand.Consume(Double.POSITIVE_INFINITY, powerDraw, Long.MAX_VALUE) + SimResourceCommand.Consume(powerDraw, Long.MAX_VALUE) else - SimResourceCommand.Idle() + SimResourceCommand.Consume(0.0) } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index 5a4c4f44..527619bd 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -80,14 +80,13 @@ public class SimTraceWorkload(public val trace: Sequence, private val } private inner class Consumer(val cpu: ProcessingUnit) : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand { - val now = ctx.clock.millis() + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { val fragment = pullFragment(now) ?: return SimResourceCommand.Exit val timestamp = fragment.timestamp + offset // Fragment is in the future if (timestamp > now) { - return SimResourceCommand.Idle(timestamp) + return SimResourceCommand.Consume(0.0, timestamp - now) } val cores = min(cpu.node.coreCount, fragment.cores) @@ -97,12 +96,11 @@ public class SimTraceWorkload(public val trace: Sequence, private val 0.0 val deadline = timestamp + fragment.duration val duration = deadline - now - val work = duration * usage / 1000 - return if (cpu.id < cores && work > 0.0) - SimResourceCommand.Consume(work, usage, deadline) + return if (cpu.id < cores && usage > 0.0) + SimResourceCommand.Consume(usage, duration) else - SimResourceCommand.Idle(deadline) + SimResourceCommand.Consume(0.0, duration) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index 3d3feb2a..55d6d7c4 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -155,6 +155,8 @@ internal class SimSpaceSharedHypervisorTest { vm.run(SimRuntimeWorkload(duration)) vm.close() + yield() + val vm2 = hypervisor.createMachine(machineModel) vm2.run(SimRuntimeWorkload(duration)) vm2.close() diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt index 5efdbed9..f2dd8455 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt @@ -32,7 +32,7 @@ public class SimNetworkSink( public val capacity: Double ) : SimNetworkPort() { override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand = SimResourceCommand.Idle() + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand = SimResourceCommand.Consume(0.0) override fun toString(): String = "SimNetworkSink.Consumer" } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index 3ce85d02..e8839496 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -47,21 +47,13 @@ public class SimPdu( public fun newOutlet(): Outlet = Outlet(distributor.newOutput()) override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer by distributor { - override fun onNext(ctx: SimResourceContext): SimResourceCommand { - return when (val cmd = distributor.onNext(ctx)) { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + return when (val cmd = distributor.onNext(ctx, now, delta)) { is SimResourceCommand.Consume -> { - val duration = cmd.work / cmd.limit val loss = computePowerLoss(cmd.limit) val newLimit = cmd.limit + loss - SimResourceCommand.Consume(duration * newLimit, newLimit, cmd.deadline) - } - is SimResourceCommand.Idle -> { - val loss = computePowerLoss(0.0) - if (loss > 0.0) - SimResourceCommand.Consume(Double.POSITIVE_INFINITY, loss, cmd.deadline) - else - cmd + SimResourceCommand.Consume(newLimit, cmd.duration) } else -> cmd } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index f9431d21..4c2beb68 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -55,21 +55,13 @@ public class SimUps( override fun onConnect(inlet: SimPowerInlet) { val consumer = inlet.createConsumer() aggregator.startConsumer(object : SimResourceConsumer by consumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand { - return when (val cmd = consumer.onNext(ctx)) { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + return when (val cmd = consumer.onNext(ctx, now, delta)) { is SimResourceCommand.Consume -> { - val duration = cmd.work / cmd.limit val loss = computePowerLoss(cmd.limit) val newLimit = cmd.limit + loss - SimResourceCommand.Consume(duration * newLimit, newLimit, cmd.deadline) - } - is SimResourceCommand.Idle -> { - val loss = computePowerLoss(0.0) - if (loss > 0.0) - SimResourceCommand.Consume(Double.POSITIVE_INFINITY, loss, cmd.deadline) - else - cmd + SimResourceCommand.Consume(newLimit, cmd.duration) } else -> cmd } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt index 00648876..da5c3257 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt @@ -32,12 +32,7 @@ public abstract class SimAbstractResourceAggregator( /** * This method is invoked when the resource consumer consumes resources. */ - protected abstract fun doConsume(work: Double, limit: Double, deadline: Long) - - /** - * This method is invoked when the resource consumer enters an idle state. - */ - protected abstract fun doIdle(deadline: Long) + protected abstract fun doConsume(limit: Double, duration: Long) /** * This method is invoked when the resource consumer finishes processing. @@ -98,26 +93,23 @@ public abstract class SimAbstractResourceAggregator( private val _output = object : SimAbstractResourceProvider(interpreter, parent, initialCapacity = 0.0) { override fun createLogic(): SimResourceProviderLogic { return object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long { - doIdle(deadline) - return Long.MAX_VALUE - } - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long { - doConsume(work, limit, deadline) - return Long.MAX_VALUE + override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { + doConsume(limit, duration) + return super.onConsume(ctx, now, limit, duration) } override fun onFinish(ctx: SimResourceControllableContext) { doFinish() } - override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { - updateCounters(ctx, work, willOvercommit) - } - - override fun getConsumedWork(ctx: SimResourceControllableContext, work: Double, speed: Double, duration: Long): Double { - return work - _inputConsumers.sumOf { it.remainingWork } + override fun onUpdate( + ctx: SimResourceControllableContext, + delta: Long, + limit: Double, + willOvercommit: Boolean + ) { + updateCounters(ctx, delta, limit, willOvercommit) } } } @@ -156,12 +148,6 @@ public abstract class SimAbstractResourceAggregator( get() = _ctx!! private var _ctx: SimResourceContext? = null - /** - * The remaining work of the consumer. - */ - val remainingWork: Double - get() = _ctx?.remainingWork ?: 0.0 - /** * The resource command to run next. */ @@ -179,7 +165,7 @@ public abstract class SimAbstractResourceAggregator( } /* SimResourceConsumer */ - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { var next = command return if (next != null) { @@ -190,7 +176,7 @@ public abstract class SimAbstractResourceAggregator( next = command this.command = null - next ?: SimResourceCommand.Idle() + next ?: SimResourceCommand.Consume(0.0) } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt index 4e8e803a..548bc228 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt @@ -87,21 +87,35 @@ public abstract class SimAbstractResourceProvider( /** * Update the counters of the resource provider. */ - protected fun updateCounters(ctx: SimResourceContext, work: Double, willOvercommit: Boolean) { - if (work <= 0.0) { + protected fun updateCounters(ctx: SimResourceContext, delta: Long, limit: Double, willOvercommit: Boolean) { + if (delta <= 0.0) { return } val counters = _counters - val remainingWork = ctx.remainingWork + val deltaS = delta / 1000.0 + val work = limit * deltaS + val actualWork = ctx.speed * deltaS + val remainingWork = work - actualWork + counters.demand += work - counters.actual += work - remainingWork + counters.actual += actualWork if (willOvercommit && remainingWork > 0.0) { counters.overcommit += remainingWork } } + /** + * Update the counters of the resource provider. + */ + protected fun updateCounters(demand: Double, actual: Double, overcommit: Double) { + val counters = _counters + counters.demand += demand + counters.actual += actual + counters.overcommit += overcommit + } + final override fun startConsumer(consumer: SimResourceConsumer) { check(ctx == null) { "Resource is in invalid state" } val ctx = interpreter.newContext(consumer, createLogic(), parent) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt index 991cda7a..537be1b5 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt @@ -31,7 +31,7 @@ public class SimResourceAggregatorMaxMin( ) : SimAbstractResourceAggregator(interpreter, parent) { private val consumers = mutableListOf() - override fun doConsume(work: Double, limit: Double, deadline: Long) { + override fun doConsume(limit: Double, duration: Long) { // Sort all consumers by their capacity consumers.sortWith(compareBy { it.ctx.capacity }) @@ -40,22 +40,15 @@ public class SimResourceAggregatorMaxMin( val inputCapacity = input.ctx.capacity val fraction = inputCapacity / capacity val grantedSpeed = limit * fraction - val grantedWork = fraction * work - val command = if (grantedWork > 0.0 && grantedSpeed > 0.0) - SimResourceCommand.Consume(grantedWork, grantedSpeed, deadline) + val command = if (grantedSpeed > 0.0) + SimResourceCommand.Consume(grantedSpeed, duration) else - SimResourceCommand.Idle() + SimResourceCommand.Consume(0.0, duration) input.push(command) } } - override fun doIdle(deadline: Long) { - for (input in consumers) { - input.push(SimResourceCommand.Idle(deadline)) - } - } - override fun doFinish() { val iterator = consumers.iterator() for (input in iterator) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt index f7f3fa4d..4a980071 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt @@ -27,24 +27,18 @@ package org.opendc.simulator.resources */ public sealed class SimResourceCommand { /** - * A request to the resource to perform the specified amount of work before the given [deadline]. + * A request to the resource to perform work for the specified [duration]. * - * @param work The amount of work to process. * @param limit The maximum amount of work to be processed per second. - * @param deadline The instant at which the work needs to be fulfilled. + * @param duration The duration of the resource consumption in milliseconds. */ - public data class Consume(val work: Double, val limit: Double, val deadline: Long = Long.MAX_VALUE) : SimResourceCommand() { + public data class Consume(val limit: Double, val duration: Long = Long.MAX_VALUE) : SimResourceCommand() { init { - require(work > 0) { "Amount of work must be positive" } - require(limit > 0) { "Limit must be positive" } + require(limit >= 0.0) { "Negative limit is not allowed" } + require(duration >= 0) { "Duration must be positive" } } } - /** - * An indication to the resource that the consumer will idle until the specified [deadline] or if it is interrupted. - */ - public data class Idle(val deadline: Long = Long.MAX_VALUE) : SimResourceCommand() - /** * An indication to the resource that the consumer has finished. */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt index 4d937514..4d1d2c32 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt @@ -34,9 +34,11 @@ public interface SimResourceConsumer { * the resource finished processing, reached its deadline or was interrupted. * * @param ctx The execution context in which the consumer runs. + * @param now The virtual timestamp in milliseconds at which the update is occurring. + * @param delta The virtual duration between this call and the last call in milliseconds. * @return The next command that the resource should execute. */ - public fun onNext(ctx: SimResourceContext): SimResourceCommand + public fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand /** * This method is invoked when an event has occurred. diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt index 0d9a6106..f28b43d0 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt @@ -49,11 +49,6 @@ public interface SimResourceContext { */ public val demand: Double - /** - * The amount of work still remaining at this instant. - */ - public val remainingWork: Double - /** * Ask the resource provider to interrupt its resource. */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index 63cfbdac..d23c7dbb 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -97,8 +97,8 @@ public class SimResourceDistributorMaxMin( } /* SimResourceConsumer */ - override fun onNext(ctx: SimResourceContext): SimResourceCommand { - return doNext(ctx) + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + return doNext(ctx, now) } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { @@ -134,39 +134,17 @@ public class SimResourceDistributorMaxMin( public val interference: Double } - /** - * Update the counters of the distributor. - */ - private fun updateCounters(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { - if (work <= 0.0) { - return - } - - val counters = _counters - val remainingWork = ctx.remainingWork - - counters.demand += work - counters.actual += work - remainingWork - - if (willOvercommit && remainingWork > 0.0) { - counters.overcommit += remainingWork - } - } - /** * Schedule the work of the outputs. */ - private fun doNext(ctx: SimResourceContext): SimResourceCommand { + private fun doNext(ctx: SimResourceContext, now: Long): SimResourceCommand { // If there is no work yet, mark the input as idle. if (activeOutputs.isEmpty()) { - return SimResourceCommand.Idle() + return SimResourceCommand.Consume(0.0) } - val now = interpreter.clock.millis() - val capacity = ctx.capacity - var duration: Double = Double.MAX_VALUE - var deadline: Long = Long.MAX_VALUE + var duration: Long = Long.MAX_VALUE var availableSpeed = capacity var totalRequestedSpeed = 0.0 @@ -191,10 +169,10 @@ public class SimResourceDistributorMaxMin( val availableShare = availableSpeed / remaining-- val grantedSpeed = min(output.allowedSpeed, availableShare) - deadline = min(deadline, output.deadline) + duration = min(duration, output.duration) // Ignore idle computation - if (grantedSpeed <= 0.0 || output.work <= 0.0) { + if (grantedSpeed <= 0.0) { output.actualSpeed = 0.0 continue } @@ -203,35 +181,29 @@ public class SimResourceDistributorMaxMin( output.actualSpeed = grantedSpeed availableSpeed -= grantedSpeed - - // The duration that we want to run is that of the shortest request of an output - duration = min(duration, output.work / grantedSpeed) } - val targetDuration = min(duration, (deadline - now) / 1000.0) + val durationS = duration / 1000.0 var totalRequestedWork = 0.0 var totalAllocatedWork = 0.0 for (output in activeOutputs) { - val work = output.work + val limit = output.limit val speed = output.actualSpeed if (speed > 0.0) { - val outputDuration = work / speed - totalRequestedWork += work * (duration / outputDuration) - totalAllocatedWork += work * (targetDuration / outputDuration) + totalRequestedWork += limit * durationS + totalAllocatedWork += speed * durationS } } - assert(deadline >= now) { "Deadline already passed" } - this.totalRequestedSpeed = totalRequestedSpeed this.totalAllocatedWork = totalAllocatedWork val totalAllocatedSpeed = capacity - availableSpeed this.totalAllocatedSpeed = totalAllocatedSpeed return if (totalAllocatedWork > 0.0 && totalAllocatedSpeed > 0.0) - SimResourceCommand.Consume(totalAllocatedWork, totalAllocatedSpeed, deadline) + SimResourceCommand.Consume(totalAllocatedSpeed, duration) else - SimResourceCommand.Idle(deadline) + SimResourceCommand.Consume(0.0, duration) } private fun updateCapacity(ctx: SimResourceContext) { @@ -243,7 +215,7 @@ public class SimResourceDistributorMaxMin( /** * An internal [SimResourceProvider] implementation for switch outputs. */ - private inner class Output(capacity: Double, private val key: InterferenceKey?) : + private inner class Output(capacity: Double, val key: InterferenceKey?) : SimAbstractResourceProvider(interpreter, parent, capacity), SimResourceCloseableProvider, SimResourceProviderLogic, @@ -253,11 +225,6 @@ public class SimResourceDistributorMaxMin( */ private var isClosed: Boolean = false - /** - * The current requested work. - */ - @JvmField var work: Double = 0.0 - /** * The requested limit. */ @@ -266,7 +233,7 @@ public class SimResourceDistributorMaxMin( /** * The current deadline. */ - @JvmField var deadline: Long = Long.MAX_VALUE + @JvmField var duration: Long = Long.MAX_VALUE /** * The processing speed that is allowed by the model constraints. @@ -304,44 +271,19 @@ public class SimResourceDistributorMaxMin( } /* SimResourceProviderLogic */ - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long { - allowedSpeed = 0.0 - this.deadline = deadline - work = 0.0 - limit = 0.0 - lastCommandTimestamp = ctx.clock.millis() - - return Long.MAX_VALUE - } - - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long { + override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { allowedSpeed = min(ctx.capacity, limit) - this.work = work this.limit = limit - this.deadline = deadline - lastCommandTimestamp = ctx.clock.millis() - - return Long.MAX_VALUE - } - - override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { - updateCounters(ctx, work, willOvercommit) + this.duration = duration + lastCommandTimestamp = now - this@SimResourceDistributorMaxMin.updateCounters(ctx, work, willOvercommit) - } - - override fun onFinish(ctx: SimResourceControllableContext) { - work = 0.0 - limit = 0.0 - deadline = Long.MAX_VALUE - lastCommandTimestamp = ctx.clock.millis() + return super.onConsume(ctx, now, limit, duration) } - override fun getConsumedWork(ctx: SimResourceControllableContext, work: Double, speed: Double, duration: Long): Double { - val totalRemainingWork = this@SimResourceDistributorMaxMin.ctx?.remainingWork ?: 0.0 - - // Compute the fraction of compute time allocated to the output - val fraction = actualSpeed / totalAllocatedSpeed + override fun onUpdate(ctx: SimResourceControllableContext, delta: Long, limit: Double, willOvercommit: Boolean) { + if (delta <= 0.0) { + return + } // Compute the performance penalty due to resource interference val perfScore = if (interferenceDomain != null) { @@ -351,12 +293,29 @@ public class SimResourceDistributorMaxMin( 1.0 } - // Compute the work that was actually granted to the output. - val potentialConsumedWork = (totalAllocatedWork - totalRemainingWork) * fraction + val deltaS = delta / 1000.0 + val work = limit * deltaS + val actualWork = actualSpeed * deltaS + val remainingWork = work - actualWork + val overcommit = if (willOvercommit && remainingWork > 0.0) { + remainingWork + } else { + 0.0 + } - _counters.interference += potentialConsumedWork * max(0.0, 1 - perfScore) + updateCounters(work, actualWork, overcommit) - return potentialConsumedWork + val distCounters = _counters + distCounters.demand += work + distCounters.actual += actualWork + distCounters.overcommit += overcommit + distCounters.interference += actualWork * max(0.0, 1 - perfScore) + } + + override fun onFinish(ctx: SimResourceControllableContext) { + limit = 0.0 + duration = Long.MAX_VALUE + lastCommandTimestamp = ctx.clock.millis() } /* Comparable */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt index 2fe1b00f..d8ff87f9 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt @@ -27,53 +27,33 @@ package org.opendc.simulator.resources */ public interface SimResourceProviderLogic { /** - * This method is invoked when the resource is reported to idle until the specified [deadline]. + * This method is invoked when the consumer ask to consume the resource for the specified [duration]. * * @param ctx The context in which the provider runs. - * @param deadline The deadline that was requested by the resource consumer. - * @return The instant at which to resume the consumer. - */ - public fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long - - /** - * This method is invoked when the resource will be consumed until the specified amount of [work] was processed - * or [deadline] is reached. - * - * @param ctx The context in which the provider runs. - * @param work The amount of work that was requested by the resource consumer. + * @param now The virtual timestamp in milliseconds at which the update is occurring. * @param limit The limit on the work rate of the resource consumer. - * @param deadline The deadline that was requested by the resource consumer. - * @return The instant at which to resume the consumer. + * @param duration The duration of the consumption in milliseconds. + * @return The deadline of the resource consumption. */ - public fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long + public fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { + return if (duration == Long.MAX_VALUE) { + return Long.MAX_VALUE + } else { + now + duration + } + } /** * This method is invoked when the progress of the resource consumer is materialized. * * @param ctx The context in which the provider runs. - * @param work The amount of work that was requested by the resource consumer. + * @param limit The limit on the work rate of the resource consumer. * @param willOvercommit A flag to indicate that the remaining work is overcommitted. */ - public fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) {} + public fun onUpdate(ctx: SimResourceControllableContext, delta: Long, limit: Double, willOvercommit: Boolean) {} /** * This method is invoked when the resource consumer has finished. */ - public fun onFinish(ctx: SimResourceControllableContext) - - /** - * Compute the amount of work that was consumed over the specified [duration]. - * - * @param work The total size of the resource consumption. - * @param speed The speed of the resource provider. - * @param duration The duration from the start of the consumption until now. - * @return The amount of work that was consumed by the resource provider. - */ - public fun getConsumedWork(ctx: SimResourceControllableContext, work: Double, speed: Double, duration: Long): Double { - return if (duration > 0L) { - return (duration / 1000.0) * speed - } else { - work - } - } + public fun onFinish(ctx: SimResourceControllableContext) {} } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt index 2d53198a..10213f26 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt @@ -22,9 +22,6 @@ package org.opendc.simulator.resources -import kotlin.math.ceil -import kotlin.math.min - /** * A [SimResourceSource] represents a source for some resource that provides bounded processing capacity. * @@ -39,20 +36,13 @@ public class SimResourceSource( ) : SimAbstractResourceProvider(interpreter, parent, initialCapacity) { override fun createLogic(): SimResourceProviderLogic { return object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long { - return deadline - } - - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long { - return if (work.isInfinite()) { - Long.MAX_VALUE - } else { - min(deadline, ctx.clock.millis() + getDuration(work, speed)) - } - } - - override fun onUpdate(ctx: SimResourceControllableContext, work: Double, willOvercommit: Boolean) { - updateCounters(ctx, work, willOvercommit) + override fun onUpdate( + ctx: SimResourceControllableContext, + delta: Long, + limit: Double, + willOvercommit: Boolean + ) { + updateCounters(ctx, delta, limit, willOvercommit) } override fun onFinish(ctx: SimResourceControllableContext) { @@ -62,11 +52,4 @@ public class SimResourceSource( } override fun toString(): String = "SimResourceSource[capacity=$capacity]" - - /** - * Compute the duration that a resource consumption will take with the specified [speed]. - */ - private fun getDuration(work: Double, speed: Double): Long { - return ceil(work / speed * 1000).toLong() - } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt index cec27e1c..68bedbd9 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt @@ -100,19 +100,19 @@ public class SimResourceTransformer( } } - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { val delegate = delegate if (!hasDelegateStarted) { start() } - updateCounters(ctx) + updateCounters(ctx, delta) return if (delegate != null) { - val command = transform(ctx, delegate.onNext(ctx)) + val command = transform(ctx, delegate.onNext(ctx, now, delta)) - _work = if (command is SimResourceCommand.Consume) command.work else 0.0 + _limit = if (command is SimResourceCommand.Consume) command.limit else 0.0 if (command == SimResourceCommand.Exit) { // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we @@ -124,12 +124,12 @@ public class SimResourceTransformer( if (isCoupled) SimResourceCommand.Exit else - onNext(ctx) + onNext(ctx, now, delta) } else { command } } else { - SimResourceCommand.Idle() + SimResourceCommand.Consume(0.0) } } @@ -180,19 +180,21 @@ public class SimResourceTransformer( } /** - * Counter to track the current submitted work. + * The requested speed. */ - private var _work = 0.0 + private var _limit: Double = 0.0 /** * Update the resource counters for the transformer. */ - private fun updateCounters(ctx: SimResourceContext) { + private fun updateCounters(ctx: SimResourceContext, delta: Long) { val counters = _counters - val remainingWork = ctx.remainingWork - counters.demand += _work - counters.actual += _work - remainingWork - counters.overcommit += remainingWork + val deltaS = delta / 1000.0 + val work = _limit * deltaS + val actualWork = ctx.speed * deltaS + counters.demand += work + counters.actual += actualWork + counters.overcommit += (work - actualWork) } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt index 4f4ebb14..1f8434b7 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt @@ -50,8 +50,8 @@ public class SimSpeedConsumerAdapter( callback(0.0) } - override fun onNext(ctx: SimResourceContext): SimResourceCommand { - return delegate.onNext(ctx) + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + return delegate.onNext(ctx, now, delta) } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt index 2e94e1c1..e5173e5f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt @@ -34,20 +34,11 @@ import org.opendc.simulator.resources.SimResourceEvent public class SimTraceConsumer(private val trace: Sequence) : SimResourceConsumer { private var iterator: Iterator? = null - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { val iterator = checkNotNull(iterator) return if (iterator.hasNext()) { - val now = ctx.clock.millis() val fragment = iterator.next() - val work = (fragment.duration / 1000) * fragment.usage - val deadline = now + fragment.duration - - assert(deadline >= now) { "Deadline already passed" } - - if (work > 0.0) - SimResourceCommand.Consume(work, fragment.usage, deadline) - else - SimResourceCommand.Idle(deadline) + SimResourceCommand.Consume(fragment.usage, fragment.duration) } else { SimResourceCommand.Exit } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt index faa693c4..ae837043 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt @@ -25,6 +25,7 @@ package org.opendc.simulator.resources.consumer import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext +import kotlin.math.roundToLong /** * A [SimResourceConsumer] that consumes the specified amount of work at the specified utilization. @@ -39,18 +40,19 @@ public class SimWorkConsumer( require(utilization > 0.0 && utilization <= 1.0) { "Utilization must be in (0, 1]" } } - private var isFirst = true + private var remainingWork = work - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + val actualWork = ctx.speed * delta / 1000.0 val limit = ctx.capacity * utilization - val work = if (isFirst) { - isFirst = false - work - } else { - ctx.remainingWork - } - return if (work > 0.0) { - SimResourceCommand.Consume(work, limit) + + remainingWork -= actualWork + + val remainingWork = remainingWork + val duration = (remainingWork / limit * 1000).roundToLong() + + return if (duration > 0) { + SimResourceCommand.Consume(limit, duration) } else { SimResourceCommand.Exit } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index b79998a3..a9507e52 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -57,12 +57,6 @@ internal class SimResourceContextImpl( } } - /** - * The amount of work still remaining at this instant. - */ - override val remainingWork: Double - get() = getRemainingWork(_clock.millis()) - /** * A flag to indicate the state of the context. */ @@ -87,8 +81,8 @@ internal class SimResourceContextImpl( * The current state of the resource context. */ private var _timestamp: Long = Long.MIN_VALUE - private var _work: Double = 0.0 private var _limit: Double = 0.0 + private var _duration: Long = Long.MAX_VALUE private var _deadline: Long = Long.MAX_VALUE /** @@ -178,7 +172,6 @@ internal class SimResourceContextImpl( } catch (cause: Throwable) { doFail(cause) } finally { - _remainingWorkFlush = Long.MIN_VALUE _timestamp = timestamp } } @@ -200,29 +193,25 @@ internal class SimResourceContextImpl( SimResourceState.Pending, SimResourceState.Stopped -> state SimResourceState.Active -> { val isInterrupted = _flag and FLAG_INTERRUPT != 0 - val remainingWork = getRemainingWork(timestamp) - val isConsume = _limit > 0.0 val reachedDeadline = _deadline <= timestamp + val delta = max(0, timestamp - _timestamp) // Update the resource counters only if there is some progress if (timestamp > _timestamp) { - logic.onUpdate(this, _work, reachedDeadline) + logic.onUpdate(this, delta, _limit, reachedDeadline) } // We should only continue processing the next command if: // 1. The resource consumption was finished. // 2. The resource capacity cannot satisfy the demand. // 3. The resource consumer should be interrupted (e.g., someone called .interrupt()) - if ((isConsume && remainingWork == 0.0) || reachedDeadline || isInterrupted) { - when (val command = consumer.onNext(this)) { - is SimResourceCommand.Idle -> interpretIdle(timestamp, command.deadline) - is SimResourceCommand.Consume -> interpretConsume(timestamp, command.work, command.limit, command.deadline) + if (reachedDeadline || isInterrupted) { + when (val command = consumer.onNext(this, timestamp, delta)) { + is SimResourceCommand.Consume -> interpretConsume(timestamp, command.limit, command.duration) is SimResourceCommand.Exit -> interpretExit() } - } else if (isConsume) { - interpretConsume(timestamp, remainingWork, _limit, _deadline) } else { - interpretIdle(timestamp, _deadline) + interpretConsume(timestamp, _limit, _duration - delta) } } } @@ -257,32 +246,15 @@ internal class SimResourceContextImpl( /** * Interpret the [SimResourceCommand.Consume] command. */ - private fun interpretConsume(now: Long, work: Double, limit: Double, deadline: Long): SimResourceState { - require(deadline >= now) { "Deadline already passed" } - + private fun interpretConsume(now: Long, limit: Double, duration: Long): SimResourceState { _speed = min(capacity, limit) - _work = work _limit = limit - _deadline = deadline + _duration = duration - val timestamp = logic.onConsume(this, work, limit, deadline) - scheduleUpdate(timestamp) + val timestamp = logic.onConsume(this, now, limit, duration) - return SimResourceState.Active - } - - /** - * Interpret the [SimResourceCommand.Idle] command. - */ - private fun interpretIdle(now: Long, deadline: Long): SimResourceState { - require(deadline >= now) { "Deadline already passed" } - - _speed = 0.0 - _work = 0.0 - _limit = 0.0 - _deadline = deadline + _deadline = timestamp - val timestamp = logic.onIdle(this, deadline) scheduleUpdate(timestamp) return SimResourceState.Active @@ -293,37 +265,13 @@ internal class SimResourceContextImpl( */ private fun interpretExit(): SimResourceState { _speed = 0.0 - _work = 0.0 _limit = 0.0 + _duration = Long.MAX_VALUE _deadline = Long.MAX_VALUE return SimResourceState.Stopped } - private var _remainingWork: Double = 0.0 - private var _remainingWorkFlush: Long = Long.MIN_VALUE - - /** - * Obtain the remaining work at the given timestamp. - */ - private fun getRemainingWork(now: Long): Double { - return if (_remainingWorkFlush < now) { - _remainingWorkFlush = now - computeRemainingWork(now).also { _remainingWork = it } - } else { - _remainingWork - } - } - - /** - * Compute the remaining work based on the current state. - */ - private fun computeRemainingWork(now: Long): Double { - return if (_work > 0.0) - max(0.0, _work - logic.getConsumedWork(this, _work, speed, now - _timestamp)) - else 0.0 - } - /** * Indicate that the capacity of the resource has changed. */ @@ -333,16 +281,11 @@ internal class SimResourceContextImpl( return } - val isThrottled = speed > capacity - interpreter.batch { // Inform the consumer of the capacity change. This might already trigger an interrupt. consumer.onEvent(this, SimResourceEvent.Capacity) - // Optimization: only invalidate context if the new capacity cannot satisfy the active resource command. - if (isThrottled) { - invalidate() - } + interrupt() } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt index 2f01a8c4..a9390553 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt @@ -38,7 +38,6 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * Test suite for the [SimResourceAggregatorMaxMin] class. */ -@OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceAggregatorMaxMinTest { @Test fun testSingleCapacity() = runBlockingSimulation { @@ -102,15 +101,15 @@ internal class SimResourceAggregatorMaxMinTest { sources.forEach(aggregator::addInput) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(4.0, 4.0, 1000)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(4.0, 1000)) .andThen(SimResourceCommand.Exit) aggregator.consume(consumer) yield() assertEquals(1000, clock.millis()) - verify(exactly = 2) { consumer.onNext(any()) } + verify(exactly = 2) { consumer.onNext(any(), any(), any()) } } @Test @@ -125,8 +124,8 @@ internal class SimResourceAggregatorMaxMinTest { sources.forEach(aggregator::addInput) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(1.0, 1.0)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(1.0, duration = 1000)) .andThenThrows(IllegalStateException("Test Exception")) assertThrows { aggregator.consume(consumer) } @@ -152,7 +151,7 @@ internal class SimResourceAggregatorMaxMinTest { sources[0].capacity = 0.5 } yield() - assertEquals(2334, clock.millis()) + assertEquals(2333, clock.millis()) } @Test @@ -173,7 +172,7 @@ internal class SimResourceAggregatorMaxMinTest { sources[0].capacity = 0.5 } yield() - assertEquals(1000, clock.millis()) + assertEquals(1167, clock.millis()) } @Test @@ -188,8 +187,8 @@ internal class SimResourceAggregatorMaxMinTest { sources.forEach(aggregator::addInput) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(4.0, 4.0, 1000)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(4.0, 1000)) .andThen(SimResourceCommand.Exit) aggregator.consume(consumer) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt index 02d456ff..9a52dc63 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt @@ -31,44 +31,23 @@ import org.junit.jupiter.api.assertThrows */ class SimResourceCommandTest { @Test - fun testZeroWork() { - assertThrows { - SimResourceCommand.Consume(0.0, 1.0) - } - } - - @Test - fun testNegativeWork() { - assertThrows { - SimResourceCommand.Consume(-1.0, 1.0) - } - } - - @Test - fun testZeroLimit() { + fun testNegativeLimit() { assertThrows { - SimResourceCommand.Consume(1.0, 0.0) + SimResourceCommand.Consume(-1.0, 1) } } @Test - fun testNegativeLimit() { + fun testNegativeDuration() { assertThrows { - SimResourceCommand.Consume(1.0, -1.0, 1) + SimResourceCommand.Consume(1.0, -1) } } @Test fun testConsumeCorrect() { assertDoesNotThrow { - SimResourceCommand.Consume(1.0, 1.0) - } - } - - @Test - fun testIdleCorrect() { - assertDoesNotThrow { - SimResourceCommand.Idle(1) + SimResourceCommand.Consume(1.0) } } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt index 6cb507ce..0cb95abb 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt @@ -32,19 +32,14 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * A test suite for the [SimResourceContextImpl] class. */ -@OptIn(ExperimentalCoroutinesApi::class) class SimResourceContextTest { @Test fun testFlushWithoutCommand() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Consume(10.0, 1.0) andThen SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit - val logic = object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long = deadline - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long = deadline - override fun onFinish(ctx: SimResourceControllableContext) {} - } + val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) context.doUpdate(interpreter.clock.millis()) @@ -54,12 +49,11 @@ class SimResourceContextTest { fun testIntermediateFlush() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Consume(10.0, 1.0) andThen SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit val logic = spyk(object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long = deadline override fun onFinish(ctx: SimResourceControllableContext) {} - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long = deadline + override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long = duration }) val context = spyk(SimResourceContextImpl(null, interpreter, consumer, logic)) @@ -74,13 +68,9 @@ class SimResourceContextTest { fun testIntermediateFlushIdle() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Idle(10) andThen SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) andThen SimResourceCommand.Exit - val logic = spyk(object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long = deadline - override fun onFinish(ctx: SimResourceControllableContext) {} - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long = deadline - }) + val logic = spyk(object : SimResourceProviderLogic {}) val context = spyk(SimResourceContextImpl(null, interpreter, consumer, logic)) context.start() @@ -90,7 +80,7 @@ class SimResourceContextTest { context.invalidate() assertAll( - { verify(exactly = 2) { logic.onIdle(any(), any()) } }, + { verify(exactly = 2) { logic.onConsume(any(), any(), 0.0, any()) } }, { verify(exactly = 1) { logic.onFinish(any()) } } ) } @@ -99,13 +89,9 @@ class SimResourceContextTest { fun testDoubleStart() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Idle(10) andThen SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) andThen SimResourceCommand.Exit - val logic = object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long = deadline - override fun onFinish(ctx: SimResourceControllableContext) {} - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long = deadline - } + val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) context.start() @@ -116,16 +102,12 @@ class SimResourceContextTest { } @Test - fun testIdempodentCapacityChange() = runBlockingSimulation { + fun testIdempotentCapacityChange() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Consume(10.0, 1.0) andThen SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit - val logic = object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long = deadline - override fun onFinish(ctx: SimResourceControllableContext) {} - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long = deadline - } + val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) context.capacity = 4200.0 @@ -139,15 +121,11 @@ class SimResourceContextTest { fun testFailureNoInfiniteLoop() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Exit every { consumer.onEvent(any(), SimResourceEvent.Exit) } throws IllegalStateException("onEvent") every { consumer.onFailure(any(), any()) } throws IllegalStateException("onFailure") - val logic = spyk(object : SimResourceProviderLogic { - override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long = deadline - override fun onFinish(ctx: SimResourceControllableContext) {} - override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long = deadline - }) + val logic = spyk(object : SimResourceProviderLogic {}) val context = SimResourceContextImpl(null, interpreter, consumer, logic) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt index 4895544d..c310fad6 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt @@ -37,8 +37,7 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * A test suite for the [SimResourceSource] class. */ -@OptIn(ExperimentalCoroutinesApi::class) -class SimResourceSourceTest { +internal class SimResourceSourceTest { @Test fun testSpeed() = runBlockingSimulation { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) @@ -46,8 +45,8 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(1000 * capacity, capacity)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(capacity, duration = 1000)) .andThen(SimResourceCommand.Exit) val res = mutableListOf() @@ -81,8 +80,8 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(1000 * capacity, 2 * capacity)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(2 * capacity, duration = 1000)) .andThen(SimResourceCommand.Exit) val res = mutableListOf() @@ -104,7 +103,7 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { return SimResourceCommand.Exit } @@ -133,11 +132,10 @@ class SimResourceSourceTest { } } - override fun onNext(ctx: SimResourceContext): SimResourceCommand { - assertEquals(0.0, ctx.remainingWork) + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { return if (isFirst) { isFirst = false - SimResourceCommand.Consume(4.0, 1.0) + SimResourceCommand.Consume(1.0, duration = 4000) } else { SimResourceCommand.Exit } @@ -175,8 +173,8 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(1.0, 1.0)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(1.0, duration = 1000)) .andThenThrows(IllegalStateException()) assertThrows { @@ -191,8 +189,8 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(1.0, 1.0)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(1.0)) .andThenThrows(IllegalStateException()) assertThrows { @@ -210,8 +208,8 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Consume(1.0, 1.0)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(1.0)) .andThenThrows(IllegalStateException()) launch { provider.consume(consumer) } @@ -228,8 +226,8 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Idle(clock.millis() + 500)) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(0.0, 500)) .andThen(SimResourceCommand.Exit) provider.consume(consumer) @@ -246,28 +244,12 @@ class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Idle()) + every { consumer.onNext(any(), any(), any()) } + .returns(SimResourceCommand.Consume(0.0)) .andThenThrows(IllegalStateException()) provider.consume(consumer) } } } - - @Test - fun testIncorrectDeadline() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } - .returns(SimResourceCommand.Idle(2)) - .andThen(SimResourceCommand.Exit) - - delay(10) - - assertThrows { provider.consume(consumer) } - } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt index ad8d82e3..ad3b0f9f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.resources import io.mockk.every import io.mockk.mockk -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -38,7 +37,6 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * Test suite for the [SimResourceSwitchExclusive] class. */ -@OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceSwitchExclusiveTest { /** * Test a trace workload. @@ -91,7 +89,7 @@ internal class SimResourceSwitchExclusiveTest { val duration = 5 * 60L * 1000 val workload = mockk(relaxUnitFun = true) - every { workload.onNext(any()) } returns SimResourceCommand.Consume(duration / 1000.0, 1.0) andThen SimResourceCommand.Exit + every { workload.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0, duration = duration) andThen SimResourceCommand.Exit val switch = SimResourceSwitchExclusive() val source = SimResourceSource(3200.0, scheduler) @@ -127,10 +125,10 @@ internal class SimResourceSwitchExclusiveTest { } } - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { return if (isFirst) { isFirst = false - SimResourceCommand.Consume(duration / 1000.0, 1.0) + SimResourceCommand.Consume(1.0, duration = duration) } else { SimResourceCommand.Exit } @@ -161,9 +159,8 @@ internal class SimResourceSwitchExclusiveTest { fun testConcurrentWorkloadFails() = runBlockingSimulation { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val duration = 5 * 60L * 1000 val workload = mockk(relaxUnitFun = true) - every { workload.onNext(any()) } returns SimResourceCommand.Consume(duration / 1000.0, 1.0) andThen SimResourceCommand.Exit + every { workload.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit val switch = SimResourceSwitchExclusive() val source = SimResourceSource(3200.0, scheduler) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt index e4292ec0..d8f18e65 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.resources import io.mockk.every import io.mockk.mockk -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.yield @@ -37,7 +36,6 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * Test suite for the [SimResourceSwitch] implementations */ -@OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceSwitchMaxMinTest { @Test fun testSmoke() = runBlockingSimulation { @@ -50,7 +48,7 @@ internal class SimResourceSwitchMaxMinTest { val provider = switch.newOutput() val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Consume(1.0, 1.0) andThen SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0, duration = 1000) andThen SimResourceCommand.Exit try { provider.consume(consumer) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt index cf69b7b5..3780fd60 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt @@ -37,7 +37,6 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * A test suite for the [SimResourceTransformer] class. */ -@OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceTransformerTest { @Test fun testCancelImmediately() = runBlockingSimulation { @@ -48,7 +47,7 @@ internal class SimResourceTransformerTest { launch { source.consume(forwarder) } forwarder.consume(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { return SimResourceCommand.Exit } }) @@ -68,10 +67,10 @@ internal class SimResourceTransformerTest { forwarder.consume(object : SimResourceConsumer { var isFirst = true - override fun onNext(ctx: SimResourceContext): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { return if (isFirst) { isFirst = false - SimResourceCommand.Consume(10.0, 1.0) + SimResourceCommand.Consume(1.0, duration = 10 * 1000L) } else { SimResourceCommand.Exit } @@ -86,7 +85,7 @@ internal class SimResourceTransformerTest { fun testState() = runBlockingSimulation { val forwarder = SimResourceForwarder() val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext): SimResourceCommand = SimResourceCommand.Exit + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand = SimResourceCommand.Exit } assertFalse(forwarder.isActive) @@ -108,7 +107,7 @@ internal class SimResourceTransformerTest { val forwarder = SimResourceForwarder() val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Exit forwarder.startConsumer(consumer) forwarder.cancel() @@ -123,7 +122,7 @@ internal class SimResourceTransformerTest { val source = SimResourceSource(2000.0, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Idle(10) + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) source.startConsumer(forwarder) yield() @@ -142,7 +141,7 @@ internal class SimResourceTransformerTest { val source = SimResourceSource(2000.0, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Idle(10) + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) source.startConsumer(forwarder) yield() @@ -161,7 +160,7 @@ internal class SimResourceTransformerTest { val source = SimResourceSource(2000.0, scheduler) val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any()) } returns SimResourceCommand.Exit + every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Exit source.startConsumer(forwarder) forwarder.consume(consumer) @@ -200,7 +199,7 @@ internal class SimResourceTransformerTest { forwarder.consume(consumer) assertEquals(0, clock.millis()) - verify(exactly = 1) { consumer.onNext(any()) } + verify(exactly = 1) { consumer.onNext(any(), any(), any()) } } @Test diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt index 42648cf1..830f16d3 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.resources -import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.opendc.simulator.core.runBlockingSimulation @@ -32,7 +31,6 @@ import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** * A test suite for the [SimWorkConsumer] class. */ -@OptIn(ExperimentalCoroutinesApi::class) internal class SimWorkConsumerTest { @Test fun testSmoke() = runBlockingSimulation { diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt index 728dfd99..992b4991 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt @@ -126,7 +126,7 @@ internal class WorkflowServiceTest { { assertEquals(metrics.jobsSubmitted, metrics.jobsFinished, "Not all started jobs finished") }, { assertEquals(0, metrics.tasksActive, "Not all started tasks finished") }, { assertEquals(metrics.tasksSubmitted, metrics.tasksFinished, "Not all started tasks finished") }, - { assertEquals(33213237L, clock.millis()) } + { assertEquals(33213236L, clock.millis()) } ) } -- cgit v1.2.3 From 02fa44c0b116ff51c4cbe2876d8b2a225ed68553 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 28 Sep 2021 11:58:19 +0200 Subject: refactor(simulator): Add support for pushing flow from context This change adds a new method to `SimResourceContext` called `push` which allows users to change the requested flow rate directly without having to interrupt the consumer. --- .../opendc/experiments/tf20/core/SimTFDevice.kt | 11 +- .../org/opendc/simulator/compute/device/SimPsu.kt | 10 +- .../simulator/compute/workload/SimTraceWorkload.kt | 21 ++-- .../org/opendc/simulator/network/SimNetworkSink.kt | 2 +- .../kotlin/org/opendc/simulator/power/SimPdu.kt | 15 +-- .../kotlin/org/opendc/simulator/power/SimUps.kt | 15 +-- .../resources/SimAbstractResourceAggregator.kt | 53 ++++++--- .../resources/SimResourceAggregatorMaxMin.kt | 8 +- .../simulator/resources/SimResourceCommand.kt | 46 -------- .../simulator/resources/SimResourceConsumer.kt | 7 +- .../simulator/resources/SimResourceContext.kt | 14 ++- .../resources/SimResourceControllableContext.kt | 7 +- .../resources/SimResourceDistributorMaxMin.kt | 18 +-- .../simulator/resources/SimResourceTransformer.kt | 109 +++++++++++------- .../resources/consumer/SimSpeedConsumerAdapter.kt | 3 +- .../resources/consumer/SimTraceConsumer.kt | 9 +- .../resources/consumer/SimWorkConsumer.kt | 11 +- .../resources/impl/SimResourceContextImpl.kt | 123 +++++++++------------ .../resources/SimResourceAggregatorMaxMinTest.kt | 55 ++++----- .../simulator/resources/SimResourceCommandTest.kt | 53 --------- .../simulator/resources/SimResourceContextTest.kt | 90 ++++++++++++--- .../simulator/resources/SimResourceSourceTest.kt | 73 +++++------- .../resources/SimResourceSwitchExclusiveTest.kt | 17 ++- .../resources/SimResourceSwitchMaxMinTest.kt | 7 +- .../resources/SimResourceTransformerTest.kt | 44 +++++--- 25 files changed, 392 insertions(+), 429 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index bfc5fc6f..1fbd3b6a 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -128,7 +128,7 @@ public class SimTFDevice( } } - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { val consumedWork = ctx.speed * delta / 1000.0 val activeWork = activeWork @@ -137,7 +137,8 @@ public class SimTFDevice( this.activeWork = null } else { val duration = (activeWork.flops / ctx.capacity * 1000).roundToLong() - return SimResourceCommand.Consume(ctx.capacity, duration) + ctx.push(ctx.capacity) + return duration } } @@ -146,9 +147,11 @@ public class SimTFDevice( return if (head != null) { this.activeWork = head val duration = (head.flops / ctx.capacity * 1000).roundToLong() - SimResourceCommand.Consume(ctx.capacity, duration) + ctx.push(ctx.capacity) + duration } else { - SimResourceCommand.Consume(0.0) + ctx.push(0.0) + Long.MAX_VALUE } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index 34ac4418..6e6e590f 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.compute.device import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.power.SimPowerInlet -import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext import org.opendc.simulator.resources.SimResourceEvent @@ -83,13 +82,10 @@ public class SimPsu( } override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { val powerDraw = computePowerDraw(_driver?.computePower() ?: 0.0) - - return if (powerDraw > 0.0) - SimResourceCommand.Consume(powerDraw, Long.MAX_VALUE) - else - SimResourceCommand.Consume(0.0) + ctx.push(powerDraw) + return Long.MAX_VALUE } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index 527619bd..dd582bb2 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext import kotlin.math.min @@ -80,13 +79,20 @@ public class SimTraceWorkload(public val trace: Sequence, private val } private inner class Consumer(val cpu: ProcessingUnit) : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { - val fragment = pullFragment(now) ?: return SimResourceCommand.Exit + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + val fragment = pullFragment(now) + + if (fragment == null) { + ctx.close() + return Long.MAX_VALUE + } + val timestamp = fragment.timestamp + offset // Fragment is in the future if (timestamp > now) { - return SimResourceCommand.Consume(0.0, timestamp - now) + ctx.push(0.0) + return timestamp - now } val cores = min(cpu.node.coreCount, fragment.cores) @@ -97,10 +103,9 @@ public class SimTraceWorkload(public val trace: Sequence, private val val deadline = timestamp + fragment.duration val duration = deadline - now - return if (cpu.id < cores && usage > 0.0) - SimResourceCommand.Consume(usage, duration) - else - SimResourceCommand.Consume(0.0, duration) + ctx.push(if (cpu.id < cores && usage > 0.0) usage else 0.0) + + return duration } } diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt index f2dd8455..7db0f176 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt @@ -32,7 +32,7 @@ public class SimNetworkSink( public val capacity: Double ) : SimNetworkPort() { override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand = SimResourceCommand.Consume(0.0) + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long = Long.MAX_VALUE override fun toString(): String = "SimNetworkSink.Consumer" } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index e8839496..b0ea7f0a 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -47,16 +47,13 @@ public class SimPdu( public fun newOutlet(): Outlet = Outlet(distributor.newOutput()) override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer by distributor { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { - return when (val cmd = distributor.onNext(ctx, now, delta)) { - is SimResourceCommand.Consume -> { - val loss = computePowerLoss(cmd.limit) - val newLimit = cmd.limit + loss + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + val duration = distributor.onNext(ctx, now, delta) + val loss = computePowerLoss(ctx.demand) + val newLimit = ctx.demand + loss - SimResourceCommand.Consume(newLimit, cmd.duration) - } - else -> cmd - } + ctx.push(newLimit) + return duration } override fun toString(): String = "SimPdu.Consumer" diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 4c2beb68..59006dfc 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -55,16 +55,13 @@ public class SimUps( override fun onConnect(inlet: SimPowerInlet) { val consumer = inlet.createConsumer() aggregator.startConsumer(object : SimResourceConsumer by consumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { - return when (val cmd = consumer.onNext(ctx, now, delta)) { - is SimResourceCommand.Consume -> { - val loss = computePowerLoss(cmd.limit) - val newLimit = cmd.limit + loss + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + val duration = consumer.onNext(ctx, now, delta) + val loss = computePowerLoss(ctx.demand) + val newLimit = ctx.demand + loss - SimResourceCommand.Consume(newLimit, cmd.duration) - } - else -> cmd - } + ctx.push(newLimit) + return duration } }) } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt index da5c3257..8e0eb5f8 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt @@ -125,16 +125,21 @@ public abstract class SimAbstractResourceAggregator( /** * An input for the resource aggregator. */ - public interface Input { + public interface Input : AutoCloseable { /** * The [SimResourceContext] associated with the input. */ public val ctx: SimResourceContext /** - * Push the specified [SimResourceCommand] to the input. + * Push to this input with the specified [limit] and [duration]. */ - public fun push(command: SimResourceCommand) + public fun push(limit: Double, duration: Long) + + /** + * Close the input for further input. + */ + public override fun close() } /** @@ -151,7 +156,12 @@ public abstract class SimAbstractResourceAggregator( /** * The resource command to run next. */ - private var command: SimResourceCommand? = null + private var _duration: Long = Long.MAX_VALUE + + /** + * A flag to indicate that the consumer should flush. + */ + private var _isPushed = false private fun updateCapacity() { // Adjust capacity of output resource @@ -159,25 +169,34 @@ public abstract class SimAbstractResourceAggregator( } /* Input */ - override fun push(command: SimResourceCommand) { - this.command = command - _ctx?.interrupt() + override fun push(limit: Double, duration: Long) { + _duration = duration + val ctx = _ctx + if (ctx != null) { + ctx.push(limit) + ctx.interrupt() + } + _isPushed = true + } + + override fun close() { + _duration = Long.MAX_VALUE + _isPushed = true + _ctx?.close() } /* SimResourceConsumer */ - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { - var next = command + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + var next = _duration - return if (next != null) { - this.command = null - next - } else { + if (!_isPushed) { _output.flush() - - next = command - this.command = null - next ?: SimResourceCommand.Consume(0.0) + next = _duration } + + _isPushed = false + _duration = Long.MAX_VALUE + return next } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt index 537be1b5..b258a368 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt @@ -41,11 +41,7 @@ public class SimResourceAggregatorMaxMin( val fraction = inputCapacity / capacity val grantedSpeed = limit * fraction - val command = if (grantedSpeed > 0.0) - SimResourceCommand.Consume(grantedSpeed, duration) - else - SimResourceCommand.Consume(0.0, duration) - input.push(command) + input.push(grantedSpeed, duration) } } @@ -53,7 +49,7 @@ public class SimResourceAggregatorMaxMin( val iterator = consumers.iterator() for (input in iterator) { iterator.remove() - input.push(SimResourceCommand.Exit) + input.close() } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt deleted file mode 100644 index 4a980071..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCommand.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A SimResourceCommand communicates to a resource how it is consumed by a [SimResourceConsumer]. - */ -public sealed class SimResourceCommand { - /** - * A request to the resource to perform work for the specified [duration]. - * - * @param limit The maximum amount of work to be processed per second. - * @param duration The duration of the resource consumption in milliseconds. - */ - public data class Consume(val limit: Double, val duration: Long = Long.MAX_VALUE) : SimResourceCommand() { - init { - require(limit >= 0.0) { "Negative limit is not allowed" } - require(duration >= 0) { "Duration must be positive" } - } - } - - /** - * An indication to the resource that the consumer has finished. - */ - public object Exit : SimResourceCommand() -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt index 4d1d2c32..0b25358a 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt @@ -30,15 +30,14 @@ package org.opendc.simulator.resources */ public interface SimResourceConsumer { /** - * This method is invoked when a resource asks for the next [command][SimResourceCommand] to process, either because - * the resource finished processing, reached its deadline or was interrupted. + * This method is invoked when the resource provider is pulling this resource consumer. * * @param ctx The execution context in which the consumer runs. * @param now The virtual timestamp in milliseconds at which the update is occurring. * @param delta The virtual duration between this call and the last call in milliseconds. - * @return The next command that the resource should execute. + * @return The duration after which the resource consumer should be pulled again. */ - public fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand + public fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long /** * This method is invoked when an event has occurred. diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt index f28b43d0..225cae0b 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt @@ -28,7 +28,7 @@ import java.time.Clock * The execution context in which a [SimResourceConsumer] runs. It facilitates the communication and control between a * resource and a resource consumer. */ -public interface SimResourceContext { +public interface SimResourceContext : AutoCloseable { /** * The virtual clock tracking simulation time. */ @@ -53,4 +53,16 @@ public interface SimResourceContext { * Ask the resource provider to interrupt its resource. */ public fun interrupt() + + /** + * Push the given flow to this context. + * + * @param rate The rate of the flow to push. + */ + public fun push(rate: Double) + + /** + * Stop the resource context. + */ + public override fun close() } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt index ceaca39a..ba52b597 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt @@ -27,7 +27,7 @@ package org.opendc.simulator.resources * * This interface is used by resource providers to control the resource context. */ -public interface SimResourceControllableContext : SimResourceContext, AutoCloseable { +public interface SimResourceControllableContext : SimResourceContext { /** * The state of the resource context. */ @@ -43,11 +43,6 @@ public interface SimResourceControllableContext : SimResourceContext, AutoClosea */ public fun start() - /** - * Stop the resource context. - */ - public override fun close() - /** * Invalidate the resource context's state. * diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index d23c7dbb..eac58410 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -53,11 +53,6 @@ public class SimResourceDistributorMaxMin( */ private val activeOutputs: MutableList = mutableListOf() - /** - * The total amount of work allocated to be executed. - */ - private var totalAllocatedWork = 0.0 - /** * The total allocated speed for the output resources. */ @@ -97,7 +92,7 @@ public class SimResourceDistributorMaxMin( } /* SimResourceConsumer */ - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { return doNext(ctx, now) } @@ -137,10 +132,10 @@ public class SimResourceDistributorMaxMin( /** * Schedule the work of the outputs. */ - private fun doNext(ctx: SimResourceContext, now: Long): SimResourceCommand { + private fun doNext(ctx: SimResourceContext, now: Long): Long { // If there is no work yet, mark the input as idle. if (activeOutputs.isEmpty()) { - return SimResourceCommand.Consume(0.0) + return Long.MAX_VALUE } val capacity = ctx.capacity @@ -196,14 +191,11 @@ public class SimResourceDistributorMaxMin( } this.totalRequestedSpeed = totalRequestedSpeed - this.totalAllocatedWork = totalAllocatedWork val totalAllocatedSpeed = capacity - availableSpeed this.totalAllocatedSpeed = totalAllocatedSpeed - return if (totalAllocatedWork > 0.0 && totalAllocatedSpeed > 0.0) - SimResourceCommand.Consume(totalAllocatedSpeed, duration) - else - SimResourceCommand.Consume(0.0, duration) + ctx.push(totalAllocatedSpeed) + return duration } private fun updateCapacity(ctx: SimResourceContext) { diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt index 68bedbd9..f12ef9f1 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt @@ -23,6 +23,7 @@ package org.opendc.simulator.resources import org.opendc.simulator.resources.impl.SimResourceCountersImpl +import java.time.Clock /** * A [SimResourceFlow] that transforms the resource commands emitted by the resource commands to the resource provider. @@ -32,13 +33,8 @@ import org.opendc.simulator.resources.impl.SimResourceCountersImpl */ public class SimResourceTransformer( private val isCoupled: Boolean = false, - private val transform: (SimResourceContext, SimResourceCommand) -> SimResourceCommand + private val transform: (SimResourceContext, Long) -> Long ) : SimResourceFlow, AutoCloseable { - /** - * The [SimResourceContext] in which the forwarder runs. - */ - private var ctx: SimResourceContext? = null - /** * The delegate [SimResourceConsumer]. */ @@ -49,17 +45,63 @@ public class SimResourceTransformer( */ private var hasDelegateStarted: Boolean = false + /** + * The exposed [SimResourceContext]. + */ + private val ctx = object : SimResourceContext { + override val clock: Clock + get() = _ctx!!.clock + + override val capacity: Double + get() = _ctx?.capacity ?: 0.0 + + override val demand: Double + get() = _ctx?.demand ?: 0.0 + + override val speed: Double + get() = _ctx?.speed ?: 0.0 + + override fun interrupt() { + _ctx?.interrupt() + } + + override fun push(rate: Double) { + _ctx?.push(rate) + _limit = rate + } + + override fun close() { + val delegate = checkNotNull(delegate) { "Delegate not active" } + + // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we + // reset beforehand the existing state and check whether it has been updated afterwards + reset() + + delegate.onEvent(this, SimResourceEvent.Exit) + + if (isCoupled) + _ctx?.close() + else + _ctx?.push(0.0) + } + } + + /** + * The [SimResourceContext] in which the forwarder runs. + */ + private var _ctx: SimResourceContext? = null + override val isActive: Boolean get() = delegate != null override val capacity: Double - get() = ctx?.capacity ?: 0.0 + get() = ctx.capacity override val speed: Double - get() = ctx?.speed ?: 0.0 + get() = ctx.speed override val demand: Double - get() = ctx?.demand ?: 0.0 + get() = ctx.demand override val counters: SimResourceCounters get() = _counters @@ -75,32 +117,32 @@ public class SimResourceTransformer( } override fun interrupt() { - ctx?.interrupt() + ctx.interrupt() } override fun cancel() { val delegate = delegate - val ctx = ctx + val ctx = _ctx if (delegate != null) { this.delegate = null if (ctx != null) { - delegate.onEvent(ctx, SimResourceEvent.Exit) + delegate.onEvent(this.ctx, SimResourceEvent.Exit) } } } override fun close() { - val ctx = ctx + val ctx = _ctx if (ctx != null) { - this.ctx = null + this._ctx = null ctx.interrupt() } } - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { val delegate = delegate if (!hasDelegateStarted) { @@ -110,54 +152,39 @@ public class SimResourceTransformer( updateCounters(ctx, delta) return if (delegate != null) { - val command = transform(ctx, delegate.onNext(ctx, now, delta)) - - _limit = if (command is SimResourceCommand.Consume) command.limit else 0.0 - - if (command == SimResourceCommand.Exit) { - // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we - // reset beforehand the existing state and check whether it has been updated afterwards - reset() - - delegate.onEvent(ctx, SimResourceEvent.Exit) - - if (isCoupled) - SimResourceCommand.Exit - else - onNext(ctx, now, delta) - } else { - command - } + val duration = transform(ctx, delegate.onNext(this.ctx, now, delta)) + _limit = ctx.demand + duration } else { - SimResourceCommand.Consume(0.0) + Long.MAX_VALUE } } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { when (event) { SimResourceEvent.Start -> { - this.ctx = ctx + _ctx = ctx } SimResourceEvent.Exit -> { - this.ctx = null + _ctx = null val delegate = delegate if (delegate != null) { reset() - delegate.onEvent(ctx, SimResourceEvent.Exit) + delegate.onEvent(this.ctx, SimResourceEvent.Exit) } } - else -> delegate?.onEvent(ctx, event) + else -> delegate?.onEvent(this.ctx, event) } } override fun onFailure(ctx: SimResourceContext, cause: Throwable) { - this.ctx = null + _ctx = null val delegate = delegate if (delegate != null) { reset() - delegate.onFailure(ctx, cause) + delegate.onFailure(this.ctx, cause) } } @@ -166,7 +193,7 @@ public class SimResourceTransformer( */ private fun start() { val delegate = delegate ?: return - delegate.onEvent(checkNotNull(ctx), SimResourceEvent.Start) + delegate.onEvent(checkNotNull(_ctx), SimResourceEvent.Start) hasDelegateStarted = true } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt index 1f8434b7..46885640 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.resources.consumer -import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext import org.opendc.simulator.resources.SimResourceEvent @@ -50,7 +49,7 @@ public class SimSpeedConsumerAdapter( callback(0.0) } - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { return delegate.onNext(ctx, now, delta) } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt index e5173e5f..ad6b0108 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.resources.consumer -import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext import org.opendc.simulator.resources.SimResourceEvent @@ -34,13 +33,15 @@ import org.opendc.simulator.resources.SimResourceEvent public class SimTraceConsumer(private val trace: Sequence) : SimResourceConsumer { private var iterator: Iterator? = null - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { val iterator = checkNotNull(iterator) return if (iterator.hasNext()) { val fragment = iterator.next() - SimResourceCommand.Consume(fragment.usage, fragment.duration) + ctx.push(fragment.usage) + fragment.duration } else { - SimResourceCommand.Exit + ctx.close() + Long.MAX_VALUE } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt index ae837043..bf76711f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.resources.consumer -import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext import kotlin.math.roundToLong @@ -37,12 +36,12 @@ public class SimWorkConsumer( init { require(work >= 0.0) { "Work must be positive" } - require(utilization > 0.0 && utilization <= 1.0) { "Utilization must be in (0, 1]" } + require(utilization > 0.0) { "Utilization must be positive" } } private var remainingWork = work - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { val actualWork = ctx.speed * delta / 1000.0 val limit = ctx.capacity * utilization @@ -52,9 +51,11 @@ public class SimWorkConsumer( val duration = (remainingWork / limit * 1000).roundToLong() return if (duration > 0) { - SimResourceCommand.Consume(limit, duration) + ctx.push(limit) + duration } else { - SimResourceCommand.Exit + ctx.close() + Long.MAX_VALUE } } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index a9507e52..d7ea0043 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -85,6 +85,11 @@ internal class SimResourceContextImpl( private var _duration: Long = Long.MAX_VALUE private var _deadline: Long = Long.MAX_VALUE + /** + * A flag to indicate that an update is active. + */ + private var _updateActive = false + /** * The update flag indicating why the update was triggered. */ @@ -108,7 +113,9 @@ internal class SimResourceContextImpl( if (_state != SimResourceState.Stopped) { interpreter.batch { _state = SimResourceState.Stopped - doStop() + if (!_updateActive) { + doStop() + } } } } @@ -139,6 +146,11 @@ internal class SimResourceContextImpl( interpreter.scheduleSync(this) } + override fun push(rate: Double) { + _speed = min(capacity, rate) + _limit = rate + } + /** * Determine whether the state of the resource context should be updated. */ @@ -151,14 +163,49 @@ internal class SimResourceContextImpl( * Update the state of the resource context. */ fun doUpdate(timestamp: Long) { + val oldState = _state + if (oldState != SimResourceState.Active) { + return + } + + _updateActive = true + + val flag = _flag + val isInterrupted = flag and FLAG_INTERRUPT != 0 + val reachedDeadline = _deadline <= timestamp + val delta = max(0, timestamp - _timestamp) + try { - val oldState = _state - val newState = doUpdate(timestamp, oldState) - _state = newState + // Update the resource counters only if there is some progress + if (timestamp > _timestamp) { + logic.onUpdate(this, delta, _limit, reachedDeadline) + } + + // We should only continue processing the next command if: + // 1. The resource consumption was finished. + // 2. The resource consumer should be interrupted (e.g., someone called .interrupt()) + val duration = if (reachedDeadline || isInterrupted) { + consumer.onNext(this, timestamp, delta) + } else { + _deadline - timestamp + } + + // Reset update flags _flag = 0 - when (newState) { + when (_state) { + SimResourceState.Active -> { + val limit = _limit + push(limit) + _duration = duration + + val target = logic.onConsume(this, timestamp, limit, duration) + + _deadline = target + + scheduleUpdate(target) + } SimResourceState.Pending -> if (oldState != SimResourceState.Pending) { throw IllegalStateException("Illegal transition to pending state") @@ -167,12 +214,12 @@ internal class SimResourceContextImpl( if (oldState != SimResourceState.Stopped) { doStop() } - else -> {} } } catch (cause: Throwable) { doFail(cause) } finally { _timestamp = timestamp + _updateActive = false } } @@ -184,39 +231,6 @@ internal class SimResourceContextImpl( override fun toString(): String = "SimResourceContextImpl[capacity=$capacity]" - /** - * Update the state of the resource context. - */ - private fun doUpdate(timestamp: Long, state: SimResourceState): SimResourceState { - return when (state) { - // Resource context is not active, so its state will not update - SimResourceState.Pending, SimResourceState.Stopped -> state - SimResourceState.Active -> { - val isInterrupted = _flag and FLAG_INTERRUPT != 0 - val reachedDeadline = _deadline <= timestamp - val delta = max(0, timestamp - _timestamp) - - // Update the resource counters only if there is some progress - if (timestamp > _timestamp) { - logic.onUpdate(this, delta, _limit, reachedDeadline) - } - - // We should only continue processing the next command if: - // 1. The resource consumption was finished. - // 2. The resource capacity cannot satisfy the demand. - // 3. The resource consumer should be interrupted (e.g., someone called .interrupt()) - if (reachedDeadline || isInterrupted) { - when (val command = consumer.onNext(this, timestamp, delta)) { - is SimResourceCommand.Consume -> interpretConsume(timestamp, command.limit, command.duration) - is SimResourceCommand.Exit -> interpretExit() - } - } else { - interpretConsume(timestamp, _limit, _duration - delta) - } - } - } - } - /** * Stop the resource context. */ @@ -226,6 +240,8 @@ internal class SimResourceContextImpl( logic.onFinish(this) } catch (cause: Throwable) { doFail(cause) + } finally { + _deadline = Long.MAX_VALUE } } @@ -243,35 +259,6 @@ internal class SimResourceContextImpl( logic.onFinish(this) } - /** - * Interpret the [SimResourceCommand.Consume] command. - */ - private fun interpretConsume(now: Long, limit: Double, duration: Long): SimResourceState { - _speed = min(capacity, limit) - _limit = limit - _duration = duration - - val timestamp = logic.onConsume(this, now, limit, duration) - - _deadline = timestamp - - scheduleUpdate(timestamp) - - return SimResourceState.Active - } - - /** - * Interpret the [SimResourceCommand.Exit] command. - */ - private fun interpretExit(): SimResourceState { - _speed = 0.0 - _limit = 0.0 - _duration = Long.MAX_VALUE - _deadline = Long.MAX_VALUE - - return SimResourceState.Stopped - } - /** * Indicate that the capacity of the resource has changed. */ diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt index a9390553..f4ea5fe8 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt @@ -22,14 +22,12 @@ package org.opendc.simulator.resources -import io.mockk.every -import io.mockk.mockk +import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.* import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll -import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter import org.opendc.simulator.resources.consumer.SimWorkConsumer @@ -100,10 +98,17 @@ internal class SimResourceAggregatorMaxMinTest { ) sources.forEach(aggregator::addInput) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(4.0, 1000)) - .andThen(SimResourceCommand.Exit) + val consumer = spyk(object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(4.0) + 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + }) aggregator.consume(consumer) yield() @@ -112,27 +117,6 @@ internal class SimResourceAggregatorMaxMinTest { verify(exactly = 2) { consumer.onNext(any(), any(), any()) } } - @Test - fun testException() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val sources = listOf( - SimResourceSource(1.0, scheduler), - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(1.0, duration = 1000)) - .andThenThrows(IllegalStateException("Test Exception")) - - assertThrows { aggregator.consume(consumer) } - yield() - assertFalse(sources[0].isActive) - } - @Test fun testAdjustCapacity() = runBlockingSimulation { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) @@ -186,10 +170,17 @@ internal class SimResourceAggregatorMaxMinTest { ) sources.forEach(aggregator::addInput) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(4.0, 1000)) - .andThen(SimResourceCommand.Exit) + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(4.0) + 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + } aggregator.consume(consumer) yield() diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt deleted file mode 100644 index 9a52dc63..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceCommandTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow -import org.junit.jupiter.api.assertThrows - -/** - * Test suite for [SimResourceCommand]. - */ -class SimResourceCommandTest { - @Test - fun testNegativeLimit() { - assertThrows { - SimResourceCommand.Consume(-1.0, 1) - } - } - - @Test - fun testNegativeDuration() { - assertThrows { - SimResourceCommand.Consume(1.0, -1) - } - } - - @Test - fun testConsumeCorrect() { - assertDoesNotThrow { - SimResourceCommand.Consume(1.0) - } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt index 0cb95abb..4e57f598 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt @@ -36,8 +36,17 @@ class SimResourceContextTest { @Test fun testFlushWithoutCommand() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(1.0) + 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + } val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) @@ -48,14 +57,23 @@ class SimResourceContextTest { @Test fun testIntermediateFlush() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(4.0) + 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + } val logic = spyk(object : SimResourceProviderLogic { override fun onFinish(ctx: SimResourceControllableContext) {} override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long = duration }) - val context = spyk(SimResourceContextImpl(null, interpreter, consumer, logic)) + val context = SimResourceContextImpl(null, interpreter, consumer, logic) context.start() delay(1) // Delay 1 ms to prevent hitting the fast path @@ -67,11 +85,20 @@ class SimResourceContextTest { @Test fun testIntermediateFlushIdle() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) andThen SimResourceCommand.Exit + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(0.0) + 10 + } else { + ctx.close() + Long.MAX_VALUE + } + } + } val logic = spyk(object : SimResourceProviderLogic {}) - val context = spyk(SimResourceContextImpl(null, interpreter, consumer, logic)) + val context = SimResourceContextImpl(null, interpreter, consumer, logic) context.start() delay(5) @@ -88,8 +115,17 @@ class SimResourceContextTest { @Test fun testDoubleStart() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) andThen SimResourceCommand.Exit + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(0.0) + 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + } val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) @@ -104,8 +140,17 @@ class SimResourceContextTest { @Test fun testIdempotentCapacityChange() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit + val consumer = spyk(object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (now == 0L) { + ctx.push(1.0) + 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + }) val logic = object : SimResourceProviderLogic {} @@ -120,12 +165,23 @@ class SimResourceContextTest { @Test fun testFailureNoInfiniteLoop() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Exit - every { consumer.onEvent(any(), SimResourceEvent.Exit) } throws IllegalStateException("onEvent") - every { consumer.onFailure(any(), any()) } throws IllegalStateException("onFailure") - val logic = spyk(object : SimResourceProviderLogic {}) + val consumer = spyk(object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + + override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + if (event == SimResourceEvent.Exit) throw IllegalStateException("onEvent") + } + + override fun onFailure(ctx: SimResourceContext, cause: Throwable) { + throw IllegalStateException("onFailure") + } + }) + + val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt index c310fad6..e055daf7 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt @@ -44,10 +44,7 @@ internal class SimResourceSourceTest { val capacity = 4200.0 val provider = SimResourceSource(capacity, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(capacity, duration = 1000)) - .andThen(SimResourceCommand.Exit) + val consumer = SimWorkConsumer(4200.0, 1.0) val res = mutableListOf() val adapter = SimSpeedConsumerAdapter(consumer, res::add) @@ -79,10 +76,7 @@ internal class SimResourceSourceTest { val capacity = 4200.0 val provider = SimResourceSource(capacity, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(2 * capacity, duration = 1000)) - .andThen(SimResourceCommand.Exit) + val consumer = SimWorkConsumer(capacity, 2.0) val res = mutableListOf() val adapter = SimSpeedConsumerAdapter(consumer, res::add) @@ -103,8 +97,9 @@ internal class SimResourceSourceTest { val provider = SimResourceSource(capacity, scheduler) val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { - return SimResourceCommand.Exit + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { @@ -132,12 +127,14 @@ internal class SimResourceSourceTest { } } - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { return if (isFirst) { isFirst = false - SimResourceCommand.Consume(1.0, duration = 4000) + ctx.push(1.0) + 4000 } else { - SimResourceCommand.Exit + ctx.close() + Long.MAX_VALUE } } } @@ -172,10 +169,19 @@ internal class SimResourceSourceTest { val capacity = 4200.0 val provider = SimResourceSource(capacity, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(1.0, duration = 1000)) - .andThenThrows(IllegalStateException()) + val consumer = object : SimResourceConsumer { + var isFirst = true + + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + ctx.push(1.0) + 1000 + } else { + throw IllegalStateException() + } + } + } assertThrows { provider.consume(consumer) @@ -188,10 +194,7 @@ internal class SimResourceSourceTest { val capacity = 4200.0 val provider = SimResourceSource(capacity, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(1.0)) - .andThenThrows(IllegalStateException()) + val consumer = SimWorkConsumer(capacity, 1.0) assertThrows { coroutineScope { @@ -207,30 +210,13 @@ internal class SimResourceSourceTest { val capacity = 4200.0 val provider = SimResourceSource(capacity, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(1.0)) - .andThenThrows(IllegalStateException()) + val consumer = SimWorkConsumer(capacity, 1.0) launch { provider.consume(consumer) } delay(500) provider.cancel() - assertEquals(500, clock.millis()) - } - - @Test - fun testIdle() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(0.0, 500)) - .andThen(SimResourceCommand.Exit) - - provider.consume(consumer) + yield() assertEquals(500, clock.millis()) } @@ -243,10 +229,9 @@ internal class SimResourceSourceTest { val capacity = 4200.0 val provider = SimResourceSource(capacity, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } - .returns(SimResourceCommand.Consume(0.0)) - .andThenThrows(IllegalStateException()) + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long = Long.MAX_VALUE + } provider.consume(consumer) } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt index ad3b0f9f..9f86dc0d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt @@ -22,8 +22,6 @@ package org.opendc.simulator.resources -import io.mockk.every -import io.mockk.mockk import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -32,6 +30,7 @@ import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter import org.opendc.simulator.resources.consumer.SimTraceConsumer +import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** @@ -88,8 +87,7 @@ internal class SimResourceSwitchExclusiveTest { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) val duration = 5 * 60L * 1000 - val workload = mockk(relaxUnitFun = true) - every { workload.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0, duration = duration) andThen SimResourceCommand.Exit + val workload = SimWorkConsumer(duration * 3.2, 1.0) val switch = SimResourceSwitchExclusive() val source = SimResourceSource(3200.0, scheduler) @@ -125,12 +123,14 @@ internal class SimResourceSwitchExclusiveTest { } } - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { return if (isFirst) { isFirst = false - SimResourceCommand.Consume(1.0, duration = duration) + ctx.push(1.0) + duration } else { - SimResourceCommand.Exit + ctx.close() + Long.MAX_VALUE } } } @@ -159,9 +159,6 @@ internal class SimResourceSwitchExclusiveTest { fun testConcurrentWorkloadFails() = runBlockingSimulation { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val workload = mockk(relaxUnitFun = true) - every { workload.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0) andThen SimResourceCommand.Exit - val switch = SimResourceSwitchExclusive() val source = SimResourceSource(3200.0, scheduler) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt index d8f18e65..ba0d66ff 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt @@ -22,8 +22,6 @@ package org.opendc.simulator.resources -import io.mockk.every -import io.mockk.mockk import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.yield @@ -31,6 +29,7 @@ import org.junit.jupiter.api.* import org.junit.jupiter.api.Assertions.assertEquals import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimTraceConsumer +import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl /** @@ -46,9 +45,7 @@ internal class SimResourceSwitchMaxMinTest { sources.forEach { switch.addInput(it) } val provider = switch.newOutput() - - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(1.0, duration = 1000) andThen SimResourceCommand.Exit + val consumer = SimWorkConsumer(2000.0, 1.0) try { provider.consume(consumer) diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt index 3780fd60..fc43c3da 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt @@ -22,8 +22,6 @@ package org.opendc.simulator.resources -import io.mockk.every -import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.* @@ -47,8 +45,9 @@ internal class SimResourceTransformerTest { launch { source.consume(forwarder) } forwarder.consume(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { - return SimResourceCommand.Exit + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE } }) @@ -67,12 +66,14 @@ internal class SimResourceTransformerTest { forwarder.consume(object : SimResourceConsumer { var isFirst = true - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { return if (isFirst) { isFirst = false - SimResourceCommand.Consume(1.0, duration = 10 * 1000L) + ctx.push(1.0) + 10 * 1000 } else { - SimResourceCommand.Exit + ctx.close() + Long.MAX_VALUE } } }) @@ -85,7 +86,10 @@ internal class SimResourceTransformerTest { fun testState() = runBlockingSimulation { val forwarder = SimResourceForwarder() val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): SimResourceCommand = SimResourceCommand.Exit + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } } assertFalse(forwarder.isActive) @@ -106,8 +110,12 @@ internal class SimResourceTransformerTest { fun testCancelPendingDelegate() = runBlockingSimulation { val forwarder = SimResourceForwarder() - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Exit + val consumer = spyk(object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + }) forwarder.startConsumer(consumer) forwarder.cancel() @@ -121,8 +129,7 @@ internal class SimResourceTransformerTest { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) val source = SimResourceSource(2000.0, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) + val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) source.startConsumer(forwarder) yield() @@ -140,8 +147,7 @@ internal class SimResourceTransformerTest { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) val source = SimResourceSource(2000.0, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Consume(0.0, 10) + val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) source.startConsumer(forwarder) yield() @@ -159,8 +165,12 @@ internal class SimResourceTransformerTest { val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) val source = SimResourceSource(2000.0, scheduler) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onNext(any(), any(), any()) } returns SimResourceCommand.Exit + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + } source.startConsumer(forwarder) forwarder.consume(consumer) @@ -190,7 +200,7 @@ internal class SimResourceTransformerTest { @Test fun testTransformExit() = runBlockingSimulation { - val forwarder = SimResourceTransformer { _, _ -> SimResourceCommand.Exit } + val forwarder = SimResourceTransformer { ctx, _ -> ctx.close(); Long.MAX_VALUE } val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) val source = SimResourceSource(1.0, scheduler) -- cgit v1.2.3 From 657deac134f7b9ee30ed7e2b7667e30f3b17f79f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 16:52:30 +0200 Subject: perf(simulator): Reduce memory allocations in SimResourceInterpreter This change removes unnecessary allocations in the SimResourceInterpreter caused by the way timers were allocated for the resource context. --- .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../resources/impl/SimResourceContextImpl.kt | 71 ++++---- .../resources/impl/SimResourceInterpreterImpl.kt | 199 +++++++++------------ .../simulator/resources/SimResourceContextTest.kt | 4 +- 4 files changed, 127 insertions(+), 149 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index ffc50ad8..04413db5 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -212,7 +212,7 @@ class CapelinIntegrationTest { { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(12027839, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(477664, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(475891, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index d7ea0043..9cbf849d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -24,6 +24,7 @@ package org.opendc.simulator.resources.impl import org.opendc.simulator.resources.* import java.time.Clock +import java.util.ArrayDeque import kotlin.math.max import kotlin.math.min @@ -96,9 +97,9 @@ internal class SimResourceContextImpl( private var _flag: Int = 0 /** - * The current pending update. + * The timers at which the context is scheduled to be interrupted. */ - private var _pendingUpdate: SimResourceInterpreterImpl.Update? = null + private val _timers: ArrayDeque = ArrayDeque() override fun start() { check(_state == SimResourceState.Pending) { "Consumer is already started" } @@ -126,7 +127,7 @@ internal class SimResourceContextImpl( } _flag = _flag or FLAG_INTERRUPT - scheduleUpdate() + scheduleUpdate(clock.millis()) } override fun invalidate() { @@ -135,7 +136,7 @@ internal class SimResourceContextImpl( } _flag = _flag or FLAG_INVALIDATE - scheduleUpdate() + scheduleUpdate(clock.millis()) } override fun flush() { @@ -143,7 +144,7 @@ internal class SimResourceContextImpl( return } - interpreter.scheduleSync(this) + interpreter.scheduleSync(clock.millis(), this) } override fun push(rate: Double) { @@ -154,9 +155,9 @@ internal class SimResourceContextImpl( /** * Determine whether the state of the resource context should be updated. */ - fun requiresUpdate(timestamp: Long): Boolean { + fun shouldUpdate(timestamp: Long): Boolean { // Either the resource context is flagged or there is a pending update at this timestamp - return _flag != 0 || _pendingUpdate?.timestamp == timestamp + return _flag != 0 || _deadline == timestamp } /** @@ -204,7 +205,7 @@ internal class SimResourceContextImpl( _deadline = target - scheduleUpdate(target) + scheduleUpdate(timestamp, target) } SimResourceState.Pending -> if (oldState != SimResourceState.Pending) { @@ -229,6 +230,30 @@ internal class SimResourceContextImpl( } } + /** + * Prune the elapsed timers from this context. + */ + fun pruneTimers(now: Long) { + val timers = _timers + while (true) { + val head = timers.peek() + if (head == null || head.target > now) { + break + } + timers.poll() + } + } + + /** + * Try to re-schedule the resource context in case it was skipped. + */ + fun tryReschedule(now: Long) { + val deadline = _deadline + if (deadline > now && deadline != Long.MAX_VALUE) { + scheduleUpdate(now, deadline) + } + } + override fun toString(): String = "SimResourceContextImpl[capacity=$capacity]" /** @@ -279,35 +304,17 @@ internal class SimResourceContextImpl( /** * Schedule an update for this resource context. */ - private fun scheduleUpdate() { - // Cancel the pending update - val pendingUpdate = _pendingUpdate - if (pendingUpdate != null) { - _pendingUpdate = null - pendingUpdate.cancel() - } - - interpreter.scheduleImmediate(this) + private fun scheduleUpdate(now: Long) { + interpreter.scheduleImmediate(now, this) } /** * Schedule a delayed update for this resource context. */ - private fun scheduleUpdate(timestamp: Long) { - val pendingUpdate = _pendingUpdate - if (pendingUpdate != null) { - if (pendingUpdate.timestamp == timestamp) { - // Fast-path: A pending update for the same timestamp already exists - return - } else { - // Cancel the old pending update - _pendingUpdate = null - pendingUpdate.cancel() - } - } - - if (timestamp != Long.MAX_VALUE) { - _pendingUpdate = interpreter.scheduleDelayed(this, timestamp) + private fun scheduleUpdate(now: Long, target: Long) { + val timers = _timers + if (target != Long.MAX_VALUE && (timers.isEmpty() || target < timers.peek().target)) { + timers.addFirst(interpreter.scheduleDelayed(now, this, target)) } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt index c3dcebd0..2b6ec2ba 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt @@ -53,7 +53,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, /** * A priority queue containing the resource updates to be scheduled in the future. */ - private val futureQueue = PriorityQueue(compareBy { it.timestamp }) + private val futureQueue = PriorityQueue() /** * The stack of interpreter invocations to occur in the future. @@ -77,13 +77,14 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, get() = batchIndex > 0 /** - * Enqueue the specified [ctx] to be updated immediately during the active interpreter cycle. - * - * This method should be used when the state of a resource context is invalidated/interrupted and needs to be - * re-computed. In case no interpreter is currently active, the interpreter will be started. + * Update the specified [ctx] synchronously. */ - fun scheduleImmediate(ctx: SimResourceContextImpl) { - queue.add(ctx) + fun scheduleSync(now: Long, ctx: SimResourceContextImpl) { + ctx.doUpdate(now) + + if (visited.add(ctx)) { + collectAncestors(ctx, visited) + } // In-case the interpreter is already running in the call-stack, return immediately. The changes will be picked // up by the active interpreter. @@ -93,21 +94,20 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, try { batchIndex++ - runInterpreter() + runInterpreter(now) } finally { batchIndex-- } } /** - * Update the specified [ctx] synchronously. + * Enqueue the specified [ctx] to be updated immediately during the active interpreter cycle. + * + * This method should be used when the state of a resource context is invalidated/interrupted and needs to be + * re-computed. In case no interpreter is currently active, the interpreter will be started. */ - fun scheduleSync(ctx: SimResourceContextImpl) { - ctx.doUpdate(clock.millis()) - - if (visited.add(ctx)) { - collectAncestors(ctx, visited) - } + fun scheduleImmediate(now: Long, ctx: SimResourceContextImpl) { + queue.add(ctx) // In-case the interpreter is already running in the call-stack, return immediately. The changes will be picked // up by the active interpreter. @@ -117,35 +117,30 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, try { batchIndex++ - runInterpreter() + runInterpreter(now) } finally { batchIndex-- } } /** - * Schedule the interpreter to run at [timestamp] to update the resource contexts. + * Schedule the interpreter to run at [target] to update the resource contexts. * * This method will override earlier calls to this method for the same [ctx]. * + * @param now The current virtual timestamp. * @param ctx The resource context to which the event applies. - * @param timestamp The timestamp when the interrupt should happen. + * @param target The timestamp when the interrupt should happen. */ - fun scheduleDelayed(ctx: SimResourceContextImpl, timestamp: Long): Update { - val now = clock.millis() + fun scheduleDelayed(now: Long, ctx: SimResourceContextImpl, target: Long): Timer { val futureQueue = futureQueue - require(timestamp >= now) { "Timestamp must be in the future" } + require(target >= now) { "Timestamp must be in the future" } - val update = allocUpdate(ctx, timestamp) - futureQueue.add(update) + val timer = Timer(ctx, target) + futureQueue.add(timer) - // Optimization: Check if we need to push the interruption forward. Note that we check by timer reference. - if (futureQueue.peek() === update) { - trySchedule(futureQueue, futureInvocations) - } - - return update + return timer } override fun newContext( @@ -162,7 +157,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, try { // Flush the work if the platform is not already running if (batchIndex == 1 && queue.isNotEmpty()) { - runInterpreter() + runInterpreter(clock.millis()) } } finally { batchIndex-- @@ -172,37 +167,46 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, /** * Interpret all actions that are scheduled for the current timestamp. */ - private fun runInterpreter() { - val now = clock.millis() + private fun runInterpreter(now: Long) { val queue = queue val futureQueue = futureQueue val futureInvocations = futureInvocations val visited = visited + // Remove any entries in the `futureInvocations` queue from the past + while (true) { + val head = futureInvocations.peek() + if (head == null || head.timestamp > now) { + break + } + futureInvocations.poll() + } + // Execute all scheduled updates at current timestamp while (true) { - val update = futureQueue.peek() ?: break + val timer = futureQueue.peek() ?: break + val ctx = timer.ctx + val target = timer.target - assert(update.timestamp >= now) { "Internal inconsistency: found update of the past" } + assert(target >= now) { "Internal inconsistency: found update of the past" } - if (update.timestamp > now && !update.isCancelled) { - // Schedule a task for the next event to occur. - trySchedule(futureQueue, futureInvocations) + if (target > now) { break } futureQueue.poll() - val shouldExecute = !update.isCancelled && update.ctx.requiresUpdate(now) - if (shouldExecute) { - update.ctx.doUpdate(now) + ctx.pruneTimers(now) - if (visited.add(update.ctx)) { - collectAncestors(update.ctx, visited) + if (ctx.shouldUpdate(now)) { + ctx.doUpdate(now) + + if (visited.add(ctx)) { + collectAncestors(ctx, visited) } + } else { + ctx.tryReschedule(now) } - - updatePool.add(update) } // Repeat execution of all immediate updates until the system has converged to a steady-state @@ -211,9 +215,8 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, // Execute all immediate updates while (true) { val ctx = queue.poll() ?: break - val shouldExecute = ctx.requiresUpdate(now) - if (shouldExecute) { + if (ctx.shouldUpdate(now)) { ctx.doUpdate(now) if (visited.add(ctx)) { @@ -228,88 +231,65 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, visited.clear() } while (queue.isNotEmpty()) + + // Schedule an interpreter invocation for the next update to occur. + val headTimer = futureQueue.peek() + if (headTimer != null) { + trySchedule(now, futureInvocations, headTimer.target) + } } /** - * Try to schedule the next interpreter event. + * Collect all the ancestors of the specified [system]. */ - private fun trySchedule(queue: PriorityQueue, scheduled: ArrayDeque) { - val nextTimer = queue.peek() - val now = clock.millis() - - // Check whether we need to update our schedule: - if (nextTimer == null) { - // Case 1: all timers are cancelled - for (invocation in scheduled) { - invocation.cancel() - } - scheduled.clear() - return + private tailrec fun collectAncestors(system: SimResourceSystem, systems: MutableSet) { + val parent = system.parent + if (parent != null) { + systems.add(parent) + collectAncestors(parent, systems) } + } + /** + * Try to schedule an interpreter invocation at the specified [target]. + * + * @param now The current virtual timestamp. + * @param target The virtual timestamp at which the interpreter invocation should happen. + * @param scheduled The queue of scheduled invocations. + */ + private fun trySchedule(now: Long, scheduled: ArrayDeque, target: Long) { while (true) { val invocation = scheduled.peekFirst() - if (invocation == null || invocation.timestamp > nextTimer.timestamp) { + if (invocation == null || invocation.timestamp > target) { // Case 2: A new timer was registered ahead of the other timers. // Solution: Schedule a new scheduler invocation - val nextTimestamp = nextTimer.timestamp @OptIn(InternalCoroutinesApi::class) val handle = delay.invokeOnTimeout( - nextTimestamp - now, + target - now, { try { batchIndex++ - runInterpreter() + runInterpreter(target) } finally { batchIndex-- } }, context ) - scheduled.addFirst(Invocation(nextTimestamp, handle)) + scheduled.addFirst(Invocation(target, handle)) break - } else if (invocation.timestamp < nextTimer.timestamp) { + } else if (invocation.timestamp < target) { // Case 2: A timer was cancelled and the head of the timer queue is now later than excepted // Solution: Cancel the next scheduler invocation - invocation.cancel() scheduled.pollFirst() + + invocation.cancel() } else { break } } } - /** - * Collect all the ancestors of the specified [system]. - */ - private tailrec fun collectAncestors(system: SimResourceSystem, systems: MutableSet) { - val parent = system.parent - if (parent != null) { - systems.add(parent) - collectAncestors(parent, systems) - } - } - - /** - * The pool of existing updates. - */ - private val updatePool = ArrayDeque() - - /** - * Allocate an [Update] object. - */ - private fun allocUpdate(ctx: SimResourceContextImpl, timestamp: Long): Update { - val update = updatePool.poll() - return if (update != null) { - update.ctx = ctx - update.timestamp = timestamp - update.isCancelled = false - update - } else { - Update(ctx, timestamp) - } - } - /** * A future interpreter invocation. * @@ -318,34 +298,25 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, */ private data class Invocation( @JvmField val timestamp: Long, - private val disposableHandle: DisposableHandle + @JvmField val handle: DisposableHandle ) { /** * Cancel the interpreter invocation. */ - fun cancel() = disposableHandle.dispose() + fun cancel() = handle.dispose() } /** - * An update call for [ctx] that is scheduled for [timestamp]. + * An update call for [ctx] that is scheduled for [target]. * - * This class represents an update in the future at [timestamp] requested by [ctx]. A deferred update might be + * This class represents an update in the future at [target] requested by [ctx]. A deferred update might be * cancelled if the resource context was invalidated in the meantime. */ - class Update(@JvmField var ctx: SimResourceContextImpl, @JvmField var timestamp: Long) { - /** - * A flag to indicate that the task has been cancelled. - */ - @JvmField - var isCancelled: Boolean = false - - /** - * Cancel the update. - */ - fun cancel() { - isCancelled = true + class Timer(@JvmField val ctx: SimResourceContextImpl, @JvmField val target: Long) : Comparable { + override fun compareTo(other: Timer): Int { + return target.compareTo(other.target) } - override fun toString(): String = "Update[ctx=$ctx,timestamp=$timestamp]" + override fun toString(): String = "Timer[ctx=$ctx,timestamp=$target]" } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt index 4e57f598..e95e9e42 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt @@ -51,7 +51,7 @@ class SimResourceContextTest { val logic = object : SimResourceProviderLogic {} val context = SimResourceContextImpl(null, interpreter, consumer, logic) - context.doUpdate(interpreter.clock.millis()) + interpreter.scheduleSync(interpreter.clock.millis(), context) } @Test @@ -77,7 +77,7 @@ class SimResourceContextTest { context.start() delay(1) // Delay 1 ms to prevent hitting the fast path - context.doUpdate(interpreter.clock.millis()) + interpreter.scheduleSync(interpreter.clock.millis(), context) verify(exactly = 2) { logic.onConsume(any(), any(), any(), any()) } } -- cgit v1.2.3 From d3b0b551362eb677c12047cba82a6279ea4608b4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 17:06:45 +0200 Subject: refactor(simulator): Simplify max-min aggregator implementation This change simplifies the implementation of the SimResourceAggregatorMaxMin class by utilizing the new push method. This approach should offer better performance than the previous version, since we can directly push changes to the source. --- .../resources/SimAbstractResourceAggregator.kt | 81 +++------------------- .../resources/SimResourceAggregatorMaxMin.kt | 15 ++-- 2 files changed, 16 insertions(+), 80 deletions(-) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt index 8e0eb5f8..d064d7fa 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt @@ -32,7 +32,7 @@ public abstract class SimAbstractResourceAggregator( /** * This method is invoked when the resource consumer consumes resources. */ - protected abstract fun doConsume(limit: Double, duration: Long) + protected abstract fun doConsume(limit: Double) /** * This method is invoked when the resource consumer finishes processing. @@ -42,12 +42,12 @@ public abstract class SimAbstractResourceAggregator( /** * This method is invoked when an input context is started. */ - protected abstract fun onInputStarted(input: Input) + protected abstract fun onInputStarted(input: SimResourceContext) /** * This method is invoked when an input is stopped. */ - protected abstract fun onInputFinished(input: Input) + protected abstract fun onInputFinished(input: SimResourceContext) /* SimResourceAggregator */ override fun addInput(input: SimResourceProvider) { @@ -95,7 +95,7 @@ public abstract class SimAbstractResourceAggregator( return object : SimResourceProviderLogic { override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { - doConsume(limit, duration) + doConsume(limit) return super.onConsume(ctx, now, limit, duration) } @@ -113,90 +113,25 @@ public abstract class SimAbstractResourceAggregator( } } } - - /** - * Flush the progress of the output if possible. - */ - fun flush() { - ctx?.flush() - } - } - - /** - * An input for the resource aggregator. - */ - public interface Input : AutoCloseable { - /** - * The [SimResourceContext] associated with the input. - */ - public val ctx: SimResourceContext - - /** - * Push to this input with the specified [limit] and [duration]. - */ - public fun push(limit: Double, duration: Long) - - /** - * Close the input for further input. - */ - public override fun close() } /** * An internal [SimResourceConsumer] implementation for aggregator inputs. */ - private inner class Consumer : Input, SimResourceConsumer { + private inner class Consumer : SimResourceConsumer { /** * The resource context associated with the input. */ - override val ctx: SimResourceContext - get() = _ctx!! private var _ctx: SimResourceContext? = null - /** - * The resource command to run next. - */ - private var _duration: Long = Long.MAX_VALUE - - /** - * A flag to indicate that the consumer should flush. - */ - private var _isPushed = false - private fun updateCapacity() { // Adjust capacity of output resource _output.capacity = _inputConsumers.sumOf { it._ctx?.capacity ?: 0.0 } } - /* Input */ - override fun push(limit: Double, duration: Long) { - _duration = duration - val ctx = _ctx - if (ctx != null) { - ctx.push(limit) - ctx.interrupt() - } - _isPushed = true - } - - override fun close() { - _duration = Long.MAX_VALUE - _isPushed = true - _ctx?.close() - } - /* SimResourceConsumer */ override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - var next = _duration - - if (!_isPushed) { - _output.flush() - next = _duration - } - - _isPushed = false - _duration = Long.MAX_VALUE - return next + return Long.MAX_VALUE } override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { @@ -205,10 +140,10 @@ public abstract class SimAbstractResourceAggregator( _ctx = ctx updateCapacity() - onInputStarted(this) + onInputStarted(ctx) } SimResourceEvent.Capacity -> updateCapacity() - SimResourceEvent.Exit -> onInputFinished(this) + SimResourceEvent.Exit -> onInputFinished(ctx) else -> {} } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt index b258a368..f131ac6c 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt @@ -29,19 +29,20 @@ public class SimResourceAggregatorMaxMin( interpreter: SimResourceInterpreter, parent: SimResourceSystem? = null ) : SimAbstractResourceAggregator(interpreter, parent) { - private val consumers = mutableListOf() + private val consumers = mutableListOf() - override fun doConsume(limit: Double, duration: Long) { + override fun doConsume(limit: Double) { // Sort all consumers by their capacity - consumers.sortWith(compareBy { it.ctx.capacity }) + consumers.sortWith(compareBy { it.capacity }) // Divide the requests over the available capacity of the input resources fairly for (input in consumers) { - val inputCapacity = input.ctx.capacity + val inputCapacity = input.capacity val fraction = inputCapacity / capacity val grantedSpeed = limit * fraction - input.push(grantedSpeed, duration) + input.push(grantedSpeed) + input.interrupt() } } @@ -53,11 +54,11 @@ public class SimResourceAggregatorMaxMin( } } - override fun onInputStarted(input: Input) { + override fun onInputStarted(input: SimResourceContext) { consumers.add(input) } - override fun onInputFinished(input: Input) { + override fun onInputFinished(input: SimResourceContext) { consumers.remove(input) } } -- cgit v1.2.3 From d031a70f8bea02a86df7840c5ce731185df86883 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 28 Sep 2021 22:10:12 +0200 Subject: refactor(simulator): Invoke consumer callback on every invalidation This change updates the simulator implementation to always invoke the `SimResourceConsumer.onNext` callback when the resource context is invalidated. This allows users to update the resource counter or do some other work if the context has changed. --- .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../resources/consumer/SimTraceConsumer.kt | 18 ++++++++--- .../resources/impl/SimResourceContextImpl.kt | 36 +++++++++------------- .../simulator/resources/SimResourceContextTest.kt | 33 +++++--------------- 4 files changed, 36 insertions(+), 53 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 04413db5..12336308 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -212,7 +212,7 @@ class CapelinIntegrationTest { { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(12027839, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(475891, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(476163, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt index ad6b0108..4c0e075c 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt @@ -31,12 +31,20 @@ import org.opendc.simulator.resources.SimResourceEvent * consumption for some period of time. */ public class SimTraceConsumer(private val trace: Sequence) : SimResourceConsumer { - private var iterator: Iterator? = null + private var _iterator: Iterator? = null + private var _nextTarget = Long.MIN_VALUE override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val iterator = checkNotNull(iterator) + // Check whether the trace fragment was fully consumed, otherwise wait until we have done so + val nextTarget = _nextTarget + if (nextTarget > now) { + return now - nextTarget + } + + val iterator = checkNotNull(_iterator) return if (iterator.hasNext()) { val fragment = iterator.next() + _nextTarget = now + fragment.duration ctx.push(fragment.usage) fragment.duration } else { @@ -48,11 +56,11 @@ public class SimTraceConsumer(private val trace: Sequence) : SimResour override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { when (event) { SimResourceEvent.Start -> { - check(iterator == null) { "Consumer already running" } - iterator = trace.iterator() + check(_iterator == null) { "Consumer already running" } + _iterator = trace.iterator() } SimResourceEvent.Exit -> { - iterator = null + _iterator = null } else -> {} } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index 9cbf849d..1ac38946 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -148,6 +148,10 @@ internal class SimResourceContextImpl( } override fun push(rate: Double) { + if (_limit == rate) { + return + } + _speed = min(capacity, rate) _limit = rate } @@ -163,7 +167,7 @@ internal class SimResourceContextImpl( /** * Update the state of the resource context. */ - fun doUpdate(timestamp: Long) { + fun doUpdate(now: Long) { val oldState = _state if (oldState != SimResourceState.Active) { return @@ -171,41 +175,29 @@ internal class SimResourceContextImpl( _updateActive = true - val flag = _flag - val isInterrupted = flag and FLAG_INTERRUPT != 0 - val reachedDeadline = _deadline <= timestamp - val delta = max(0, timestamp - _timestamp) + val reachedDeadline = _deadline <= now + val delta = max(0, now - _timestamp) try { - // Update the resource counters only if there is some progress - if (timestamp > _timestamp) { + if (now > _timestamp) { logic.onUpdate(this, delta, _limit, reachedDeadline) } - // We should only continue processing the next command if: - // 1. The resource consumption was finished. - // 2. The resource consumer should be interrupted (e.g., someone called .interrupt()) - val duration = if (reachedDeadline || isInterrupted) { - consumer.onNext(this, timestamp, delta) - } else { - _deadline - timestamp - } + val duration = consumer.onNext(this, now, delta) // Reset update flags _flag = 0 when (_state) { SimResourceState.Active -> { - val limit = _limit - push(limit) - _duration = duration - - val target = logic.onConsume(this, timestamp, limit, duration) + val target = logic.onConsume(this, now, _limit, duration) + _speed = min(capacity, _limit) + _duration = duration _deadline = target - scheduleUpdate(timestamp, target) + scheduleUpdate(now, target) } SimResourceState.Pending -> if (oldState != SimResourceState.Pending) { @@ -219,7 +211,7 @@ internal class SimResourceContextImpl( } catch (cause: Throwable) { doFail(cause) } finally { - _timestamp = timestamp + _timestamp = now _updateActive = false } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt index e95e9e42..c7230a0e 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt @@ -26,6 +26,7 @@ import io.mockk.* import kotlinx.coroutines.* import org.junit.jupiter.api.* import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.simulator.resources.impl.SimResourceContextImpl import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl @@ -57,23 +58,14 @@ class SimResourceContextTest { @Test fun testIntermediateFlush() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(4.0) - 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - } + val consumer = SimWorkConsumer(1.0, 1.0) val logic = spyk(object : SimResourceProviderLogic { override fun onFinish(ctx: SimResourceControllableContext) {} override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long = duration }) val context = SimResourceContextImpl(null, interpreter, consumer, logic) + context.capacity = 1.0 context.start() delay(1) // Delay 1 ms to prevent hitting the fast path @@ -85,29 +77,20 @@ class SimResourceContextTest { @Test fun testIntermediateFlushIdle() = runBlockingSimulation { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(0.0) - 10 - } else { - ctx.close() - Long.MAX_VALUE - } - } - } + val consumer = SimWorkConsumer(1.0, 1.0) val logic = spyk(object : SimResourceProviderLogic {}) val context = SimResourceContextImpl(null, interpreter, consumer, logic) + context.capacity = 1.0 context.start() - delay(5) + delay(500) context.invalidate() - delay(5) + delay(500) context.invalidate() assertAll( - { verify(exactly = 2) { logic.onConsume(any(), any(), 0.0, any()) } }, + { verify(exactly = 2) { logic.onConsume(any(), any(), any(), any()) } }, { verify(exactly = 1) { logic.onFinish(any()) } } ) } -- cgit v1.2.3 From 15899c88d29c039149f701e7f0d538a49a436599 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 10:33:36 +0200 Subject: refactor(simulator): Lazily push changes to resource context This change updates the SimResourceContextImpl to lazily push changes to the resource context instead of applying them directly. The change is picked up after the resource is updated again. --- .../simulator/resources/SimResourceTransformer.kt | 4 +- .../resources/impl/SimResourceContextImpl.kt | 58 ++++++++++++---------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt index f12ef9f1..a317f832 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt @@ -152,9 +152,7 @@ public class SimResourceTransformer( updateCounters(ctx, delta) return if (delegate != null) { - val duration = transform(ctx, delegate.onNext(this.ctx, now, delta)) - _limit = ctx.demand - duration + transform(ctx, delegate.onNext(this.ctx, now, delta)) } else { Long.MAX_VALUE } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index 1ac38946..78d79434 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -69,8 +69,8 @@ internal class SimResourceContextImpl( * The current processing speed of the resource. */ override val speed: Double - get() = _speed - private var _speed = 0.0 + get() = _rate + private var _rate = 0.0 /** * The current resource processing demand. @@ -81,10 +81,10 @@ internal class SimResourceContextImpl( /** * The current state of the resource context. */ - private var _timestamp: Long = Long.MIN_VALUE private var _limit: Double = 0.0 - private var _duration: Long = Long.MAX_VALUE - private var _deadline: Long = Long.MAX_VALUE + private var _activeLimit: Double = 0.0 + private var _deadline: Long = Long.MIN_VALUE + private var _lastUpdate: Long = Long.MIN_VALUE /** * A flag to indicate that an update is active. @@ -152,8 +152,13 @@ internal class SimResourceContextImpl( return } - _speed = min(capacity, rate) _limit = rate + + // Invalidate only if the active limit is change and no update is active + // If an update is active, it will already get picked up at the end of the update + if (_activeLimit != rate && !_updateActive) { + invalidate() + } } /** @@ -173,45 +178,47 @@ internal class SimResourceContextImpl( return } + val lastUpdate = _lastUpdate + _lastUpdate = now _updateActive = true val reachedDeadline = _deadline <= now - val delta = max(0, now - _timestamp) + val delta = max(0, now - lastUpdate) try { // Update the resource counters only if there is some progress - if (now > _timestamp) { - logic.onUpdate(this, delta, _limit, reachedDeadline) + if (now > lastUpdate) { + logic.onUpdate(this, delta, _activeLimit, reachedDeadline) } val duration = consumer.onNext(this, now, delta) + val newDeadline = if (duration != Long.MAX_VALUE) now + duration else duration // Reset update flags _flag = 0 + // Check whether the state has changed after [consumer.onNext] when (_state) { SimResourceState.Active -> { - val target = logic.onConsume(this, now, _limit, duration) - - _speed = min(capacity, _limit) - _duration = duration - _deadline = target + logic.onConsume(this, now, _limit, duration) - scheduleUpdate(now, target) + // Schedule an update at the new deadline + scheduleUpdate(now, newDeadline) } - SimResourceState.Pending -> - if (oldState != SimResourceState.Pending) { - throw IllegalStateException("Illegal transition to pending state") - } - SimResourceState.Stopped -> - if (oldState != SimResourceState.Stopped) { - doStop() - } + SimResourceState.Stopped -> doStop() + SimResourceState.Pending -> throw IllegalStateException("Illegal transition to pending state") } + + // Note: pending limit might be changed by [logic.onConsume], so re-fetch the value + val newLimit = _limit + + // Flush the changes to the flow + _activeLimit = newLimit + _deadline = newDeadline + _rate = min(capacity, newLimit) } catch (cause: Throwable) { doFail(cause) } finally { - _timestamp = now _updateActive = false } } @@ -246,7 +253,7 @@ internal class SimResourceContextImpl( } } - override fun toString(): String = "SimResourceContextImpl[capacity=$capacity]" + override fun toString(): String = "SimResourceContextImpl[capacity=$capacity,rate=$_rate]" /** * Stop the resource context. @@ -259,6 +266,7 @@ internal class SimResourceContextImpl( doFail(cause) } finally { _deadline = Long.MAX_VALUE + _limit = 0.0 } } -- cgit v1.2.3 From e07a5357013b92377a840b4d0d394d0ef6605b26 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 27 Sep 2021 14:22:02 +0200 Subject: refactor(simulator): Remove onUpdate callback This change removes the `onUpdate` callback from the `SimResourceProviderLogic` interface. Instead, users should now update counters using either `onConsume` or `onConverge`. --- .../experiments/capelin/CapelinIntegrationTest.kt | 8 +- .../resources/SimAbstractResourceAggregator.kt | 18 +-- .../resources/SimAbstractResourceProvider.kt | 22 +-- .../resources/SimResourceDistributorMaxMin.kt | 148 +++++++++++---------- .../simulator/resources/SimResourceInterpreter.kt | 7 +- .../resources/SimResourceProviderLogic.kt | 25 ++-- .../simulator/resources/SimResourceSource.kt | 16 ++- .../simulator/resources/SimResourceTransformer.kt | 14 +- .../resources/impl/SimResourceContextImpl.kt | 79 ++++++----- .../resources/impl/SimResourceInterpreterImpl.kt | 34 +---- .../simulator/resources/SimResourceContextTest.kt | 24 ++-- .../resources/SimResourceTransformerTest.kt | 3 + 12 files changed, 201 insertions(+), 197 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 12336308..16085d82 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -118,7 +118,7 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, { assertEquals(223331032, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, { assertEquals(67006568, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, - { assertEquals(3088047, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, + { assertEquals(3159379, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Incorrect lost time" } }, { assertEquals(5.841120890240688E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, ) @@ -211,7 +211,7 @@ class CapelinIntegrationTest { assertAll( { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, - { assertEquals(12027839, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(476163, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } @@ -252,8 +252,8 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(11134319, exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(9604081, exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(11132222, exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9606178, exporter.activeTime) { "Active time incorrect" } }, { assertEquals(0, exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(0, exporter.lostTime) { "Lost time incorrect" } }, { assertEquals(2559005056, exporter.uptime) { "Uptime incorrect" } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt index d064d7fa..621ea6e7 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt @@ -90,26 +90,22 @@ public abstract class SimAbstractResourceAggregator( _output.interrupt() } - private val _output = object : SimAbstractResourceProvider(interpreter, parent, initialCapacity = 0.0) { + private val _output = object : SimAbstractResourceProvider(interpreter, initialCapacity = 0.0) { override fun createLogic(): SimResourceProviderLogic { return object : SimResourceProviderLogic { - override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { + override fun onConsume(ctx: SimResourceControllableContext, now: Long, delta: Long, limit: Double, duration: Long) { + updateCounters(ctx, delta) doConsume(limit) - return super.onConsume(ctx, now, limit, duration) } - override fun onFinish(ctx: SimResourceControllableContext) { + override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { + updateCounters(ctx, delta) doFinish() } - override fun onUpdate( - ctx: SimResourceControllableContext, - delta: Long, - limit: Double, - willOvercommit: Boolean - ) { - updateCounters(ctx, delta, limit, willOvercommit) + override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { + parent?.onConverge(now) } } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt index 548bc228..085cba63 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt @@ -29,7 +29,6 @@ import org.opendc.simulator.resources.impl.SimResourceCountersImpl */ public abstract class SimAbstractResourceProvider( private val interpreter: SimResourceInterpreter, - private val parent: SimResourceSystem?, initialCapacity: Double ) : SimResourceProvider { /** @@ -84,26 +83,31 @@ public abstract class SimAbstractResourceProvider( ctx.start() } + /** + * The previous demand for the resource. + */ + private var previousDemand = 0.0 + /** * Update the counters of the resource provider. */ - protected fun updateCounters(ctx: SimResourceContext, delta: Long, limit: Double, willOvercommit: Boolean) { - if (delta <= 0.0) { + protected fun updateCounters(ctx: SimResourceContext, delta: Long) { + val demand = previousDemand + previousDemand = ctx.demand + + if (delta <= 0) { return } val counters = _counters val deltaS = delta / 1000.0 - val work = limit * deltaS + val work = demand * deltaS val actualWork = ctx.speed * deltaS val remainingWork = work - actualWork counters.demand += work counters.actual += actualWork - - if (willOvercommit && remainingWork > 0.0) { - counters.overcommit += remainingWork - } + counters.overcommit += remainingWork } /** @@ -118,7 +122,7 @@ public abstract class SimAbstractResourceProvider( final override fun startConsumer(consumer: SimResourceConsumer) { check(ctx == null) { "Resource is in invalid state" } - val ctx = interpreter.newContext(consumer, createLogic(), parent) + val ctx = interpreter.newContext(consumer, createLogic()) ctx.capacity = capacity this.ctx = ctx diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt index eac58410..7df940ad 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt @@ -93,46 +93,6 @@ public class SimResourceDistributorMaxMin( /* SimResourceConsumer */ override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return doNext(ctx, now) - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - this.ctx = ctx - updateCapacity(ctx) - } - SimResourceEvent.Exit -> { - val iterator = _outputs.iterator() - while (iterator.hasNext()) { - val output = iterator.next() - - // Remove the output from the outputs to prevent ConcurrentModificationException when removing it - // during the call to output.close() - iterator.remove() - - output.close() - } - } - SimResourceEvent.Capacity -> updateCapacity(ctx) - else -> {} - } - } - - /** - * Extended [SimResourceCounters] interface for the distributor. - */ - public interface Counters : SimResourceCounters { - /** - * The amount of work lost due to interference. - */ - public val interference: Double - } - - /** - * Schedule the work of the outputs. - */ - private fun doNext(ctx: SimResourceContext, now: Long): Long { // If there is no work yet, mark the input as idle. if (activeOutputs.isEmpty()) { return Long.MAX_VALUE @@ -198,6 +158,39 @@ public class SimResourceDistributorMaxMin( return duration } + override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + when (event) { + SimResourceEvent.Start -> { + this.ctx = ctx + updateCapacity(ctx) + } + SimResourceEvent.Exit -> { + val iterator = _outputs.iterator() + while (iterator.hasNext()) { + val output = iterator.next() + + // Remove the output from the outputs to prevent ConcurrentModificationException when removing it + // during the call to output.close() + iterator.remove() + + output.close() + } + } + SimResourceEvent.Capacity -> updateCapacity(ctx) + else -> {} + } + } + + /** + * Extended [SimResourceCounters] interface for the distributor. + */ + public interface Counters : SimResourceCounters { + /** + * The amount of work lost due to interference. + */ + public val interference: Double + } + private fun updateCapacity(ctx: SimResourceContext) { for (output in _outputs) { output.capacity = ctx.capacity @@ -208,7 +201,7 @@ public class SimResourceDistributorMaxMin( * An internal [SimResourceProvider] implementation for switch outputs. */ private inner class Output(capacity: Double, val key: InterferenceKey?) : - SimAbstractResourceProvider(interpreter, parent, capacity), + SimAbstractResourceProvider(interpreter, capacity), SimResourceCloseableProvider, SimResourceProviderLogic, Comparable { @@ -263,17 +256,54 @@ public class SimResourceDistributorMaxMin( } /* SimResourceProviderLogic */ - override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { + override fun onConsume( + ctx: SimResourceControllableContext, + now: Long, + delta: Long, + limit: Double, + duration: Long + ) { + doUpdateCounters(delta) + allowedSpeed = min(ctx.capacity, limit) + actualSpeed = 0.0 this.limit = limit this.duration = duration lastCommandTimestamp = now + } + + override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { + parent?.onConverge(now) + } + + override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { + doUpdateCounters(delta) + + limit = 0.0 + duration = Long.MAX_VALUE + actualSpeed = 0.0 + allowedSpeed = 0.0 + lastCommandTimestamp = now + } - return super.onConsume(ctx, now, limit, duration) + /* Comparable */ + override fun compareTo(other: Output): Int = allowedSpeed.compareTo(other.allowedSpeed) + + /** + * Pull the next command if necessary. + */ + fun pull(now: Long) { + val ctx = ctx + if (ctx != null && lastCommandTimestamp < now) { + ctx.flush() + } } - override fun onUpdate(ctx: SimResourceControllableContext, delta: Long, limit: Double, willOvercommit: Boolean) { - if (delta <= 0.0) { + /** + * Helper method to update the resource counters of the distributor. + */ + private fun doUpdateCounters(delta: Long) { + if (delta <= 0L) { return } @@ -289,38 +319,14 @@ public class SimResourceDistributorMaxMin( val work = limit * deltaS val actualWork = actualSpeed * deltaS val remainingWork = work - actualWork - val overcommit = if (willOvercommit && remainingWork > 0.0) { - remainingWork - } else { - 0.0 - } - updateCounters(work, actualWork, overcommit) + updateCounters(work, actualWork, remainingWork) val distCounters = _counters distCounters.demand += work distCounters.actual += actualWork - distCounters.overcommit += overcommit + distCounters.overcommit += remainingWork distCounters.interference += actualWork * max(0.0, 1 - perfScore) } - - override fun onFinish(ctx: SimResourceControllableContext) { - limit = 0.0 - duration = Long.MAX_VALUE - lastCommandTimestamp = ctx.clock.millis() - } - - /* Comparable */ - override fun compareTo(other: Output): Int = allowedSpeed.compareTo(other.allowedSpeed) - - /** - * Pull the next command if necessary. - */ - fun pull(now: Long) { - val ctx = ctx - if (ctx != null && lastCommandTimestamp < now) { - ctx.flush() - } - } } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt index 82631377..4bfeaf20 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt @@ -43,13 +43,8 @@ public interface SimResourceInterpreter { * * @param consumer The consumer logic. * @param provider The logic of the resource provider. - * @param parent The system to which the resource context belongs. */ - public fun newContext( - consumer: SimResourceConsumer, - provider: SimResourceProviderLogic, - parent: SimResourceSystem? = null - ): SimResourceControllableContext + public fun newContext(consumer: SimResourceConsumer, provider: SimResourceProviderLogic): SimResourceControllableContext /** * Start batching the execution of resource updates until [popBatch] is called. diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt index d8ff87f9..cc718165 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt @@ -23,7 +23,7 @@ package org.opendc.simulator.resources /** - * The logic of a resource provider. + * A collection of callbacks associated with a flow stage. */ public interface SimResourceProviderLogic { /** @@ -31,29 +31,28 @@ public interface SimResourceProviderLogic { * * @param ctx The context in which the provider runs. * @param now The virtual timestamp in milliseconds at which the update is occurring. + * @param delta The virtual duration between this call and the last call to [onConsume] in milliseconds. * @param limit The limit on the work rate of the resource consumer. * @param duration The duration of the consumption in milliseconds. * @return The deadline of the resource consumption. */ - public fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long { - return if (duration == Long.MAX_VALUE) { - return Long.MAX_VALUE - } else { - now + duration - } - } + public fun onConsume(ctx: SimResourceControllableContext, now: Long, delta: Long, limit: Double, duration: Long) {} /** - * This method is invoked when the progress of the resource consumer is materialized. + * This method is invoked when the flow graph has converged into a steady-state system. * * @param ctx The context in which the provider runs. - * @param limit The limit on the work rate of the resource consumer. - * @param willOvercommit A flag to indicate that the remaining work is overcommitted. + * @param now The virtual timestamp in milliseconds at which the system converged. + * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. */ - public fun onUpdate(ctx: SimResourceControllableContext, delta: Long, limit: Double, willOvercommit: Boolean) {} + public fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) {} /** * This method is invoked when the resource consumer has finished. + * + * @param ctx The context in which the provider runs. + * @param now The virtual timestamp in milliseconds at which the provider finished. + * @param delta The virtual duration between this call and the last call to [onConsume] in milliseconds. */ - public fun onFinish(ctx: SimResourceControllableContext) {} + public fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) {} } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt index 10213f26..c8d4cf0d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt @@ -33,21 +33,27 @@ public class SimResourceSource( initialCapacity: Double, private val interpreter: SimResourceInterpreter, private val parent: SimResourceSystem? = null -) : SimAbstractResourceProvider(interpreter, parent, initialCapacity) { +) : SimAbstractResourceProvider(interpreter, initialCapacity) { override fun createLogic(): SimResourceProviderLogic { return object : SimResourceProviderLogic { - override fun onUpdate( + override fun onConsume( ctx: SimResourceControllableContext, + now: Long, delta: Long, limit: Double, - willOvercommit: Boolean + duration: Long ) { - updateCounters(ctx, delta, limit, willOvercommit) + updateCounters(ctx, delta) } - override fun onFinish(ctx: SimResourceControllableContext) { + override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { + updateCounters(ctx, delta) cancel() } + + override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { + parent?.onConverge(now) + } } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt index a317f832..397463e0 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt @@ -73,16 +73,16 @@ public class SimResourceTransformer( override fun close() { val delegate = checkNotNull(delegate) { "Delegate not active" } + if (isCoupled) + _ctx?.close() + else + _ctx?.push(0.0) + // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we // reset beforehand the existing state and check whether it has been updated afterwards reset() delegate.onEvent(this, SimResourceEvent.Exit) - - if (isCoupled) - _ctx?.close() - else - _ctx?.push(0.0) } } @@ -213,6 +213,10 @@ public class SimResourceTransformer( * Update the resource counters for the transformer. */ private fun updateCounters(ctx: SimResourceContext, delta: Long) { + if (delta <= 0) { + return + } + val counters = _counters val deltaS = delta / 1000.0 val work = _limit * deltaS diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index 78d79434..5a9ffe2d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -32,11 +32,10 @@ import kotlin.math.min * Implementation of a [SimResourceContext] managing the communication between resources and resource consumers. */ internal class SimResourceContextImpl( - override val parent: SimResourceSystem?, private val interpreter: SimResourceInterpreterImpl, private val consumer: SimResourceConsumer, private val logic: SimResourceProviderLogic -) : SimResourceControllableContext, SimResourceSystem { +) : SimResourceControllableContext { /** * The clock of the context. */ @@ -84,7 +83,6 @@ internal class SimResourceContextImpl( private var _limit: Double = 0.0 private var _activeLimit: Double = 0.0 private var _deadline: Long = Long.MIN_VALUE - private var _lastUpdate: Long = Long.MIN_VALUE /** * A flag to indicate that an update is active. @@ -96,6 +94,12 @@ internal class SimResourceContextImpl( */ private var _flag: Int = 0 + /** + * The timestamp of calls to the callbacks. + */ + private var _lastUpdate: Long = Long.MIN_VALUE + private var _lastConvergence: Long = Long.MAX_VALUE + /** * The timers at which the context is scheduled to be interrupted. */ @@ -111,12 +115,20 @@ internal class SimResourceContextImpl( } override fun close() { - if (_state != SimResourceState.Stopped) { - interpreter.batch { - _state = SimResourceState.Stopped - if (!_updateActive) { - doStop() - } + if (_state == SimResourceState.Stopped) { + return + } + + interpreter.batch { + _state = SimResourceState.Stopped + if (!_updateActive) { + val now = clock.millis() + val delta = max(0, now - _lastUpdate) + doStop(now, delta) + + // FIX: Make sure the context converges + _flag = _flag or FLAG_INVALIDATE + scheduleUpdate(clock.millis()) } } } @@ -166,7 +178,7 @@ internal class SimResourceContextImpl( */ fun shouldUpdate(timestamp: Long): Boolean { // Either the resource context is flagged or there is a pending update at this timestamp - return _flag != 0 || _deadline == timestamp + return _flag != 0 || _limit != _activeLimit || _deadline == timestamp } /** @@ -179,18 +191,13 @@ internal class SimResourceContextImpl( } val lastUpdate = _lastUpdate + _lastUpdate = now _updateActive = true - val reachedDeadline = _deadline <= now val delta = max(0, now - lastUpdate) try { - // Update the resource counters only if there is some progress - if (now > lastUpdate) { - logic.onUpdate(this, delta, _activeLimit, reachedDeadline) - } - val duration = consumer.onNext(this, now, delta) val newDeadline = if (duration != Long.MAX_VALUE) now + duration else duration @@ -200,12 +207,12 @@ internal class SimResourceContextImpl( // Check whether the state has changed after [consumer.onNext] when (_state) { SimResourceState.Active -> { - logic.onConsume(this, now, _limit, duration) + logic.onConsume(this, now, delta, _limit, duration) // Schedule an update at the new deadline scheduleUpdate(now, newDeadline) } - SimResourceState.Stopped -> doStop() + SimResourceState.Stopped -> doStop(now, delta) SimResourceState.Pending -> throw IllegalStateException("Illegal transition to pending state") } @@ -217,18 +224,12 @@ internal class SimResourceContextImpl( _deadline = newDeadline _rate = min(capacity, newLimit) } catch (cause: Throwable) { - doFail(cause) + doFail(now, delta, cause) } finally { _updateActive = false } } - override fun onConverge(timestamp: Long) { - if (_state == SimResourceState.Active) { - consumer.onEvent(this, SimResourceEvent.Run) - } - } - /** * Prune the elapsed timers from this context. */ @@ -253,17 +254,35 @@ internal class SimResourceContextImpl( } } + /** + * This method is invoked when the system converges into a steady state. + */ + fun onConverge(timestamp: Long) { + val delta = max(0, timestamp - _lastConvergence) + _lastConvergence = timestamp + + try { + if (_state == SimResourceState.Active) { + consumer.onEvent(this, SimResourceEvent.Run) + } + + logic.onConverge(this, timestamp, delta) + } catch (cause: Throwable) { + doFail(timestamp, max(0, timestamp - _lastUpdate), cause) + } + } + override fun toString(): String = "SimResourceContextImpl[capacity=$capacity,rate=$_rate]" /** * Stop the resource context. */ - private fun doStop() { + private fun doStop(now: Long, delta: Long) { try { consumer.onEvent(this, SimResourceEvent.Exit) - logic.onFinish(this) + logic.onFinish(this, now, delta) } catch (cause: Throwable) { - doFail(cause) + doFail(now, delta, cause) } finally { _deadline = Long.MAX_VALUE _limit = 0.0 @@ -273,7 +292,7 @@ internal class SimResourceContextImpl( /** * Fail the resource consumer. */ - private fun doFail(cause: Throwable) { + private fun doFail(now: Long, delta: Long, cause: Throwable) { try { consumer.onFailure(this, cause) } catch (e: Throwable) { @@ -281,7 +300,7 @@ internal class SimResourceContextImpl( e.printStackTrace() } - logic.onFinish(this) + logic.onFinish(this, now, delta) } /** diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt index 2b6ec2ba..2abf0749 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt @@ -63,7 +63,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, /** * The systems that have been visited during the interpreter cycle. */ - private val visited = linkedSetOf() + private val visited = linkedSetOf() /** * The index in the batch stack. @@ -81,10 +81,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, */ fun scheduleSync(now: Long, ctx: SimResourceContextImpl) { ctx.doUpdate(now) - - if (visited.add(ctx)) { - collectAncestors(ctx, visited) - } + visited.add(ctx) // In-case the interpreter is already running in the call-stack, return immediately. The changes will be picked // up by the active interpreter. @@ -143,11 +140,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, return timer } - override fun newContext( - consumer: SimResourceConsumer, - provider: SimResourceProviderLogic, - parent: SimResourceSystem? - ): SimResourceControllableContext = SimResourceContextImpl(parent, this, consumer, provider) + override fun newContext(consumer: SimResourceConsumer, provider: SimResourceProviderLogic): SimResourceControllableContext = SimResourceContextImpl(this, consumer, provider) override fun pushBatch() { batchIndex++ @@ -200,10 +193,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, if (ctx.shouldUpdate(now)) { ctx.doUpdate(now) - - if (visited.add(ctx)) { - collectAncestors(ctx, visited) - } + visited.add(ctx) } else { ctx.tryReschedule(now) } @@ -218,10 +208,7 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, if (ctx.shouldUpdate(now)) { ctx.doUpdate(now) - - if (visited.add(ctx)) { - collectAncestors(ctx, visited) - } + visited.add(ctx) } } @@ -239,17 +226,6 @@ internal class SimResourceInterpreterImpl(private val context: CoroutineContext, } } - /** - * Collect all the ancestors of the specified [system]. - */ - private tailrec fun collectAncestors(system: SimResourceSystem, systems: MutableSet) { - val parent = system.parent - if (parent != null) { - systems.add(parent) - collectAncestors(parent, systems) - } - } - /** * Try to schedule an interpreter invocation at the specified [target]. * diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt index c7230a0e..1428ce42 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt @@ -50,7 +50,7 @@ class SimResourceContextTest { } val logic = object : SimResourceProviderLogic {} - val context = SimResourceContextImpl(null, interpreter, consumer, logic) + val context = SimResourceContextImpl(interpreter, consumer, logic) interpreter.scheduleSync(interpreter.clock.millis(), context) } @@ -60,18 +60,15 @@ class SimResourceContextTest { val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) val consumer = SimWorkConsumer(1.0, 1.0) - val logic = spyk(object : SimResourceProviderLogic { - override fun onFinish(ctx: SimResourceControllableContext) {} - override fun onConsume(ctx: SimResourceControllableContext, now: Long, limit: Double, duration: Long): Long = duration - }) - val context = SimResourceContextImpl(null, interpreter, consumer, logic) + val logic = spyk(object : SimResourceProviderLogic {}) + val context = SimResourceContextImpl(interpreter, consumer, logic) context.capacity = 1.0 context.start() delay(1) // Delay 1 ms to prevent hitting the fast path interpreter.scheduleSync(interpreter.clock.millis(), context) - verify(exactly = 2) { logic.onConsume(any(), any(), any(), any()) } + verify(exactly = 2) { logic.onConsume(any(), any(), any(), any(), any()) } } @Test @@ -80,7 +77,7 @@ class SimResourceContextTest { val consumer = SimWorkConsumer(1.0, 1.0) val logic = spyk(object : SimResourceProviderLogic {}) - val context = SimResourceContextImpl(null, interpreter, consumer, logic) + val context = SimResourceContextImpl(interpreter, consumer, logic) context.capacity = 1.0 context.start() @@ -90,8 +87,8 @@ class SimResourceContextTest { context.invalidate() assertAll( - { verify(exactly = 2) { logic.onConsume(any(), any(), any(), any()) } }, - { verify(exactly = 1) { logic.onFinish(any()) } } + { verify(exactly = 2) { logic.onConsume(any(), any(), any(), any(), any()) } }, + { verify(exactly = 1) { logic.onFinish(any(), any(), any()) } } ) } @@ -111,7 +108,7 @@ class SimResourceContextTest { } val logic = object : SimResourceProviderLogic {} - val context = SimResourceContextImpl(null, interpreter, consumer, logic) + val context = SimResourceContextImpl(interpreter, consumer, logic) context.start() @@ -136,8 +133,7 @@ class SimResourceContextTest { }) val logic = object : SimResourceProviderLogic {} - - val context = SimResourceContextImpl(null, interpreter, consumer, logic) + val context = SimResourceContextImpl(interpreter, consumer, logic) context.capacity = 4200.0 context.start() context.capacity = 4200.0 @@ -166,7 +162,7 @@ class SimResourceContextTest { val logic = object : SimResourceProviderLogic {} - val context = SimResourceContextImpl(null, interpreter, consumer, logic) + val context = SimResourceContextImpl(interpreter, consumer, logic) context.start() diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt index fc43c3da..d7d0924f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt @@ -223,6 +223,9 @@ internal class SimResourceTransformerTest { forwarder.consume(consumer) + yield() + + assertEquals(2.0, source.counters.actual) assertEquals(source.counters.actual, forwarder.counters.actual) { "Actual work" } assertEquals(source.counters.demand, forwarder.counters.demand) { "Work demand" } assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } -- cgit v1.2.3 From 7703fc9fcc847208b1803a58d9eaa5938d2c77a1 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 15:02:38 +0200 Subject: refactor(simulator): Do not expose SimResourceState This change hides the SimResourceState from public API since it is not actively used outside of the `SimResourceContextImpl` class. --- .../resources/SimResourceControllableContext.kt | 5 --- .../opendc/simulator/resources/SimResourceState.kt | 43 ------------------- .../resources/impl/SimResourceContextImpl.kt | 50 +++++++++++++++------- 3 files changed, 34 insertions(+), 64 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceState.kt diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt index ba52b597..b406b896 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt @@ -28,11 +28,6 @@ package org.opendc.simulator.resources * This interface is used by resource providers to control the resource context. */ public interface SimResourceControllableContext : SimResourceContext { - /** - * The state of the resource context. - */ - public val state: SimResourceState - /** * The capacity of the resource. */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceState.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceState.kt deleted file mode 100644 index c72951d0..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceState.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * The state of a resource provider. - */ -public enum class SimResourceState { - /** - * The resource provider is pending and the resource is waiting to be consumed. - */ - Pending, - - /** - * The resource provider is active and the resource is currently being consumed. - */ - Active, - - /** - * The resource provider is stopped and the resource cannot be consumed anymore. - */ - Stopped -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt index 5a9ffe2d..cbfa7afd 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt @@ -60,9 +60,7 @@ internal class SimResourceContextImpl( /** * A flag to indicate the state of the context. */ - override val state: SimResourceState - get() = _state - private var _state = SimResourceState.Pending + private var _state = State.Pending /** * The current processing speed of the resource. @@ -106,21 +104,21 @@ internal class SimResourceContextImpl( private val _timers: ArrayDeque = ArrayDeque() override fun start() { - check(_state == SimResourceState.Pending) { "Consumer is already started" } + check(_state == State.Pending) { "Consumer is already started" } interpreter.batch { consumer.onEvent(this, SimResourceEvent.Start) - _state = SimResourceState.Active + _state = State.Active interrupt() } } override fun close() { - if (_state == SimResourceState.Stopped) { + if (_state == State.Stopped) { return } interpreter.batch { - _state = SimResourceState.Stopped + _state = State.Stopped if (!_updateActive) { val now = clock.millis() val delta = max(0, now - _lastUpdate) @@ -134,7 +132,7 @@ internal class SimResourceContextImpl( } override fun interrupt() { - if (_state == SimResourceState.Stopped) { + if (_state == State.Stopped) { return } @@ -143,7 +141,7 @@ internal class SimResourceContextImpl( } override fun invalidate() { - if (_state == SimResourceState.Stopped) { + if (_state == State.Stopped) { return } @@ -152,7 +150,7 @@ internal class SimResourceContextImpl( } override fun flush() { - if (_state == SimResourceState.Stopped) { + if (_state == State.Stopped) { return } @@ -186,7 +184,7 @@ internal class SimResourceContextImpl( */ fun doUpdate(now: Long) { val oldState = _state - if (oldState != SimResourceState.Active) { + if (oldState != State.Active) { return } @@ -206,14 +204,14 @@ internal class SimResourceContextImpl( // Check whether the state has changed after [consumer.onNext] when (_state) { - SimResourceState.Active -> { + State.Active -> { logic.onConsume(this, now, delta, _limit, duration) // Schedule an update at the new deadline scheduleUpdate(now, newDeadline) } - SimResourceState.Stopped -> doStop(now, delta) - SimResourceState.Pending -> throw IllegalStateException("Illegal transition to pending state") + State.Stopped -> doStop(now, delta) + State.Pending -> throw IllegalStateException("Illegal transition to pending state") } // Note: pending limit might be changed by [logic.onConsume], so re-fetch the value @@ -262,7 +260,7 @@ internal class SimResourceContextImpl( _lastConvergence = timestamp try { - if (_state == SimResourceState.Active) { + if (_state == State.Active) { consumer.onEvent(this, SimResourceEvent.Run) } @@ -308,7 +306,7 @@ internal class SimResourceContextImpl( */ private fun onCapacityChange() { // Do not inform the consumer if it has not been started yet - if (state != SimResourceState.Active) { + if (_state != State.Active) { return } @@ -337,6 +335,26 @@ internal class SimResourceContextImpl( } } + /** + * The state of a resource context. + */ + private enum class State { + /** + * The resource context is pending and the resource is waiting to be consumed. + */ + Pending, + + /** + * The resource context is active and the resource is currently being consumed. + */ + Active, + + /** + * The resource context is stopped and the resource cannot be consumed anymore. + */ + Stopped + } + /** * A flag to indicate that the context should be invalidated. */ -- cgit v1.2.3 From 0272738f3ba5faeb0b5463464ff2d961136bb317 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 15:04:54 +0200 Subject: refactor(simulator): Remove SimResourceFlow interface --- .../opendc/simulator/resources/SimResourceFlow.kt | 29 ---------------------- .../simulator/resources/SimResourceTransformer.kt | 5 ++-- 2 files changed, 3 insertions(+), 31 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceFlow.kt diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceFlow.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceFlow.kt deleted file mode 100644 index bbf6ad44..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceFlow.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A [SimResourceFlow] acts as both a resource consumer and resource provider at the same time, simplifying bridging - * between different components. - */ -public interface SimResourceFlow : SimResourceConsumer, SimResourceProvider diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt index 397463e0..76a3bdd7 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt @@ -26,7 +26,8 @@ import org.opendc.simulator.resources.impl.SimResourceCountersImpl import java.time.Clock /** - * A [SimResourceFlow] that transforms the resource commands emitted by the resource commands to the resource provider. + * A [SimResourceConsumer] and [SimResourceProvider] that transforms the resource commands emitted by the resource + * commands to the resource provider. * * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. * @param transform The function to transform the received resource command. @@ -34,7 +35,7 @@ import java.time.Clock public class SimResourceTransformer( private val isCoupled: Boolean = false, private val transform: (SimResourceContext, Long) -> Long -) : SimResourceFlow, AutoCloseable { +) : SimResourceConsumer, SimResourceProvider, AutoCloseable { /** * The delegate [SimResourceConsumer]. */ -- cgit v1.2.3 From f00c5f3663a2bdbfacc2d6f812503f22f1ed26bb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 16:06:48 +0200 Subject: refactor(simulator): Eliminate usage of distributor and aggregator This change removes the use of distributor and aggregator from the other OpenDC components. For the future, we focus on maintaining a single SimResourceSwitch implementation to achieve both use-cases. --- .../main/kotlin/org/opendc/simulator/power/SimPdu.kt | 19 ++++++++++++++----- .../main/kotlin/org/opendc/simulator/power/SimUps.kt | 13 +++++++++---- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index b0ea7f0a..e5fcd938 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -37,18 +37,27 @@ public class SimPdu( private val lossCoefficient: Double = 0.0, ) : SimPowerInlet() { /** - * The [SimResourceDistributor] that distributes the electricity over the PDU outlets. + * The [SimResourceSwitch] that distributes the electricity over the PDU outlets. */ - private val distributor = SimResourceDistributorMaxMin(interpreter) + private val switch = SimResourceSwitchMaxMin(interpreter) + + /** + * The [SimResourceTransformer] that represents the input of the PDU. + */ + private val forwarder = SimResourceForwarder() /** * Create a new PDU outlet. */ - public fun newOutlet(): Outlet = Outlet(distributor.newOutput()) + public fun newOutlet(): Outlet = Outlet(switch.newOutput()) + + init { + switch.addInput(forwarder) + } - override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer by distributor { + override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer by forwarder { override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val duration = distributor.onNext(ctx, now, delta) + val duration = forwarder.onNext(ctx, now, delta) val loss = computePowerLoss(ctx.demand) val newLimit = ctx.demand + loss diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 59006dfc..79c1b37d 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -41,20 +41,25 @@ public class SimUps( /** * The resource aggregator used to combine the input sources. */ - private val aggregator = SimResourceAggregatorMaxMin(interpreter) + private val switch = SimResourceSwitchMaxMin(interpreter) + + /** + * The [SimResourceProvider] that represents the output of the UPS. + */ + private val provider = switch.newOutput() /** * Create a new UPS outlet. */ public fun newInlet(): SimPowerInlet { val forward = SimResourceForwarder(isCoupled = true) - aggregator.addInput(forward) + switch.addInput(forward) return Inlet(forward) } override fun onConnect(inlet: SimPowerInlet) { val consumer = inlet.createConsumer() - aggregator.startConsumer(object : SimResourceConsumer by consumer { + provider.startConsumer(object : SimResourceConsumer by consumer { override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { val duration = consumer.onNext(ctx, now, delta) val loss = computePowerLoss(ctx.demand) @@ -67,7 +72,7 @@ public class SimUps( } override fun onDisconnect(inlet: SimPowerInlet) { - aggregator.cancel() + provider.cancel() } /** -- cgit v1.2.3 From d2f15fd7fd16922c11b0dcaa8807e8a321859773 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 22:05:03 +0200 Subject: refactor(simulator): Merge distributor and aggregator into switch This change removes the distributor and aggregator interfaces in favour of a single switch interface. Since the switch interface is as powerful as both the distributor and aggregator, we don't need the latter two. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 3 +- .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../compute/kernel/SimAbstractHypervisor.kt | 14 +- .../simulator/compute/kernel/SimHypervisorTest.kt | 2 + .../simulator/network/SimNetworkSwitchVirtual.kt | 2 +- .../kotlin/org/opendc/simulator/power/SimPdu.kt | 6 +- .../resources/SimAbstractResourceAggregator.kt | 147 --------- .../simulator/resources/SimResourceAggregator.kt | 38 --- .../resources/SimResourceAggregatorMaxMin.kt | 64 ---- .../resources/SimResourceCloseableProvider.kt | 37 --- .../simulator/resources/SimResourceCounters.kt | 5 + .../simulator/resources/SimResourceDistributor.kt | 42 --- .../resources/SimResourceDistributorMaxMin.kt | 332 ------------------- .../simulator/resources/SimResourceSwitch.kt | 16 +- .../resources/SimResourceSwitchExclusive.kt | 64 ++-- .../simulator/resources/SimResourceSwitchMaxMin.kt | 361 +++++++++++++++++++-- .../resources/impl/SimResourceCountersImpl.kt | 6 +- .../resources/SimResourceAggregatorMaxMinTest.kt | 190 ----------- .../resources/SimResourceSwitchExclusiveTest.kt | 28 +- .../resources/SimResourceSwitchMaxMinTest.kt | 6 +- 20 files changed, 424 insertions(+), 941 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregator.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index fdb3f1dc..a8b8afe9 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -47,7 +47,6 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.resources.SimResourceDistributorMaxMin import org.opendc.simulator.resources.SimResourceInterpreter import java.util.* import kotlin.coroutines.CoroutineContext @@ -418,7 +417,7 @@ public class SimHost( val counters = hypervisor.counters val grantedWork = counters.actual val overcommittedWork = counters.overcommit - val interferedWork = (counters as? SimResourceDistributorMaxMin.Counters)?.interference ?: 0.0 + val interferedWork = counters.interference _totalTime += (duration / 1000.0) * coreCount val activeTime = (grantedWork * d).roundToLong() diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 16085d82..1bec2de5 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -212,7 +212,7 @@ class CapelinIntegrationTest { { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(476163, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(477279, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index 98271fb0..cf9e3230 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -131,7 +131,7 @@ public abstract class SimAbstractHypervisor( /** * The vCPUs of the machine. */ - override val cpus = model.cpus.map { VCpu(switch.newOutput(interferenceKey), it) } + override val cpus = model.cpus.map { VCpu(switch, switch.newOutput(interferenceKey), it) } override fun close() { super.close() @@ -153,9 +153,10 @@ public abstract class SimAbstractHypervisor( * A [SimProcessingUnit] of a virtual machine. */ private class VCpu( - private val source: SimResourceCloseableProvider, + private val switch: SimResourceSwitch, + private val source: SimResourceProvider, override val model: ProcessingUnit - ) : SimProcessingUnit, SimResourceCloseableProvider by source { + ) : SimProcessingUnit, SimResourceProvider by source { override var capacity: Double get() = source.capacity set(_) { @@ -163,6 +164,13 @@ public abstract class SimAbstractHypervisor( } override fun toString(): String = "SimAbstractHypervisor.VCpu[model=$model]" + + /** + * Close the CPU + */ + fun close() { + switch.removeOutput(source) + } } /** diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index 1f010338..8cd535ad 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -103,8 +103,10 @@ internal class SimHypervisorTest { println("Hypervisor finished") } yield() + val vm = hypervisor.createMachine(model) vm.run(workloadA) + yield() machine.close() diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt index 05daaa5c..2267715e 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt @@ -70,7 +70,7 @@ public class SimNetworkSwitchVirtual(interpreter: SimResourceInterpreter) : SimN override fun close() { isClosed = true - _provider.close() + switch.removeOutput(_provider) _ports.remove(this) } } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index e5fcd938..947f6cb2 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -49,7 +49,7 @@ public class SimPdu( /** * Create a new PDU outlet. */ - public fun newOutlet(): Outlet = Outlet(switch.newOutput()) + public fun newOutlet(): Outlet = Outlet(switch, switch.newOutput()) init { switch.addInput(forwarder) @@ -81,7 +81,7 @@ public class SimPdu( /** * A PDU outlet. */ - public class Outlet(private val provider: SimResourceCloseableProvider) : SimPowerOutlet(), AutoCloseable { + public class Outlet(private val switch: SimResourceSwitch, private val provider: SimResourceProvider) : SimPowerOutlet(), AutoCloseable { override fun onConnect(inlet: SimPowerInlet) { provider.startConsumer(inlet.createConsumer()) } @@ -94,7 +94,7 @@ public class SimPdu( * Remove the outlet from the PDU. */ override fun close() { - provider.close() + switch.removeOutput(provider) } override fun toString(): String = "SimPdu.Outlet" diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt deleted file mode 100644 index 621ea6e7..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * Abstract implementation of [SimResourceAggregator]. - */ -public abstract class SimAbstractResourceAggregator( - interpreter: SimResourceInterpreter, - parent: SimResourceSystem? -) : SimResourceAggregator { - /** - * This method is invoked when the resource consumer consumes resources. - */ - protected abstract fun doConsume(limit: Double) - - /** - * This method is invoked when the resource consumer finishes processing. - */ - protected abstract fun doFinish() - - /** - * This method is invoked when an input context is started. - */ - protected abstract fun onInputStarted(input: SimResourceContext) - - /** - * This method is invoked when an input is stopped. - */ - protected abstract fun onInputFinished(input: SimResourceContext) - - /* SimResourceAggregator */ - override fun addInput(input: SimResourceProvider) { - val consumer = Consumer() - _inputs.add(input) - _inputConsumers.add(consumer) - input.startConsumer(consumer) - } - - override val inputs: Set - get() = _inputs - private val _inputs = mutableSetOf() - private val _inputConsumers = mutableListOf() - - /* SimResourceProvider */ - override val isActive: Boolean - get() = _output.isActive - - override val capacity: Double - get() = _output.capacity - - override val speed: Double - get() = _output.speed - - override val demand: Double - get() = _output.demand - - override val counters: SimResourceCounters - get() = _output.counters - - override fun startConsumer(consumer: SimResourceConsumer) { - _output.startConsumer(consumer) - } - - override fun cancel() { - _output.cancel() - } - - override fun interrupt() { - _output.interrupt() - } - - private val _output = object : SimAbstractResourceProvider(interpreter, initialCapacity = 0.0) { - override fun createLogic(): SimResourceProviderLogic { - return object : SimResourceProviderLogic { - - override fun onConsume(ctx: SimResourceControllableContext, now: Long, delta: Long, limit: Double, duration: Long) { - updateCounters(ctx, delta) - doConsume(limit) - } - - override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { - updateCounters(ctx, delta) - doFinish() - } - - override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { - parent?.onConverge(now) - } - } - } - } - - /** - * An internal [SimResourceConsumer] implementation for aggregator inputs. - */ - private inner class Consumer : SimResourceConsumer { - /** - * The resource context associated with the input. - */ - private var _ctx: SimResourceContext? = null - - private fun updateCapacity() { - // Adjust capacity of output resource - _output.capacity = _inputConsumers.sumOf { it._ctx?.capacity ?: 0.0 } - } - - /* SimResourceConsumer */ - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return Long.MAX_VALUE - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - _ctx = ctx - updateCapacity() - - onInputStarted(ctx) - } - SimResourceEvent.Capacity -> updateCapacity() - SimResourceEvent.Exit -> onInputFinished(ctx) - else -> {} - } - } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregator.kt deleted file mode 100644 index 00972f43..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregator.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A [SimResourceAggregator] aggregates the capacity of multiple resources into a single resource. - */ -public interface SimResourceAggregator : SimResourceProvider { - /** - * The input resources that will be switched between the output providers. - */ - public val inputs: Set - - /** - * Add the specified [input] to the aggregator. - */ - public fun addInput(input: SimResourceProvider) -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt deleted file mode 100644 index f131ac6c..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A [SimResourceAggregator] that distributes the load equally across the input resources. - */ -public class SimResourceAggregatorMaxMin( - interpreter: SimResourceInterpreter, - parent: SimResourceSystem? = null -) : SimAbstractResourceAggregator(interpreter, parent) { - private val consumers = mutableListOf() - - override fun doConsume(limit: Double) { - // Sort all consumers by their capacity - consumers.sortWith(compareBy { it.capacity }) - - // Divide the requests over the available capacity of the input resources fairly - for (input in consumers) { - val inputCapacity = input.capacity - val fraction = inputCapacity / capacity - val grantedSpeed = limit * fraction - - input.push(grantedSpeed) - input.interrupt() - } - } - - override fun doFinish() { - val iterator = consumers.iterator() - for (input in iterator) { - iterator.remove() - input.close() - } - } - - override fun onInputStarted(input: SimResourceContext) { - consumers.add(input) - } - - override fun onInputFinished(input: SimResourceContext) { - consumers.remove(input) - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt deleted file mode 100644 index bce8274b..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A [SimResourceProvider] that has a controllable and limited lifetime. - * - * This interface is used to signal that the resource provider may be closed and not reused after that point. - */ -public interface SimResourceCloseableProvider : SimResourceProvider, AutoCloseable { - /** - * End the lifetime of the resource provider. - * - * This operation cancels the existing resource consumer and prevents the resource provider from being reused. - */ - public override fun close() -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt index 725aa5bc..11924db2 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt @@ -41,6 +41,11 @@ public interface SimResourceCounters { */ public val overcommit: Double + /** + * The amount of work lost due to interference. + */ + public val interference: Double + /** * Reset the resource counters. */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt deleted file mode 100644 index f384582f..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.interference.InterferenceKey - -/** - * A [SimResourceDistributor] distributes the capacity of some resource over multiple resource consumers. - */ -public interface SimResourceDistributor : SimResourceConsumer { - /** - * The output resource providers to which resource consumers can be attached. - */ - public val outputs: Set - - /** - * Create a new output for the distributor. - * - * @param key The key of the interference member to which the output belongs. - */ - public fun newOutput(key: InterferenceKey? = null): SimResourceCloseableProvider -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt deleted file mode 100644 index 7df940ad..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.interference.InterferenceDomain -import org.opendc.simulator.resources.interference.InterferenceKey -import kotlin.math.max -import kotlin.math.min - -/** - * A [SimResourceDistributor] that distributes the capacity of a resource over consumers using max-min fair sharing. - * - * @param interpreter The interpreter for managing the resource contexts. - * @param parent The parent resource system of the distributor. - * @param interferenceDomain The interference domain of the distributor. - */ -public class SimResourceDistributorMaxMin( - private val interpreter: SimResourceInterpreter, - private val parent: SimResourceSystem? = null, - private val interferenceDomain: InterferenceDomain? = null -) : SimResourceDistributor { - override val outputs: Set - get() = _outputs - private val _outputs = mutableSetOf() - - /** - * The resource context of the consumer. - */ - private var ctx: SimResourceContext? = null - - /** - * The active outputs. - */ - private val activeOutputs: MutableList = mutableListOf() - - /** - * The total allocated speed for the output resources. - */ - private var totalAllocatedSpeed = 0.0 - - /** - * The total requested speed for the output resources. - */ - private var totalRequestedSpeed = 0.0 - - /** - * The resource counters of this distributor. - */ - public val counters: Counters - get() = _counters - private val _counters = object : Counters { - override var demand: Double = 0.0 - override var actual: Double = 0.0 - override var overcommit: Double = 0.0 - override var interference: Double = 0.0 - - override fun reset() { - demand = 0.0 - actual = 0.0 - overcommit = 0.0 - interference = 0.0 - } - - override fun toString(): String = "SimResourceDistributorMaxMin.Counters[demand=$demand,actual=$actual,overcommit=$overcommit,interference=$interference]" - } - - /* SimResourceDistributor */ - override fun newOutput(key: InterferenceKey?): SimResourceCloseableProvider { - val provider = Output(ctx?.capacity ?: 0.0, key) - _outputs.add(provider) - return provider - } - - /* SimResourceConsumer */ - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - // If there is no work yet, mark the input as idle. - if (activeOutputs.isEmpty()) { - return Long.MAX_VALUE - } - - val capacity = ctx.capacity - var duration: Long = Long.MAX_VALUE - var availableSpeed = capacity - var totalRequestedSpeed = 0.0 - - // Pull in the work of the outputs - val outputIterator = activeOutputs.listIterator() - for (output in outputIterator) { - output.pull(now) - - // Remove outputs that have finished - if (!output.isActive) { - outputIterator.remove() - } - } - - // Sort in-place the outputs based on their requested usage. - // Profiling shows that it is faster than maintaining some kind of sorted set. - activeOutputs.sort() - - // Divide the available input capacity fairly across the outputs using max-min fair sharing - var remaining = activeOutputs.size - for (output in activeOutputs) { - val availableShare = availableSpeed / remaining-- - val grantedSpeed = min(output.allowedSpeed, availableShare) - - duration = min(duration, output.duration) - - // Ignore idle computation - if (grantedSpeed <= 0.0) { - output.actualSpeed = 0.0 - continue - } - - totalRequestedSpeed += output.limit - - output.actualSpeed = grantedSpeed - availableSpeed -= grantedSpeed - } - - val durationS = duration / 1000.0 - var totalRequestedWork = 0.0 - var totalAllocatedWork = 0.0 - for (output in activeOutputs) { - val limit = output.limit - val speed = output.actualSpeed - if (speed > 0.0) { - totalRequestedWork += limit * durationS - totalAllocatedWork += speed * durationS - } - } - - this.totalRequestedSpeed = totalRequestedSpeed - val totalAllocatedSpeed = capacity - availableSpeed - this.totalAllocatedSpeed = totalAllocatedSpeed - - ctx.push(totalAllocatedSpeed) - return duration - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - this.ctx = ctx - updateCapacity(ctx) - } - SimResourceEvent.Exit -> { - val iterator = _outputs.iterator() - while (iterator.hasNext()) { - val output = iterator.next() - - // Remove the output from the outputs to prevent ConcurrentModificationException when removing it - // during the call to output.close() - iterator.remove() - - output.close() - } - } - SimResourceEvent.Capacity -> updateCapacity(ctx) - else -> {} - } - } - - /** - * Extended [SimResourceCounters] interface for the distributor. - */ - public interface Counters : SimResourceCounters { - /** - * The amount of work lost due to interference. - */ - public val interference: Double - } - - private fun updateCapacity(ctx: SimResourceContext) { - for (output in _outputs) { - output.capacity = ctx.capacity - } - } - - /** - * An internal [SimResourceProvider] implementation for switch outputs. - */ - private inner class Output(capacity: Double, val key: InterferenceKey?) : - SimAbstractResourceProvider(interpreter, capacity), - SimResourceCloseableProvider, - SimResourceProviderLogic, - Comparable { - /** - * A flag to indicate that the output is closed. - */ - private var isClosed: Boolean = false - - /** - * The requested limit. - */ - @JvmField var limit: Double = 0.0 - - /** - * The current deadline. - */ - @JvmField var duration: Long = Long.MAX_VALUE - - /** - * The processing speed that is allowed by the model constraints. - */ - @JvmField var allowedSpeed: Double = 0.0 - - /** - * The actual processing speed. - */ - @JvmField var actualSpeed: Double = 0.0 - - /** - * The timestamp at which we received the last command. - */ - private var lastCommandTimestamp: Long = Long.MIN_VALUE - - /* SimAbstractResourceProvider */ - override fun createLogic(): SimResourceProviderLogic = this - - override fun start(ctx: SimResourceControllableContext) { - check(!isClosed) { "Cannot re-use closed output" } - - activeOutputs += this - interpreter.batch { - ctx.start() - // Interrupt the input to re-schedule the resources - this@SimResourceDistributorMaxMin.ctx?.interrupt() - } - } - - override fun close() { - isClosed = true - cancel() - _outputs.remove(this) - } - - /* SimResourceProviderLogic */ - override fun onConsume( - ctx: SimResourceControllableContext, - now: Long, - delta: Long, - limit: Double, - duration: Long - ) { - doUpdateCounters(delta) - - allowedSpeed = min(ctx.capacity, limit) - actualSpeed = 0.0 - this.limit = limit - this.duration = duration - lastCommandTimestamp = now - } - - override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { - parent?.onConverge(now) - } - - override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { - doUpdateCounters(delta) - - limit = 0.0 - duration = Long.MAX_VALUE - actualSpeed = 0.0 - allowedSpeed = 0.0 - lastCommandTimestamp = now - } - - /* Comparable */ - override fun compareTo(other: Output): Int = allowedSpeed.compareTo(other.allowedSpeed) - - /** - * Pull the next command if necessary. - */ - fun pull(now: Long) { - val ctx = ctx - if (ctx != null && lastCommandTimestamp < now) { - ctx.flush() - } - } - - /** - * Helper method to update the resource counters of the distributor. - */ - private fun doUpdateCounters(delta: Long) { - if (delta <= 0L) { - return - } - - // Compute the performance penalty due to resource interference - val perfScore = if (interferenceDomain != null) { - val load = totalAllocatedSpeed / requireNotNull(this@SimResourceDistributorMaxMin.ctx).capacity - interferenceDomain.apply(key, load) - } else { - 1.0 - } - - val deltaS = delta / 1000.0 - val work = limit * deltaS - val actualWork = actualSpeed * deltaS - val remainingWork = work - actualWork - - updateCounters(work, actualWork, remainingWork) - - val distCounters = _counters - distCounters.demand += work - distCounters.actual += actualWork - distCounters.overcommit += remainingWork - distCounters.interference += actualWork * max(0.0, 1 - perfScore) - } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt index d2aab634..3c25b76d 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt @@ -27,11 +27,11 @@ import org.opendc.simulator.resources.interference.InterferenceKey /** * A [SimResourceSwitch] enables switching of capacity of multiple resources between multiple consumers. */ -public interface SimResourceSwitch : AutoCloseable { +public interface SimResourceSwitch { /** * The output resource providers to which resource consumers can be attached. */ - public val outputs: Set + public val outputs: Set /** * The input resources that will be switched between the output providers. @@ -48,10 +48,20 @@ public interface SimResourceSwitch : AutoCloseable { * * @param key The key of the interference member to which the output belongs. */ - public fun newOutput(key: InterferenceKey? = null): SimResourceCloseableProvider + public fun newOutput(key: InterferenceKey? = null): SimResourceProvider + + /** + * Remove [output] from this switch. + */ + public fun removeOutput(output: SimResourceProvider) /** * Add the specified [input] to the switch. */ public fun addInput(input: SimResourceProvider) + + /** + * Clear all inputs and outputs from the switch. + */ + public fun clear() } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt index fbb541e5..2be8ccb0 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt @@ -27,23 +27,17 @@ import java.util.ArrayDeque /** * A [SimResourceSwitch] implementation that allocates outputs to the inputs of the switch exclusively. This means that - * a single output is directly connected to an input and that the switch can only support as much outputs as inputs. + * a single output is directly connected to an input and that the switch can only support as many outputs as inputs. */ public class SimResourceSwitchExclusive : SimResourceSwitch { - /** - * A flag to indicate that the switch is closed. - */ - private var isClosed: Boolean = false - - private val _outputs = mutableSetOf() - override val outputs: Set + override val outputs: Set get() = _outputs - - private val availableResources = ArrayDeque() + private val _outputs = mutableSetOf() private val _inputs = mutableSetOf() override val inputs: Set get() = _inputs + private val _availableInputs = ArrayDeque() override val counters: SimResourceCounters = object : SimResourceCounters { override val demand: Double @@ -52,6 +46,8 @@ public class SimResourceSwitchExclusive : SimResourceSwitch { get() = _inputs.sumOf { it.counters.actual } override val overcommit: Double get() = _inputs.sumOf { it.counters.overcommit } + override val interference: Double + get() = _inputs.sumOf { it.counters.interference } override fun reset() { for (input in _inputs) { @@ -65,18 +61,25 @@ public class SimResourceSwitchExclusive : SimResourceSwitch { /** * Add an output to the switch. */ - override fun newOutput(key: InterferenceKey?): SimResourceCloseableProvider { - check(!isClosed) { "Switch has been closed" } - check(availableResources.isNotEmpty()) { "No capacity to serve request" } - val forwarder = availableResources.poll() - val output = Provider(forwarder) + override fun newOutput(key: InterferenceKey?): SimResourceProvider { + val forwarder = checkNotNull(_availableInputs.poll()) { "No capacity to serve request" } + val output = Output(forwarder) _outputs += output return output } - override fun addInput(input: SimResourceProvider) { - check(!isClosed) { "Switch has been closed" } + override fun removeOutput(output: SimResourceProvider) { + if (!_outputs.remove(output)) { + return + } + + (output as Output).close() + } + /** + * Add an input to the switch. + */ + override fun addInput(input: SimResourceProvider) { if (input in inputs) { return } @@ -84,7 +87,7 @@ public class SimResourceSwitchExclusive : SimResourceSwitch { val forwarder = SimResourceForwarder() _inputs += input - availableResources += forwarder + _availableInputs += forwarder input.startConsumer(object : SimResourceConsumer by forwarder { override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { @@ -98,18 +101,29 @@ public class SimResourceSwitchExclusive : SimResourceSwitch { }) } - override fun close() { - isClosed = true + override fun clear() { + for (input in _inputs) { + input.cancel() + } + _inputs.clear() - // Cancel all upstream subscriptions - _inputs.forEach(SimResourceProvider::cancel) + // Outputs are implicitly cancelled by the inputs forwarders + _outputs.clear() } - private inner class Provider(private val forwarder: SimResourceTransformer) : SimResourceCloseableProvider, SimResourceProvider by forwarder { - override fun close() { + /** + * An output of the resource switch. + */ + private inner class Output(private val forwarder: SimResourceTransformer) : SimResourceProvider by forwarder { + /** + * Close the output. + */ + fun close() { // We explicitly do not close the forwarder here in order to re-use it across output resources. _outputs -= this - availableResources += forwarder + _availableInputs += forwarder } + + override fun toString(): String = "SimResourceSwitchExclusive.Output" } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt index e368609f..574fb443 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt @@ -22,8 +22,11 @@ package org.opendc.simulator.resources +import org.opendc.simulator.resources.impl.SimResourceCountersImpl import org.opendc.simulator.resources.interference.InterferenceDomain import org.opendc.simulator.resources.interference.InterferenceKey +import kotlin.math.max +import kotlin.math.min /** * A [SimResourceSwitch] implementation that switches resource consumptions over the available resources using max-min @@ -34,69 +37,371 @@ import org.opendc.simulator.resources.interference.InterferenceKey * @param interferenceDomain The interference domain of the switch. */ public class SimResourceSwitchMaxMin( - interpreter: SimResourceInterpreter, - parent: SimResourceSystem? = null, - interferenceDomain: InterferenceDomain? = null + private val interpreter: SimResourceInterpreter, + private val parent: SimResourceSystem? = null, + private val interferenceDomain: InterferenceDomain? = null ) : SimResourceSwitch { /** * The output resource providers to which resource consumers can be attached. */ - override val outputs: Set - get() = distributor.outputs + override val outputs: Set + get() = _outputs + private val _outputs = mutableSetOf() + private val _activeOutputs: MutableList = mutableListOf() /** * The input resources that will be switched between the output providers. */ override val inputs: Set - get() = aggregator.inputs + get() = _inputs + private val _inputs = mutableSetOf() + private val _activeInputs = mutableListOf() /** - * The resource counters to track the execution metrics of all switch resources. + * The resource counters of this switch. */ - override val counters: SimResourceDistributorMaxMin.Counters - get() = distributor.counters + public override val counters: SimResourceCounters + get() = _counters + private val _counters = SimResourceCountersImpl() /** - * A flag to indicate that the switch was closed. + * The actual processing rate of the switch. */ - private var isClosed = false + private var _rate = 0.0 /** - * The aggregator to aggregate the resources. + * The demanded processing rate of the outputs. */ - private val aggregator = SimResourceAggregatorMaxMin(interpreter, parent) + private var _demand = 0.0 /** - * The distributor to distribute the aggregated resources. + * The capacity of the switch. */ - private val distributor = SimResourceDistributorMaxMin(interpreter, parent, interferenceDomain) + private var _capacity = 0.0 - init { - aggregator.startConsumer(distributor) - } + /** + * Flag to indicate that the scheduler is active. + */ + private var _schedulerActive = false /** * Add an output to the switch. */ - override fun newOutput(key: InterferenceKey?): SimResourceCloseableProvider { - check(!isClosed) { "Switch has been closed" } - - return distributor.newOutput(key) + override fun newOutput(key: InterferenceKey?): SimResourceProvider { + val provider = Output(_capacity, key) + _outputs.add(provider) + return provider } /** * Add the specified [input] to the switch. */ override fun addInput(input: SimResourceProvider) { - check(!isClosed) { "Switch has been closed" } + val consumer = Input(input) + if (_inputs.add(input)) { + _activeInputs.add(consumer) + input.startConsumer(consumer) + } + } + + /** + * Remove [output] from this switch. + */ + override fun removeOutput(output: SimResourceProvider) { + if (!_outputs.remove(output)) { + return + } + // This cast should always succeed since only `Output` instances should be added to _outputs + (output as Output).close() + } + + override fun clear() { + for (input in _activeInputs) { + input.cancel() + } + _activeInputs.clear() + + for (output in _activeOutputs) { + output.cancel() + } + _activeOutputs.clear() + } + + /** + * Run the scheduler of the switch. + */ + private fun runScheduler(now: Long) { + if (_schedulerActive) { + return + } + + _schedulerActive = true + try { + doSchedule(now) + } finally { + _schedulerActive = false + } + } + + /** + * Schedule the outputs over the input. + */ + private fun doSchedule(now: Long) { + // If there is no work yet, mark the input as idle. + if (_activeOutputs.isEmpty()) { + return + } + + val capacity = _capacity + var availableCapacity = capacity + + // Pull in the work of the outputs + val outputIterator = _activeOutputs.listIterator() + for (output in outputIterator) { + output.pull(now) + + // Remove outputs that have finished + if (!output.isActive) { + outputIterator.remove() + } + } + + var demand = 0.0 + + // Sort in-place the outputs based on their requested usage. + // Profiling shows that it is faster than maintaining some kind of sorted set. + _activeOutputs.sort() + + // Divide the available input capacity fairly across the outputs using max-min fair sharing + var remaining = _activeOutputs.size + for (output in _activeOutputs) { + val availableShare = availableCapacity / remaining-- + val grantedSpeed = min(output.allowedRate, availableShare) + + // Ignore idle computation + if (grantedSpeed <= 0.0) { + output.actualRate = 0.0 + continue + } + + demand += output.limit - aggregator.addInput(input) + output.actualRate = grantedSpeed + availableCapacity -= grantedSpeed + } + + val rate = capacity - availableCapacity + + _demand = demand + _rate = rate + + // Sort all consumers by their capacity + _activeInputs.sort() + + // Divide the requests over the available capacity of the input resources fairly + for (input in _activeInputs) { + val inputCapacity = input.capacity + val fraction = inputCapacity / capacity + val grantedSpeed = rate * fraction + + input.push(grantedSpeed) + } } - override fun close() { - if (!isClosed) { - isClosed = true - aggregator.cancel() + /** + * Recompute the capacity of the switch. + */ + private fun updateCapacity() { + val newCapacity = _activeInputs.sumOf(Input::capacity) + + // No-op if the capacity is unchanged + if (_capacity == newCapacity) { + return } + + _capacity = newCapacity + + for (output in _outputs) { + output.capacity = newCapacity + } + } + + /** + * An internal [SimResourceProvider] implementation for switch outputs. + */ + private inner class Output(capacity: Double, val key: InterferenceKey?) : + SimAbstractResourceProvider(interpreter, capacity), + SimResourceProviderLogic, + Comparable { + /** + * The requested limit. + */ + @JvmField var limit: Double = 0.0 + + /** + * The actual processing speed. + */ + @JvmField var actualRate: Double = 0.0 + + /** + * The processing speed that is allowed by the model constraints. + */ + val allowedRate: Double + get() = min(capacity, limit) + + /** + * A flag to indicate that the output is closed. + */ + private var _isClosed: Boolean = false + + /** + * The timestamp at which we received the last command. + */ + private var _lastPull: Long = Long.MIN_VALUE + + /** + * Close the output. + * + * This method is invoked when the user removes an output from the switch. + */ + fun close() { + _isClosed = true + cancel() + } + + /* SimAbstractResourceProvider */ + override fun createLogic(): SimResourceProviderLogic = this + + override fun start(ctx: SimResourceControllableContext) { + check(!_isClosed) { "Cannot re-use closed output" } + + _activeOutputs += this + super.start(ctx) + } + + /* SimResourceProviderLogic */ + override fun onConsume( + ctx: SimResourceControllableContext, + now: Long, + delta: Long, + limit: Double, + duration: Long + ) { + doUpdateCounters(delta) + + actualRate = 0.0 + this.limit = limit + _lastPull = now + + runScheduler(now) + } + + override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { + parent?.onConverge(now) + } + + override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { + doUpdateCounters(delta) + + limit = 0.0 + actualRate = 0.0 + _lastPull = now + } + + /* Comparable */ + override fun compareTo(other: Output): Int = allowedRate.compareTo(other.allowedRate) + + /** + * Pull the next command if necessary. + */ + fun pull(now: Long) { + val ctx = ctx + if (ctx != null && _lastPull < now) { + ctx.flush() + } + } + + /** + * Helper method to update the resource counters of the distributor. + */ + private fun doUpdateCounters(delta: Long) { + if (delta <= 0L) { + return + } + + // Compute the performance penalty due to resource interference + val perfScore = if (interferenceDomain != null) { + val load = _rate / capacity + interferenceDomain.apply(key, load) + } else { + 1.0 + } + + val deltaS = delta / 1000.0 + val work = limit * deltaS + val actualWork = actualRate * deltaS + val remainingWork = work - actualWork + + updateCounters(work, actualWork, remainingWork) + + val distCounters = _counters + distCounters.demand += work + distCounters.actual += actualWork + distCounters.overcommit += remainingWork + distCounters.interference += actualWork * max(0.0, 1 - perfScore) + } + } + + /** + * An internal [SimResourceConsumer] implementation for switch inputs. + */ + private inner class Input(private val provider: SimResourceProvider) : SimResourceConsumer, Comparable { + /** + * The active [SimResourceContext] of this consumer. + */ + private var _ctx: SimResourceContext? = null + + /** + * The capacity of this input. + */ + val capacity: Double + get() = _ctx?.capacity ?: 0.0 + + /** + * Push the specified rate to the provider. + */ + fun push(rate: Double) { + _ctx?.push(rate) + } + + /** + * Cancel this input. + */ + fun cancel() { + provider.cancel() + } + + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + runScheduler(now) + return Long.MAX_VALUE + } + + override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + when (event) { + SimResourceEvent.Start -> { + assert(_ctx == null) { "Consumer running concurrently" } + _ctx = ctx + updateCapacity() + } + SimResourceEvent.Exit -> { + _ctx = null + updateCapacity() + } + SimResourceEvent.Capacity -> updateCapacity() + else -> {} + } + } + + override fun compareTo(other: Input): Int = capacity.compareTo(other.capacity) } } diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt index 827019c5..01062179 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt @@ -31,12 +31,16 @@ internal class SimResourceCountersImpl : SimResourceCounters { override var demand: Double = 0.0 override var actual: Double = 0.0 override var overcommit: Double = 0.0 + override var interference: Double = 0.0 override fun reset() { demand = 0.0 actual = 0.0 overcommit = 0.0 + interference = 0.0 } - override fun toString(): String = "SimResourceCounters[demand=$demand,actual=$actual,overcommit=$overcommit]" + override fun toString(): String { + return "SimResourceCounters[demand=$demand,actual=$actual,overcommit=$overcommit,interference=$interference]" + } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt deleted file mode 100644 index f4ea5fe8..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import io.mockk.spyk -import io.mockk.verify -import kotlinx.coroutines.* -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * Test suite for the [SimResourceAggregatorMaxMin] class. - */ -internal class SimResourceAggregatorMaxMinTest { - @Test - fun testSingleCapacity() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val forwarder = SimResourceForwarder() - val sources = listOf( - forwarder, - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = SimWorkConsumer(1.0, 0.5) - val usage = mutableListOf() - val source = SimResourceSource(1.0, scheduler) - val adapter = SimSpeedConsumerAdapter(forwarder, usage::add) - source.startConsumer(adapter) - - aggregator.consume(consumer) - yield() - - assertAll( - { assertEquals(1000, clock.millis()) }, - { assertEquals(listOf(0.0, 0.5, 0.0), usage) } - ) - } - - @Test - fun testDoubleCapacity() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val sources = listOf( - SimResourceSource(1.0, scheduler), - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = SimWorkConsumer(2.0, 1.0) - val usage = mutableListOf() - val adapter = SimSpeedConsumerAdapter(consumer, usage::add) - - aggregator.consume(adapter) - yield() - assertAll( - { assertEquals(1000, clock.millis()) }, - { assertEquals(listOf(0.0, 2.0, 0.0), usage) } - ) - } - - @Test - fun testOvercommit() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val sources = listOf( - SimResourceSource(1.0, scheduler), - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = spyk(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(4.0) - 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - }) - - aggregator.consume(consumer) - yield() - assertEquals(1000, clock.millis()) - - verify(exactly = 2) { consumer.onNext(any(), any(), any()) } - } - - @Test - fun testAdjustCapacity() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val sources = listOf( - SimResourceSource(1.0, scheduler), - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = SimWorkConsumer(4.0, 1.0) - coroutineScope { - launch { aggregator.consume(consumer) } - delay(1000) - sources[0].capacity = 0.5 - } - yield() - assertEquals(2333, clock.millis()) - } - - @Test - fun testFailOverCapacity() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val sources = listOf( - SimResourceSource(1.0, scheduler), - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = SimWorkConsumer(1.0, 0.5) - coroutineScope { - launch { aggregator.consume(consumer) } - delay(500) - sources[0].capacity = 0.5 - } - yield() - assertEquals(1167, clock.millis()) - } - - @Test - fun testCounters() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val aggregator = SimResourceAggregatorMaxMin(scheduler) - val sources = listOf( - SimResourceSource(1.0, scheduler), - SimResourceSource(1.0, scheduler) - ) - sources.forEach(aggregator::addInput) - - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(4.0) - 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - } - - aggregator.consume(consumer) - yield() - assertEquals(1000, clock.millis()) - assertEquals(2.0, aggregator.counters.actual) { "Actual work mismatch" } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt index 9f86dc0d..49f2da5f 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt @@ -65,13 +65,8 @@ internal class SimResourceSwitchExclusiveTest { switch.addInput(forwarder) val provider = switch.newOutput() - - try { - provider.consume(workload) - yield() - } finally { - provider.close() - } + provider.consume(workload) + yield() assertAll( { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, @@ -95,13 +90,9 @@ internal class SimResourceSwitchExclusiveTest { switch.addInput(source) val provider = switch.newOutput() + provider.consume(workload) + yield() - try { - provider.consume(workload) - yield() - } finally { - provider.close() - } assertEquals(duration, clock.millis()) { "Took enough time" } } @@ -141,14 +132,9 @@ internal class SimResourceSwitchExclusiveTest { switch.addInput(source) val provider = switch.newOutput() - - try { - provider.consume(workload) - yield() - provider.consume(workload) - } finally { - provider.close() - } + provider.consume(workload) + yield() + provider.consume(workload) assertEquals(duration * 2, clock.millis()) { "Took enough time" } } diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt index ba0d66ff..03f90e21 100644 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt @@ -51,7 +51,7 @@ internal class SimResourceSwitchMaxMinTest { provider.consume(consumer) yield() } finally { - switch.close() + switch.clear() } } @@ -81,7 +81,7 @@ internal class SimResourceSwitchMaxMinTest { provider.consume(workload) yield() } finally { - switch.close() + switch.clear() } assertAll( @@ -133,7 +133,7 @@ internal class SimResourceSwitchMaxMinTest { yield() } finally { - switch.close() + switch.clear() } assertAll( { assertEquals(2073600.0, switch.counters.demand, "Requested work does not match") }, -- cgit v1.2.3 From dd605ab1f70fef1fbbed848e8ebbd6b231622273 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 22:20:48 +0200 Subject: refactor(simulator): Remove transform from SimResourceForwarder This change removes the ability to transform the duration of a pull from the SimResourceForwarder class. This ability is not used anymore, since pushes are now done using a method instead of a command. --- .../kotlin/org/opendc/simulator/power/SimPdu.kt | 2 +- .../kotlin/org/opendc/simulator/power/SimUps.kt | 2 +- .../simulator/resources/SimResourceForwarder.kt | 220 +++++++++++++++++++ .../resources/SimResourceSwitchExclusive.kt | 4 +- .../simulator/resources/SimResourceTransformer.kt | 238 --------------------- .../resources/SimResourceForwarderTest.kt | 220 +++++++++++++++++++ .../resources/SimResourceTransformerTest.kt | 234 -------------------- 7 files changed, 444 insertions(+), 476 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt create mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index 947f6cb2..1a12a52a 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -42,7 +42,7 @@ public class SimPdu( private val switch = SimResourceSwitchMaxMin(interpreter) /** - * The [SimResourceTransformer] that represents the input of the PDU. + * The [SimResourceForwarder] that represents the input of the PDU. */ private val forwarder = SimResourceForwarder() diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 79c1b37d..9c7400ed 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -86,7 +86,7 @@ public class SimUps( /** * A UPS inlet. */ - public inner class Inlet(private val forwarder: SimResourceTransformer) : SimPowerInlet(), AutoCloseable { + public inner class Inlet(private val forwarder: SimResourceForwarder) : SimPowerInlet(), AutoCloseable { override fun createConsumer(): SimResourceConsumer = forwarder /** diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt new file mode 100644 index 00000000..0cd2bfc7 --- /dev/null +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.resources + +import org.opendc.simulator.resources.impl.SimResourceCountersImpl +import java.time.Clock + +/** + * A class that acts as a [SimResourceConsumer] and [SimResourceProvider] at the same time. + * + * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. + */ +public class SimResourceForwarder(private val isCoupled: Boolean = false) : SimResourceConsumer, SimResourceProvider, AutoCloseable { + /** + * The delegate [SimResourceConsumer]. + */ + private var delegate: SimResourceConsumer? = null + + /** + * A flag to indicate that the delegate was started. + */ + private var hasDelegateStarted: Boolean = false + + /** + * The exposed [SimResourceContext]. + */ + private val _ctx = object : SimResourceContext { + override val clock: Clock + get() = _innerCtx!!.clock + + override val capacity: Double + get() = _innerCtx?.capacity ?: 0.0 + + override val demand: Double + get() = _innerCtx?.demand ?: 0.0 + + override val speed: Double + get() = _innerCtx?.speed ?: 0.0 + + override fun interrupt() { + _innerCtx?.interrupt() + } + + override fun push(rate: Double) { + _innerCtx?.push(rate) + _limit = rate + } + + override fun close() { + val delegate = checkNotNull(delegate) { "Delegate not active" } + + if (isCoupled) + _innerCtx?.close() + else + _innerCtx?.push(0.0) + + // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we + // reset beforehand the existing state and check whether it has been updated afterwards + reset() + + delegate.onEvent(this, SimResourceEvent.Exit) + } + } + + /** + * The [SimResourceContext] in which the forwarder runs. + */ + private var _innerCtx: SimResourceContext? = null + + override val isActive: Boolean + get() = delegate != null + + override val capacity: Double + get() = _ctx.capacity + + override val speed: Double + get() = _ctx.speed + + override val demand: Double + get() = _ctx.demand + + override val counters: SimResourceCounters + get() = _counters + private val _counters = SimResourceCountersImpl() + + override fun startConsumer(consumer: SimResourceConsumer) { + check(delegate == null) { "Resource transformer already active" } + + delegate = consumer + + // Interrupt the provider to replace the consumer + interrupt() + } + + override fun interrupt() { + _ctx.interrupt() + } + + override fun cancel() { + val delegate = delegate + val ctx = _innerCtx + + if (delegate != null) { + this.delegate = null + + if (ctx != null) { + delegate.onEvent(this._ctx, SimResourceEvent.Exit) + } + } + } + + override fun close() { + val ctx = _innerCtx + + if (ctx != null) { + this._innerCtx = null + ctx.interrupt() + } + } + + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + val delegate = delegate + + if (!hasDelegateStarted) { + start() + } + + updateCounters(ctx, delta) + + return delegate?.onNext(this._ctx, now, delta) ?: Long.MAX_VALUE + } + + override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + when (event) { + SimResourceEvent.Start -> { + _innerCtx = ctx + } + SimResourceEvent.Exit -> { + _innerCtx = null + + val delegate = delegate + if (delegate != null) { + reset() + delegate.onEvent(this._ctx, SimResourceEvent.Exit) + } + } + else -> delegate?.onEvent(this._ctx, event) + } + } + + override fun onFailure(ctx: SimResourceContext, cause: Throwable) { + _innerCtx = null + + val delegate = delegate + if (delegate != null) { + reset() + delegate.onFailure(this._ctx, cause) + } + } + + /** + * Start the delegate. + */ + private fun start() { + val delegate = delegate ?: return + delegate.onEvent(checkNotNull(_innerCtx), SimResourceEvent.Start) + + hasDelegateStarted = true + } + + /** + * Reset the delegate. + */ + private fun reset() { + delegate = null + hasDelegateStarted = false + } + + /** + * The requested speed. + */ + private var _limit: Double = 0.0 + + /** + * Update the resource counters for the transformer. + */ + private fun updateCounters(ctx: SimResourceContext, delta: Long) { + if (delta <= 0) { + return + } + + val counters = _counters + val deltaS = delta / 1000.0 + val work = _limit * deltaS + val actualWork = ctx.speed * deltaS + counters.demand += work + counters.actual += actualWork + counters.overcommit += (work - actualWork) + } +} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt index 2be8ccb0..f1e004d2 100644 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt +++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt @@ -37,7 +37,7 @@ public class SimResourceSwitchExclusive : SimResourceSwitch { private val _inputs = mutableSetOf() override val inputs: Set get() = _inputs - private val _availableInputs = ArrayDeque() + private val _availableInputs = ArrayDeque() override val counters: SimResourceCounters = object : SimResourceCounters { override val demand: Double @@ -114,7 +114,7 @@ public class SimResourceSwitchExclusive : SimResourceSwitch { /** * An output of the resource switch. */ - private inner class Output(private val forwarder: SimResourceTransformer) : SimResourceProvider by forwarder { + private inner class Output(private val forwarder: SimResourceForwarder) : SimResourceProvider by forwarder { /** * Close the output. */ diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt deleted file mode 100644 index 76a3bdd7..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.impl.SimResourceCountersImpl -import java.time.Clock - -/** - * A [SimResourceConsumer] and [SimResourceProvider] that transforms the resource commands emitted by the resource - * commands to the resource provider. - * - * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. - * @param transform The function to transform the received resource command. - */ -public class SimResourceTransformer( - private val isCoupled: Boolean = false, - private val transform: (SimResourceContext, Long) -> Long -) : SimResourceConsumer, SimResourceProvider, AutoCloseable { - /** - * The delegate [SimResourceConsumer]. - */ - private var delegate: SimResourceConsumer? = null - - /** - * A flag to indicate that the delegate was started. - */ - private var hasDelegateStarted: Boolean = false - - /** - * The exposed [SimResourceContext]. - */ - private val ctx = object : SimResourceContext { - override val clock: Clock - get() = _ctx!!.clock - - override val capacity: Double - get() = _ctx?.capacity ?: 0.0 - - override val demand: Double - get() = _ctx?.demand ?: 0.0 - - override val speed: Double - get() = _ctx?.speed ?: 0.0 - - override fun interrupt() { - _ctx?.interrupt() - } - - override fun push(rate: Double) { - _ctx?.push(rate) - _limit = rate - } - - override fun close() { - val delegate = checkNotNull(delegate) { "Delegate not active" } - - if (isCoupled) - _ctx?.close() - else - _ctx?.push(0.0) - - // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we - // reset beforehand the existing state and check whether it has been updated afterwards - reset() - - delegate.onEvent(this, SimResourceEvent.Exit) - } - } - - /** - * The [SimResourceContext] in which the forwarder runs. - */ - private var _ctx: SimResourceContext? = null - - override val isActive: Boolean - get() = delegate != null - - override val capacity: Double - get() = ctx.capacity - - override val speed: Double - get() = ctx.speed - - override val demand: Double - get() = ctx.demand - - override val counters: SimResourceCounters - get() = _counters - private val _counters = SimResourceCountersImpl() - - override fun startConsumer(consumer: SimResourceConsumer) { - check(delegate == null) { "Resource transformer already active" } - - delegate = consumer - - // Interrupt the provider to replace the consumer - interrupt() - } - - override fun interrupt() { - ctx.interrupt() - } - - override fun cancel() { - val delegate = delegate - val ctx = _ctx - - if (delegate != null) { - this.delegate = null - - if (ctx != null) { - delegate.onEvent(this.ctx, SimResourceEvent.Exit) - } - } - } - - override fun close() { - val ctx = _ctx - - if (ctx != null) { - this._ctx = null - ctx.interrupt() - } - } - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val delegate = delegate - - if (!hasDelegateStarted) { - start() - } - - updateCounters(ctx, delta) - - return if (delegate != null) { - transform(ctx, delegate.onNext(this.ctx, now, delta)) - } else { - Long.MAX_VALUE - } - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - _ctx = ctx - } - SimResourceEvent.Exit -> { - _ctx = null - - val delegate = delegate - if (delegate != null) { - reset() - delegate.onEvent(this.ctx, SimResourceEvent.Exit) - } - } - else -> delegate?.onEvent(this.ctx, event) - } - } - - override fun onFailure(ctx: SimResourceContext, cause: Throwable) { - _ctx = null - - val delegate = delegate - if (delegate != null) { - reset() - delegate.onFailure(this.ctx, cause) - } - } - - /** - * Start the delegate. - */ - private fun start() { - val delegate = delegate ?: return - delegate.onEvent(checkNotNull(_ctx), SimResourceEvent.Start) - - hasDelegateStarted = true - } - - /** - * Reset the delegate. - */ - private fun reset() { - delegate = null - hasDelegateStarted = false - } - - /** - * The requested speed. - */ - private var _limit: Double = 0.0 - - /** - * Update the resource counters for the transformer. - */ - private fun updateCounters(ctx: SimResourceContext, delta: Long) { - if (delta <= 0) { - return - } - - val counters = _counters - val deltaS = delta / 1000.0 - val work = _limit * deltaS - val actualWork = ctx.speed * deltaS - counters.demand += work - counters.actual += actualWork - counters.overcommit += (work - actualWork) - } -} - -/** - * Constructs a [SimResourceTransformer] that forwards the received resource command with an identity transform. - * - * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. - */ -public fun SimResourceForwarder(isCoupled: Boolean = false): SimResourceTransformer { - return SimResourceTransformer(isCoupled) { _, command -> command } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt new file mode 100644 index 00000000..49e60f68 --- /dev/null +++ b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.resources + +import io.mockk.spyk +import io.mockk.verify +import kotlinx.coroutines.* +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl + +/** + * A test suite for the [SimResourceForwarder] class. + */ +internal class SimResourceForwarderTest { + @Test + fun testCancelImmediately() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(2000.0, scheduler) + + launch { source.consume(forwarder) } + + forwarder.consume(object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + }) + + forwarder.close() + source.cancel() + } + + @Test + fun testCancel() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(2000.0, scheduler) + + launch { source.consume(forwarder) } + + forwarder.consume(object : SimResourceConsumer { + var isFirst = true + + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + ctx.push(1.0) + 10 * 1000 + } else { + ctx.close() + Long.MAX_VALUE + } + } + }) + + forwarder.close() + source.cancel() + } + + @Test + fun testState() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + } + + assertFalse(forwarder.isActive) + + forwarder.startConsumer(consumer) + assertTrue(forwarder.isActive) + + assertThrows { forwarder.startConsumer(consumer) } + + forwarder.cancel() + assertFalse(forwarder.isActive) + + forwarder.close() + assertFalse(forwarder.isActive) + } + + @Test + fun testCancelPendingDelegate() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + + val consumer = spyk(object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + }) + + forwarder.startConsumer(consumer) + forwarder.cancel() + + verify(exactly = 0) { consumer.onEvent(any(), SimResourceEvent.Exit) } + } + + @Test + fun testCancelStartedDelegate() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(2000.0, scheduler) + + val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) + + source.startConsumer(forwarder) + yield() + forwarder.startConsumer(consumer) + yield() + forwarder.cancel() + + verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Start) } + verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Exit) } + } + + @Test + fun testCancelPropagation() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(2000.0, scheduler) + + val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) + + source.startConsumer(forwarder) + yield() + forwarder.startConsumer(consumer) + yield() + source.cancel() + + verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Start) } + verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Exit) } + } + + @Test + fun testExitPropagation() = runBlockingSimulation { + val forwarder = SimResourceForwarder(isCoupled = true) + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(2000.0, scheduler) + + val consumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + ctx.close() + return Long.MAX_VALUE + } + } + + source.startConsumer(forwarder) + forwarder.consume(consumer) + yield() + + assertFalse(forwarder.isActive) + } + + @Test + fun testAdjustCapacity() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(1.0, scheduler) + + val consumer = spyk(SimWorkConsumer(2.0, 1.0)) + source.startConsumer(forwarder) + + coroutineScope { + launch { forwarder.consume(consumer) } + delay(1000) + source.capacity = 0.5 + } + + assertEquals(3000, clock.millis()) + verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Capacity) } + } + + @Test + fun testCounters() = runBlockingSimulation { + val forwarder = SimResourceForwarder() + val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) + val source = SimResourceSource(1.0, scheduler) + + val consumer = SimWorkConsumer(2.0, 1.0) + source.startConsumer(forwarder) + + forwarder.consume(consumer) + + yield() + + assertEquals(2.0, source.counters.actual) + assertEquals(source.counters.actual, forwarder.counters.actual) { "Actual work" } + assertEquals(source.counters.demand, forwarder.counters.demand) { "Work demand" } + assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } + assertEquals(2000, clock.millis()) + } +} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt deleted file mode 100644 index d7d0924f..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import io.mockk.spyk -import io.mockk.verify -import kotlinx.coroutines.* -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * A test suite for the [SimResourceTransformer] class. - */ -internal class SimResourceTransformerTest { - @Test - fun testCancelImmediately() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - launch { source.consume(forwarder) } - - forwarder.consume(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - }) - - forwarder.close() - source.cancel() - } - - @Test - fun testCancel() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - launch { source.consume(forwarder) } - - forwarder.consume(object : SimResourceConsumer { - var isFirst = true - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - ctx.push(1.0) - 10 * 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - }) - - forwarder.close() - source.cancel() - } - - @Test - fun testState() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - } - - assertFalse(forwarder.isActive) - - forwarder.startConsumer(consumer) - assertTrue(forwarder.isActive) - - assertThrows { forwarder.startConsumer(consumer) } - - forwarder.cancel() - assertFalse(forwarder.isActive) - - forwarder.close() - assertFalse(forwarder.isActive) - } - - @Test - fun testCancelPendingDelegate() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - - val consumer = spyk(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - }) - - forwarder.startConsumer(consumer) - forwarder.cancel() - - verify(exactly = 0) { consumer.onEvent(any(), SimResourceEvent.Exit) } - } - - @Test - fun testCancelStartedDelegate() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) - - source.startConsumer(forwarder) - yield() - forwarder.startConsumer(consumer) - yield() - forwarder.cancel() - - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Start) } - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Exit) } - } - - @Test - fun testCancelPropagation() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) - - source.startConsumer(forwarder) - yield() - forwarder.startConsumer(consumer) - yield() - source.cancel() - - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Start) } - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Exit) } - } - - @Test - fun testExitPropagation() = runBlockingSimulation { - val forwarder = SimResourceForwarder(isCoupled = true) - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - } - - source.startConsumer(forwarder) - forwarder.consume(consumer) - yield() - - assertFalse(forwarder.isActive) - } - - @Test - fun testAdjustCapacity() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(1.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2.0, 1.0)) - source.startConsumer(forwarder) - - coroutineScope { - launch { forwarder.consume(consumer) } - delay(1000) - source.capacity = 0.5 - } - - assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Capacity) } - } - - @Test - fun testTransformExit() = runBlockingSimulation { - val forwarder = SimResourceTransformer { ctx, _ -> ctx.close(); Long.MAX_VALUE } - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(1.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2.0, 1.0)) - source.startConsumer(forwarder) - forwarder.consume(consumer) - - assertEquals(0, clock.millis()) - verify(exactly = 1) { consumer.onNext(any(), any(), any()) } - } - - @Test - fun testCounters() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(1.0, scheduler) - - val consumer = SimWorkConsumer(2.0, 1.0) - source.startConsumer(forwarder) - - forwarder.consume(consumer) - - yield() - - assertEquals(2.0, source.counters.actual) - assertEquals(source.counters.actual, forwarder.counters.actual) { "Actual work" } - assertEquals(source.counters.demand, forwarder.counters.demand) { "Work demand" } - assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } - assertEquals(2000, clock.millis()) - } -} -- cgit v1.2.3 From 4cc1d40d421c8736f8b21b360b61d6b065158b7a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 29 Sep 2021 23:56:16 +0200 Subject: refactor(simulator): Migrate to flow-based simulation This change renames the `opendc-simulator-resources` module into the `opendc-simulator-flow` module to indicate that the core simulation model of OpenDC is based around modelling and simulating flows. Previously, the distinction between resource consumer and provider, and input and output caused some confusion. By switching to a flow-based model, this distinction is now clear (as in, the water flows from source to consumer/sink). --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 10 +- .../org/opendc/compute/simulator/internal/Guest.kt | 2 +- .../simulator/internal/HostFaultInjectorImpl.kt | 2 +- .../org/opendc/compute/simulator/SimHostTest.kt | 10 +- .../compute/workload/ComputeWorkloadRunner.kt | 10 +- .../org/opendc/experiments/capelin/Portfolio.kt | 2 +- .../opendc/experiments/tf20/core/SimTFDevice.kt | 42 +-- .../opendc/experiments/tf20/distribute/Strategy.kt | 2 +- .../opendc/faas/simulator/SimFunctionDeployer.kt | 4 +- .../opendc-simulator-compute/build.gradle.kts | 2 +- .../simulator/compute/SimMachineBenchmarks.kt | 20 +- .../opendc/simulator/compute/SimAbstractMachine.kt | 49 +-- .../simulator/compute/SimBareMetalMachine.kt | 18 +- .../org/opendc/simulator/compute/SimMachine.kt | 2 +- .../opendc/simulator/compute/SimMachineContext.kt | 6 +- .../org/opendc/simulator/compute/SimMemory.kt | 4 +- .../simulator/compute/SimNetworkInterface.kt | 8 +- .../opendc/simulator/compute/SimProcessingUnit.kt | 4 +- .../simulator/compute/SimStorageInterface.kt | 6 +- .../org/opendc/simulator/compute/device/SimPsu.kt | 24 +- .../compute/kernel/SimAbstractHypervisor.kt | 38 +- .../compute/kernel/SimFairShareHypervisor.kt | 30 +- .../kernel/SimFairShareHypervisorProvider.kt | 10 +- .../simulator/compute/kernel/SimHypervisor.kt | 4 +- .../compute/kernel/SimHypervisorProvider.kt | 8 +- .../compute/kernel/SimSpaceSharedHypervisor.kt | 16 +- .../kernel/SimSpaceSharedHypervisorProvider.kt | 10 +- .../kernel/interference/VmInterferenceDomain.kt | 4 +- .../kernel/interference/VmInterferenceModel.kt | 2 +- .../simulator/compute/power/PStatePowerDriver.kt | 2 +- .../simulator/compute/power/SimplePowerDriver.kt | 2 +- .../simulator/compute/workload/SimFlopsWorkload.kt | 4 +- .../compute/workload/SimRuntimeWorkload.kt | 4 +- .../simulator/compute/workload/SimTraceWorkload.kt | 14 +- .../compute/workload/SimWorkloadLifecycle.kt | 26 +- .../org/opendc/simulator/compute/SimMachineTest.kt | 48 +-- .../opendc/simulator/compute/device/SimPsuTest.kt | 10 +- .../simulator/compute/kernel/SimHypervisorTest.kt | 10 +- .../compute/kernel/SimSpaceSharedHypervisorTest.kt | 36 +- .../compute/power/PStatePowerDriverTest.kt | 10 +- .../compute/workload/SimTraceWorkloadTest.kt | 10 +- .../opendc-simulator-flow/build.gradle.kts | 38 ++ .../org/opendc/simulator/flow/FlowBenchmarks.kt | 140 +++++++ .../opendc/simulator/flow/AbstractFlowConsumer.kt | 143 ++++++++ .../org/opendc/simulator/flow/FlowConnection.kt | 60 +++ .../org/opendc/simulator/flow/FlowConsumer.kt | 109 ++++++ .../opendc/simulator/flow/FlowConsumerContext.kt | 45 +++ .../org/opendc/simulator/flow/FlowConsumerLogic.kt | 56 +++ .../org/opendc/simulator/flow/FlowCounters.kt | 53 +++ .../kotlin/org/opendc/simulator/flow/FlowEngine.kt | 95 +++++ .../kotlin/org/opendc/simulator/flow/FlowEvent.kt | 48 +++ .../org/opendc/simulator/flow/FlowForwarder.kt | 217 +++++++++++ .../kotlin/org/opendc/simulator/flow/FlowSink.kt | 61 +++ .../kotlin/org/opendc/simulator/flow/FlowSource.kt | 58 +++ .../kotlin/org/opendc/simulator/flow/FlowSystem.kt | 43 +++ .../flow/interference/InterferenceDomain.kt | 19 + .../simulator/flow/interference/InterferenceKey.kt | 28 ++ .../flow/internal/FlowConsumerContextImpl.kt | 356 ++++++++++++++++++ .../simulator/flow/internal/FlowCountersImpl.kt | 46 +++ .../simulator/flow/internal/FlowEngineImpl.kt | 297 +++++++++++++++ .../opendc/simulator/flow/mux/FlowMultiplexer.kt | 70 ++++ .../flow/mux/ForwardingFlowMultiplexer.kt | 127 +++++++ .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 399 ++++++++++++++++++++ .../simulator/flow/source/FixedFlowSource.kt | 57 +++ .../simulator/flow/source/FlowSourceBarrier.kt | 52 +++ .../simulator/flow/source/FlowSourceRateAdapter.kt | 82 +++++ .../simulator/flow/source/TraceFlowSource.kt | 72 ++++ .../simulator/flow/FlowConsumerContextTest.kt | 152 ++++++++ .../org/opendc/simulator/flow/FlowForwarderTest.kt | 222 +++++++++++ .../org/opendc/simulator/flow/FlowSinkTest.kt | 240 ++++++++++++ .../flow/mux/SimResourceSwitchExclusiveTest.kt | 157 ++++++++ .../flow/mux/SimResourceSwitchMaxMinTest.kt | 147 ++++++++ .../simulator/flow/source/FixedFlowSourceTest.kt | 57 +++ .../opendc-simulator-network/build.gradle.kts | 2 +- .../org/opendc/simulator/network/SimNetworkPort.kt | 12 +- .../org/opendc/simulator/network/SimNetworkSink.kt | 10 +- .../simulator/network/SimNetworkSwitchVirtual.kt | 21 +- .../opendc/simulator/network/SimNetworkSinkTest.kt | 50 +-- .../network/SimNetworkSwitchVirtualTest.kt | 28 +- .../opendc-simulator-power/build.gradle.kts | 2 +- .../kotlin/org/opendc/simulator/power/SimPdu.kt | 36 +- .../org/opendc/simulator/power/SimPowerInlet.kt | 6 +- .../org/opendc/simulator/power/SimPowerSource.kt | 12 +- .../kotlin/org/opendc/simulator/power/SimUps.kt | 33 +- .../org/opendc/simulator/power/SimPduTest.kt | 52 +-- .../opendc/simulator/power/SimPowerSourceTest.kt | 46 +-- .../org/opendc/simulator/power/SimUpsTest.kt | 44 +-- .../opendc-simulator-resources/build.gradle.kts | 38 -- .../simulator/resources/SimResourceBenchmarks.kt | 138 ------- .../resources/SimAbstractResourceProvider.kt | 146 -------- .../simulator/resources/SimResourceConsumer.kt | 57 --- .../simulator/resources/SimResourceContext.kt | 68 ---- .../resources/SimResourceControllableContext.kt | 54 --- .../simulator/resources/SimResourceCounters.kt | 53 --- .../opendc/simulator/resources/SimResourceEvent.kt | 48 --- .../simulator/resources/SimResourceForwarder.kt | 220 ----------- .../simulator/resources/SimResourceInterpreter.kt | 94 ----- .../simulator/resources/SimResourceProvider.kt | 106 ------ .../resources/SimResourceProviderLogic.kt | 58 --- .../simulator/resources/SimResourceSource.kt | 61 --- .../simulator/resources/SimResourceSwitch.kt | 67 ---- .../resources/SimResourceSwitchExclusive.kt | 129 ------- .../simulator/resources/SimResourceSwitchMaxMin.kt | 407 --------------------- .../simulator/resources/SimResourceSystem.kt | 43 --- .../resources/consumer/SimConsumerBarrier.kt | 52 --- .../resources/consumer/SimSpeedConsumerAdapter.kt | 82 ----- .../resources/consumer/SimTraceConsumer.kt | 73 ---- .../resources/consumer/SimWorkConsumer.kt | 61 --- .../resources/impl/SimResourceContextImpl.kt | 367 ------------------- .../resources/impl/SimResourceCountersImpl.kt | 46 --- .../resources/impl/SimResourceInterpreterImpl.kt | 298 --------------- .../resources/interference/InterferenceDomain.kt | 19 - .../resources/interference/InterferenceKey.kt | 28 -- .../simulator/resources/SimResourceContextTest.kt | 173 --------- .../resources/SimResourceForwarderTest.kt | 220 ----------- .../simulator/resources/SimResourceSourceTest.kt | 240 ------------ .../resources/SimResourceSwitchExclusiveTest.kt | 156 -------- .../resources/SimResourceSwitchMaxMinTest.kt | 145 -------- .../simulator/resources/SimWorkConsumerTest.kt | 56 --- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 6 +- .../opendc/workflow/service/WorkflowServiceTest.kt | 4 +- settings.gradle.kts | 2 +- 122 files changed, 4193 insertions(+), 4247 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-flow/build.gradle.kts create mode 100644 opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEngine.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceDomain.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceKey.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FixedFlowSource.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceBarrier.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/source/FixedFlowSourceTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/build.gradle.kts delete mode 100644 opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceEvent.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSystem.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimConsumerBarrier.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceDomain.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceKey.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt delete mode 100644 opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index a8b8afe9..f499927d 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -47,7 +47,7 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine import java.util.* import kotlin.coroutines.CoroutineContext import kotlin.math.roundToLong @@ -61,7 +61,7 @@ public class SimHost( model: MachineModel, override val meta: Map, context: CoroutineContext, - interpreter: SimResourceInterpreter, + engine: FlowEngine, meterProvider: MeterProvider, hypervisor: SimHypervisorProvider, scalingGovernor: ScalingGovernor = PerformanceScalingGovernor(), @@ -78,7 +78,7 @@ public class SimHost( /** * The clock instance used by the host. */ - private val clock = interpreter.clock + private val clock = engine.clock /** * The logger instance of this server. @@ -98,13 +98,13 @@ public class SimHost( /** * The machine to run on. */ - public val machine: SimBareMetalMachine = SimBareMetalMachine(interpreter, model.optimize(), powerDriver) + public val machine: SimBareMetalMachine = SimBareMetalMachine(engine, model.optimize(), powerDriver) /** * The hypervisor to run multiple workloads. */ private val hypervisor: SimHypervisor = hypervisor.create( - interpreter, + engine, scalingGovernor = scalingGovernor, interferenceDomain = interferenceDomain, listener = object : SimHypervisor.Listener { diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index 7f33154a..eda76ba0 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -198,7 +198,7 @@ internal class Guest( } /** - * Run the process that models the virtual machine lifecycle as a coroutine. + * Converge the process that models the virtual machine lifecycle as a coroutine. */ private suspend fun runMachine(workload: SimWorkload) { delay(1) // TODO Introduce model for boot time diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt index 6919b7fd..7d46e626 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt @@ -75,7 +75,7 @@ internal class HostFaultInjectorImpl( } /** - * Run the injection process. + * Converge the injection process. */ private suspend fun runInjector() { while (true) { diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index e75c31a0..d2293be7 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -41,7 +41,7 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine import org.opendc.telemetry.compute.ComputeMetricExporter import org.opendc.telemetry.compute.HOST_ID import org.opendc.telemetry.compute.table.HostData @@ -87,14 +87,14 @@ internal class SimHostTest { .setClock(clock.toOtelClock()) .build() - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val virtDriver = SimHost( uid = hostId, name = "test", model = machineModel, meta = emptyMap(), coroutineContext, - interpreter, + engine, meterProvider, SimFairShareHypervisorProvider() ) @@ -199,14 +199,14 @@ internal class SimHostTest { .setClock(clock.toOtelClock()) .build() - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val host = SimHost( uid = hostId, name = "test", model = machineModel, meta = emptyMap(), coroutineContext, - interpreter, + engine, meterProvider, SimFairShareHypervisorProvider() ) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt index ed45bd8a..283f82fe 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadRunner.kt @@ -36,7 +36,7 @@ import org.opendc.compute.simulator.SimHost import org.opendc.compute.workload.topology.HostSpec import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine import org.opendc.telemetry.compute.* import org.opendc.telemetry.sdk.toOtelClock import java.time.Clock @@ -73,9 +73,9 @@ public class ComputeWorkloadRunner( private val _metricProducers = mutableListOf() /** - * The [SimResourceInterpreter] to simulate the hosts. + * The [FlowEngine] to simulate the hosts. */ - private val interpreter = SimResourceInterpreter(context, clock) + private val engine = FlowEngine(context, clock) /** * The hosts that belong to this class. @@ -89,7 +89,7 @@ public class ComputeWorkloadRunner( } /** - * Run a simulation of the [ComputeService] by replaying the workload trace given by [trace]. + * Converge a simulation of the [ComputeService] by replaying the workload trace given by [trace]. */ public suspend fun run(trace: List, seed: Long) { val random = Random(seed) @@ -178,7 +178,7 @@ public class ComputeWorkloadRunner( spec.model, spec.meta, context, - interpreter, + engine, meterProvider, spec.hypervisor, powerDriver = spec.powerDriver, diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index 21ff3ab0..4e855f82 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -131,7 +131,7 @@ abstract class Portfolio(name: String) : Experiment(name) { // Instantiate the desired topology runner.apply(topology) - // Run the workload trace + // Converge the workload trace runner.run(workload.source.resolve(workloadLoader, seeder), seeder.nextLong()) } finally { runner.close() diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index 1fbd3b6a..2ba65e90 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -35,7 +35,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.PowerModel import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.resources.* +import org.opendc.simulator.flow.* import java.time.Clock import java.util.* import kotlin.coroutines.Continuation @@ -65,7 +65,7 @@ public class SimTFDevice( * The [SimMachine] representing the device. */ private val machine = SimBareMetalMachine( - SimResourceInterpreter(scope.coroutineContext, clock), MachineModel(listOf(pu), listOf(memory)), + FlowEngine(scope.coroutineContext, clock), MachineModel(listOf(pu), listOf(memory)), SimplePowerDriver(powerModel) ) @@ -95,11 +95,11 @@ public class SimTFDevice( /** * The workload that will be run by the device. */ - private val workload = object : SimWorkload, SimResourceConsumer { + private val workload = object : SimWorkload, FlowSource { /** * The resource context to interrupt the workload with. */ - var ctx: SimResourceContext? = null + var ctx: FlowConnection? = null /** * The capacity of the device. @@ -128,16 +128,16 @@ public class SimTFDevice( } } - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val consumedWork = ctx.speed * delta / 1000.0 + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val consumedWork = conn.rate * delta / 1000.0 val activeWork = activeWork if (activeWork != null) { if (activeWork.consume(consumedWork)) { this.activeWork = null } else { - val duration = (activeWork.flops / ctx.capacity * 1000).roundToLong() - ctx.push(ctx.capacity) + val duration = (activeWork.flops / conn.capacity * 1000).roundToLong() + conn.push(conn.capacity) return duration } } @@ -146,27 +146,27 @@ public class SimTFDevice( val head = queue.poll() return if (head != null) { this.activeWork = head - val duration = (head.flops / ctx.capacity * 1000).roundToLong() - ctx.push(ctx.capacity) + val duration = (head.flops / conn.capacity * 1000).roundToLong() + conn.push(conn.capacity) duration } else { - ctx.push(0.0) + conn.push(0.0) Long.MAX_VALUE } } - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { when (event) { - SimResourceEvent.Start -> { - this.ctx = ctx - this.capacity = ctx.capacity + FlowEvent.Start -> { + this.ctx = conn + this.capacity = conn.capacity } - SimResourceEvent.Capacity -> { - this.capacity = ctx.capacity - ctx.interrupt() + FlowEvent.Capacity -> { + this.capacity = conn.capacity + conn.pull() } - SimResourceEvent.Run -> { - _usage.record(ctx.speed) + FlowEvent.Converge -> { + _usage.record(conn.rate) _power.record(machine.psu.powerDraw) } else -> {} @@ -188,7 +188,7 @@ public class SimTFDevice( override suspend fun compute(flops: Double) = suspendCancellableCoroutine { cont -> workload.queue.add(Work(flops, cont)) if (workload.isIdle) { - workload.ctx?.interrupt() + workload.ctx?.pull() } } diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt index 5839c0df..3e755b56 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt @@ -27,7 +27,7 @@ package org.opendc.experiments.tf20.distribute */ public interface Strategy { /** - * Run the specified batch using the given strategy. + * Converge the specified batch using the given strategy. */ public suspend fun run(forward: Double, backward: Double, batchSize: Int) } diff --git a/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt b/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt index 68bdc337..020d75b5 100644 --- a/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt +++ b/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt @@ -36,7 +36,7 @@ import org.opendc.simulator.compute.SimMachine import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine import java.time.Clock import java.util.ArrayDeque import kotlin.coroutines.Continuation @@ -74,7 +74,7 @@ public class SimFunctionDeployer( * The machine that will execute the workloads. */ public val machine: SimMachine = SimBareMetalMachine( - SimResourceInterpreter(scope.coroutineContext, clock), + FlowEngine(scope.coroutineContext, clock), model, SimplePowerDriver(ConstantPowerModel(0.0)) ) diff --git a/opendc-simulator/opendc-simulator-compute/build.gradle.kts b/opendc-simulator/opendc-simulator-compute/build.gradle.kts index 7d06ee62..e2290a14 100644 --- a/opendc-simulator/opendc-simulator-compute/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-compute/build.gradle.kts @@ -31,7 +31,7 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) - api(projects.opendcSimulator.opendcSimulatorResources) + api(projects.opendcSimulator.opendcSimulatorFlow) api(projects.opendcSimulator.opendcSimulatorPower) api(projects.opendcSimulator.opendcSimulatorNetwork) implementation(projects.opendcSimulator.opendcSimulatorCore) diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index 88ad7286..c57919c1 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -36,7 +36,7 @@ import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.SimulationCoroutineScope import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine import org.openjdk.jmh.annotations.* import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.TimeUnit @@ -48,13 +48,13 @@ import java.util.concurrent.TimeUnit @OptIn(ExperimentalCoroutinesApi::class) class SimMachineBenchmarks { private lateinit var scope: SimulationCoroutineScope - private lateinit var interpreter: SimResourceInterpreter + private lateinit var engine: FlowEngine private lateinit var machineModel: MachineModel @Setup fun setUp() { scope = SimulationCoroutineScope() - interpreter = SimResourceInterpreter(scope.coroutineContext, scope.clock) + engine = FlowEngine(scope.coroutineContext, scope.clock) val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) @@ -80,7 +80,7 @@ class SimMachineBenchmarks { fun benchmarkBareMetal(state: Workload) { return scope.runBlockingSimulation { val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) return@runBlockingSimulation machine.run(SimTraceWorkload(state.trace)) } @@ -90,9 +90,9 @@ class SimMachineBenchmarks { fun benchmarkSpaceSharedHypervisor(state: Workload) { return scope.runBlockingSimulation { val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val hypervisor = SimSpaceSharedHypervisor(engine) launch { machine.run(hypervisor) } @@ -111,9 +111,9 @@ class SimMachineBenchmarks { fun benchmarkFairShareHypervisorSingle(state: Workload) { return scope.runBlockingSimulation { val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(interpreter) + val hypervisor = SimFairShareHypervisor(engine) launch { machine.run(hypervisor) } @@ -132,9 +132,9 @@ class SimMachineBenchmarks { fun benchmarkFairShareHypervisorDouble(state: Workload) { return scope.runBlockingSimulation { val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(interpreter) + val hypervisor = SimFairShareHypervisor(engine) launch { machine.run(hypervisor) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index f9db048d..6a62d8a5 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -30,22 +30,22 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.NetworkAdapter import org.opendc.simulator.compute.model.StorageDevice import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.resources.* +import org.opendc.simulator.flow.* import kotlin.coroutines.Continuation import kotlin.coroutines.resume /** * Abstract implementation of the [SimMachine] interface. * - * @param interpreter The interpreter to manage the machine's resources. + * @param engine The engine to manage the machine's resources. * @param parent The parent simulation system. * @param model The model of the machine. */ public abstract class SimAbstractMachine( - protected val interpreter: SimResourceInterpreter, - final override val parent: SimResourceSystem?, + protected val engine: FlowEngine, + final override val parent: FlowSystem?, final override val model: MachineModel -) : SimMachine, SimResourceSystem { +) : SimMachine, FlowSystem { /** * The resources allocated for this machine. */ @@ -54,17 +54,17 @@ public abstract class SimAbstractMachine( /** * The memory interface of the machine. */ - public val memory: SimMemory = Memory(SimResourceSource(model.memory.sumOf { it.size }.toDouble(), interpreter), model.memory) + public val memory: SimMemory = Memory(FlowSink(engine, model.memory.sumOf { it.size }.toDouble()), model.memory) /** * The network interfaces available to the machine. */ - public val net: List = model.net.mapIndexed { i, adapter -> NetworkAdapterImpl(adapter, i) } + public val net: List = model.net.mapIndexed { i, adapter -> NetworkAdapterImpl(engine, adapter, i) } /** * The network interfaces available to the machine. */ - public val storage: List = model.storage.mapIndexed { i, device -> StorageDeviceImpl(interpreter, device, i) } + public val storage: List = model.storage.mapIndexed { i, device -> StorageDeviceImpl(engine, device, i) } /** * The peripherals of the machine. @@ -82,7 +82,7 @@ public abstract class SimAbstractMachine( private var cont: Continuation? = null /** - * Run the specified [SimWorkload] on this machine and suspend execution util the workload has finished. + * Converge the specified [SimWorkload] on this machine and suspend execution util the workload has finished. */ override suspend fun run(workload: SimWorkload, meta: Map) { check(!isTerminated) { "Machine is terminated" } @@ -96,14 +96,14 @@ public abstract class SimAbstractMachine( // Cancel all cpus on cancellation cont.invokeOnCancellation { this.cont = null - interpreter.batch { + engine.batch { for (cpu in cpus) { cpu.cancel() } } } - interpreter.batch { workload.onStart(ctx) } + engine.batch { workload.onStart(ctx) } } } @@ -120,7 +120,7 @@ public abstract class SimAbstractMachine( * Cancel the workload that is currently running on the machine. */ private fun cancel() { - interpreter.batch { + engine.batch { for (cpu in cpus) { cpu.cancel() } @@ -137,8 +137,8 @@ public abstract class SimAbstractMachine( * The execution context in which the workload runs. */ private inner class Context(override val meta: Map) : SimMachineContext { - override val interpreter: SimResourceInterpreter - get() = this@SimAbstractMachine.interpreter + override val engine: FlowEngine + get() = this@SimAbstractMachine.engine override val cpus: List = this@SimAbstractMachine.cpus @@ -154,7 +154,7 @@ public abstract class SimAbstractMachine( /** * The [SimMemory] implementation for a machine. */ - private class Memory(source: SimResourceSource, override val models: List) : SimMemory, SimResourceProvider by source { + private class Memory(source: FlowSink, override val models: List) : SimMemory, FlowConsumer by source { override fun toString(): String = "SimAbstractMachine.Memory" } @@ -162,6 +162,7 @@ public abstract class SimAbstractMachine( * The [SimNetworkAdapter] implementation for a machine. */ private class NetworkAdapterImpl( + private val engine: FlowEngine, model: NetworkAdapter, index: Int ) : SimNetworkAdapter(), SimNetworkInterface { @@ -169,18 +170,18 @@ public abstract class SimAbstractMachine( override val bandwidth: Double = model.bandwidth - override val provider: SimResourceProvider + override val provider: FlowConsumer get() = _rx - override fun createConsumer(): SimResourceConsumer = _tx + override fun createConsumer(): FlowSource = _tx - override val tx: SimResourceProvider + override val tx: FlowConsumer get() = _tx - private val _tx = SimResourceForwarder() + private val _tx = FlowForwarder(engine) - override val rx: SimResourceConsumer + override val rx: FlowSource get() = _rx - private val _rx = SimResourceForwarder() + private val _rx = FlowForwarder(engine) override fun toString(): String = "SimAbstractMachine.NetworkAdapterImpl[name=$name,bandwidth=$bandwidth]" } @@ -189,7 +190,7 @@ public abstract class SimAbstractMachine( * The [SimStorageInterface] implementation for a machine. */ private class StorageDeviceImpl( - interpreter: SimResourceInterpreter, + engine: FlowEngine, model: StorageDevice, index: Int ) : SimStorageInterface { @@ -197,9 +198,9 @@ public abstract class SimAbstractMachine( override val capacity: Double = model.capacity - override val read: SimResourceProvider = SimResourceSource(model.readBandwidth, interpreter) + override val read: FlowConsumer = FlowSink(engine, model.readBandwidth) - override val write: SimResourceProvider = SimResourceSource(model.writeBandwidth, interpreter) + override val write: FlowConsumer = FlowSink(engine, model.writeBandwidth) override fun toString(): String = "SimAbstractMachine.StorageDeviceImpl[name=$name,capacity=$capacity]" } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt index 639ca450..37cf282b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt @@ -26,8 +26,8 @@ import org.opendc.simulator.compute.device.SimPsu import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.PowerDriver -import org.opendc.simulator.resources.* -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.FlowEngine /** * A simulated bare-metal machine that is able to run a single workload. @@ -35,19 +35,19 @@ import org.opendc.simulator.resources.SimResourceInterpreter * A [SimBareMetalMachine] is a stateful object, and you should be careful when operating this object concurrently. For * example, the class expects only a single concurrent call to [run]. * - * @param interpreter The [SimResourceInterpreter] to drive the simulation. + * @param engine The [FlowEngine] to drive the simulation. * @param model The machine model to simulate. * @param powerDriver The power driver to use. * @param psu The power supply of the machine. * @param parent The parent simulation system. */ public class SimBareMetalMachine( - interpreter: SimResourceInterpreter, + engine: FlowEngine, model: MachineModel, powerDriver: PowerDriver, public val psu: SimPsu = SimPsu(500.0, mapOf(1.0 to 1.0)), - parent: SimResourceSystem? = null, -) : SimAbstractMachine(interpreter, parent, model) { + parent: FlowSystem? = null, +) : SimAbstractMachine(engine, parent, model) { /** * The power draw of the machine onto the PSU. */ @@ -58,7 +58,7 @@ public class SimBareMetalMachine( * The processing units of the machine. */ override val cpus: List = model.cpus.map { cpu -> - Cpu(SimResourceSource(cpu.frequency, interpreter, this@SimBareMetalMachine), cpu) + Cpu(FlowSink(engine, cpu.frequency, this@SimBareMetalMachine), cpu) } /** @@ -78,9 +78,9 @@ public class SimBareMetalMachine( * A [SimProcessingUnit] of a bare-metal machine. */ private class Cpu( - private val source: SimResourceSource, + private val source: FlowSink, override val model: ProcessingUnit - ) : SimProcessingUnit, SimResourceProvider by source { + ) : SimProcessingUnit, FlowConsumer by source { override var capacity: Double get() = source.capacity set(value) { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt index d8dd8205..ab0b56ae 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt @@ -41,7 +41,7 @@ public interface SimMachine : AutoCloseable { public val peripherals: List /** - * Run the specified [SimWorkload] on this machine and suspend execution util the workload has finished. + * Converge the specified [SimWorkload] on this machine and suspend execution util the workload has finished. */ public suspend fun run(workload: SimWorkload, meta: Map = emptyMap()) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt index 6996a30d..1317f728 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt @@ -22,7 +22,7 @@ package org.opendc.simulator.compute -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine /** * A simulated execution context in which a bootable image runs. This interface represents the @@ -31,9 +31,9 @@ import org.opendc.simulator.resources.SimResourceInterpreter */ public interface SimMachineContext : AutoCloseable { /** - * The resource interpreter that simulates the machine. + * The [FlowEngine] that simulates the machine. */ - public val interpreter: SimResourceInterpreter + public val engine: FlowEngine /** * The metadata associated with the context. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMemory.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMemory.kt index 6623df23..b1aef495 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMemory.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMemory.kt @@ -23,12 +23,12 @@ package org.opendc.simulator.compute import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.resources.SimResourceProvider +import org.opendc.simulator.flow.FlowConsumer /** * An interface to control the memory usage of simulated workloads. */ -public interface SimMemory : SimResourceProvider { +public interface SimMemory : FlowConsumer { /** * The models representing the static information of the memory units supporting this interface. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt index 1ac126ae..660b2871 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt @@ -22,8 +22,8 @@ package org.opendc.simulator.compute -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceProvider +import org.opendc.simulator.flow.FlowConsumer +import org.opendc.simulator.flow.FlowSource /** * A firmware interface to a network adapter. @@ -42,10 +42,10 @@ public interface SimNetworkInterface { /** * The resource provider for the transmit channel of the network interface. */ - public val tx: SimResourceProvider + public val tx: FlowConsumer /** * The resource consumer for the receive channel of the network interface. */ - public val rx: SimResourceConsumer + public val rx: FlowSource } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt index 93c9ddfa..c9f36ece 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt @@ -23,12 +23,12 @@ package org.opendc.simulator.compute import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.resources.SimResourceProvider +import org.opendc.simulator.flow.FlowConsumer /** * A simulated processing unit. */ -public interface SimProcessingUnit : SimResourceProvider { +public interface SimProcessingUnit : FlowConsumer { /** * The capacity of the processing unit, which can be adjusted by the workload if supported by the machine. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt index 21a801f1..3d648671 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt @@ -22,7 +22,7 @@ package org.opendc.simulator.compute -import org.opendc.simulator.resources.SimResourceProvider +import org.opendc.simulator.flow.FlowConsumer /** * A firmware interface to a storage device. @@ -41,10 +41,10 @@ public interface SimStorageInterface { /** * The resource provider for the read operations of the storage device. */ - public val read: SimResourceProvider + public val read: FlowConsumer /** * The resource consumer for the write operation of the storage device. */ - public val write: SimResourceProvider + public val write: FlowConsumer } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index 6e6e590f..b05d8ad9 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -23,10 +23,10 @@ package org.opendc.simulator.compute.device import org.opendc.simulator.compute.power.PowerDriver +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource import org.opendc.simulator.power.SimPowerInlet -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceContext -import org.opendc.simulator.resources.SimResourceEvent import java.util.* /** @@ -54,7 +54,7 @@ public class SimPsu( /** * The consumer context. */ - private var _ctx: SimResourceContext? = null + private var _ctx: FlowConnection? = null /** * The driver that is connected to the PSU. @@ -69,7 +69,7 @@ public class SimPsu( * Update the power draw of the PSU. */ public fun update() { - _ctx?.interrupt() + _ctx?.pull() } /** @@ -81,18 +81,18 @@ public class SimPsu( update() } - override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + override fun createConsumer(): FlowSource = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val powerDraw = computePowerDraw(_driver?.computePower() ?: 0.0) - ctx.push(powerDraw) + conn.push(powerDraw) return Long.MAX_VALUE } - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { when (event) { - SimResourceEvent.Start -> _ctx = ctx - SimResourceEvent.Run -> _powerDraw = ctx.speed - SimResourceEvent.Exit -> _ctx = null + FlowEvent.Start -> _ctx = conn + FlowEvent.Converge -> _powerDraw = conn.rate + FlowEvent.Exit -> _ctx = null else -> {} } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index cf9e3230..b145eefc 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -28,17 +28,17 @@ import org.opendc.simulator.compute.kernel.cpufreq.ScalingPolicy import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.resources.* -import org.opendc.simulator.resources.SimResourceSwitch +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.mux.FlowMultiplexer /** * Abstract implementation of the [SimHypervisor] interface. * - * @param interpreter The resource interpreter to use. + * @param engine The [FlowEngine] to drive the simulation. * @param scalingGovernor The scaling governor to use for scaling the CPU frequency of the underlying hardware. */ public abstract class SimAbstractHypervisor( - private val interpreter: SimResourceInterpreter, + protected val engine: FlowEngine, private val scalingGovernor: ScalingGovernor? = null, protected val interferenceDomain: VmInterferenceDomain? = null ) : SimHypervisor { @@ -50,7 +50,7 @@ public abstract class SimAbstractHypervisor( /** * The resource switch to use. */ - private lateinit var switch: SimResourceSwitch + private lateinit var mux: FlowMultiplexer /** * The virtual machines running on this hypervisor. @@ -62,8 +62,8 @@ public abstract class SimAbstractHypervisor( /** * The resource counters associated with the hypervisor. */ - public override val counters: SimResourceCounters - get() = switch.counters + public override val counters: FlowCounters + get() = mux.counters /** * The scaling governors attached to the physical CPUs backing this hypervisor. @@ -71,14 +71,14 @@ public abstract class SimAbstractHypervisor( private val governors = mutableListOf() /** - * Construct the [SimResourceSwitch] implementation that performs the actual scheduling of the CPUs. + * Construct the [FlowMultiplexer] implementation that performs the actual scheduling of the CPUs. */ - public abstract fun createSwitch(ctx: SimMachineContext): SimResourceSwitch + public abstract fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer /** * Check whether the specified machine model fits on this hypervisor. */ - public abstract fun canFit(model: MachineModel, switch: SimResourceSwitch): Boolean + public abstract fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean /** * Trigger the governors to recompute the scaling limits. @@ -91,7 +91,7 @@ public abstract class SimAbstractHypervisor( /* SimHypervisor */ override fun canFit(model: MachineModel): Boolean { - return canFit(model, switch) + return canFit(model, mux) } override fun createMachine(model: MachineModel, interferenceId: String?): SimMachine { @@ -104,7 +104,7 @@ public abstract class SimAbstractHypervisor( /* SimWorkload */ override fun onStart(ctx: SimMachineContext) { context = ctx - switch = createSwitch(ctx) + mux = createMultiplexer(ctx) for (cpu in ctx.cpus) { val governor = scalingGovernor?.createLogic(ScalingPolicyImpl(cpu)) @@ -113,7 +113,7 @@ public abstract class SimAbstractHypervisor( governor.onStart() } - switch.addInput(cpu) + mux.addOutput(cpu) } } @@ -122,7 +122,7 @@ public abstract class SimAbstractHypervisor( * * @param model The machine model of the virtual machine. */ - private inner class VirtualMachine(model: MachineModel, interferenceId: String? = null) : SimAbstractMachine(interpreter, parent = null, model) { + private inner class VirtualMachine(model: MachineModel, interferenceId: String? = null) : SimAbstractMachine(engine, parent = null, model) { /** * The interference key of this virtual machine. */ @@ -131,7 +131,7 @@ public abstract class SimAbstractHypervisor( /** * The vCPUs of the machine. */ - override val cpus = model.cpus.map { VCpu(switch, switch.newOutput(interferenceKey), it) } + override val cpus = model.cpus.map { VCpu(mux, mux.newInput(interferenceKey), it) } override fun close() { super.close() @@ -153,10 +153,10 @@ public abstract class SimAbstractHypervisor( * A [SimProcessingUnit] of a virtual machine. */ private class VCpu( - private val switch: SimResourceSwitch, - private val source: SimResourceProvider, + private val switch: FlowMultiplexer, + private val source: FlowConsumer, override val model: ProcessingUnit - ) : SimProcessingUnit, SimResourceProvider by source { + ) : SimProcessingUnit, FlowConsumer by source { override var capacity: Double get() = source.capacity set(_) { @@ -169,7 +169,7 @@ public abstract class SimAbstractHypervisor( * Close the CPU */ fun close() { - switch.removeOutput(source) + switch.removeInput(source) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index 3b44292d..36ab7c1c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -28,39 +28,39 @@ import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.SimResourceSwitch -import org.opendc.simulator.resources.SimResourceSwitchMaxMin -import org.opendc.simulator.resources.SimResourceSystem +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowSystem +import org.opendc.simulator.flow.mux.FlowMultiplexer +import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer /** * A [SimHypervisor] that distributes the computing requirements of multiple [SimWorkload]s on a single [SimMachine] * concurrently using weighted fair sharing. * - * @param interpreter The interpreter to manage the machine's resources. + * @param engine The [FlowEngine] to manage the machine's resources. * @param parent The parent simulation system. * @param scalingGovernor The CPU frequency scaling governor to use for the hypervisor. * @param interferenceDomain The resource interference domain to which the hypervisor belongs. * @param listener The hypervisor listener to use. */ public class SimFairShareHypervisor( - private val interpreter: SimResourceInterpreter, - private val parent: SimResourceSystem? = null, + engine: FlowEngine, + private val parent: FlowSystem? = null, scalingGovernor: ScalingGovernor? = null, interferenceDomain: VmInterferenceDomain? = null, private val listener: SimHypervisor.Listener? = null -) : SimAbstractHypervisor(interpreter, scalingGovernor, interferenceDomain) { +) : SimAbstractHypervisor(engine, scalingGovernor, interferenceDomain) { - override fun canFit(model: MachineModel, switch: SimResourceSwitch): Boolean = true + override fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean = true - override fun createSwitch(ctx: SimMachineContext): SimResourceSwitch { + override fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer { return SwitchSystem(ctx).switch } - private inner class SwitchSystem(private val ctx: SimMachineContext) : SimResourceSystem { - val switch = SimResourceSwitchMaxMin(interpreter, this, interferenceDomain) + private inner class SwitchSystem(private val ctx: SimMachineContext) : FlowSystem { + val switch = MaxMinFlowMultiplexer(engine, this, interferenceDomain) - override val parent: SimResourceSystem? = this@SimFairShareHypervisor.parent + override val parent: FlowSystem? = this@SimFairShareHypervisor.parent private var lastCpuUsage = 0.0 private var lastCpuDemand = 0.0 @@ -87,8 +87,8 @@ public class SimFairShareHypervisor( } lastReport = timestamp - lastCpuDemand = switch.inputs.sumOf { it.demand } - lastCpuUsage = switch.inputs.sumOf { it.speed } + lastCpuDemand = switch.outputs.sumOf { it.demand } + lastCpuUsage = switch.outputs.sumOf { it.rate } lastDemand = counters.demand lastActual = counters.actual lastOvercommit = counters.overcommit diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt index 8d0592ec..bfa099fb 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.SimResourceSystem +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowSystem /** * A [SimHypervisorProvider] for the [SimFairShareHypervisor] implementation. @@ -34,13 +34,13 @@ public class SimFairShareHypervisorProvider : SimHypervisorProvider { override val id: String = "fair-share" override fun create( - interpreter: SimResourceInterpreter, - parent: SimResourceSystem?, + engine: FlowEngine, + parent: FlowSystem?, scalingGovernor: ScalingGovernor?, interferenceDomain: VmInterferenceDomain?, listener: SimHypervisor.Listener? ): SimHypervisor = SimFairShareHypervisor( - interpreter, + engine, parent, scalingGovernor = scalingGovernor, interferenceDomain = interferenceDomain, diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt index 3b49d515..1b11ca6b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt @@ -25,7 +25,7 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.SimMachine import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.resources.SimResourceCounters +import org.opendc.simulator.flow.FlowCounters /** * A SimHypervisor facilitates the execution of multiple concurrent [SimWorkload]s, while acting as a single workload @@ -40,7 +40,7 @@ public interface SimHypervisor : SimWorkload { /** * The resource counters associated with the hypervisor. */ - public val counters: SimResourceCounters + public val counters: FlowCounters /** * Determine whether the specified machine characterized by [model] can fit on this hypervisor at this moment. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt index b307a34d..97f07097 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.SimResourceSystem +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowSystem /** * A service provider interface for constructing a [SimHypervisor]. @@ -43,8 +43,8 @@ public interface SimHypervisorProvider { * Create a [SimHypervisor] instance with the specified [listener]. */ public fun create( - interpreter: SimResourceInterpreter, - parent: SimResourceSystem? = null, + engine: FlowEngine, + parent: FlowSystem? = null, scalingGovernor: ScalingGovernor? = null, interferenceDomain: VmInterferenceDomain? = null, listener: SimHypervisor.Listener? = null diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt index ac1c0250..883e0d82 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt @@ -24,19 +24,19 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.SimResourceSwitch -import org.opendc.simulator.resources.SimResourceSwitchExclusive +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.mux.FlowMultiplexer +import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer /** * A [SimHypervisor] that allocates its sub-resources exclusively for the virtual machine that it hosts. */ -public class SimSpaceSharedHypervisor(interpreter: SimResourceInterpreter) : SimAbstractHypervisor(interpreter) { - override fun canFit(model: MachineModel, switch: SimResourceSwitch): Boolean { - return switch.inputs.size - switch.outputs.size >= model.cpus.size +public class SimSpaceSharedHypervisor(engine: FlowEngine) : SimAbstractHypervisor(engine) { + override fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean { + return switch.outputs.size - switch.inputs.size >= model.cpus.size } - override fun createSwitch(ctx: SimMachineContext): SimResourceSwitch { - return SimResourceSwitchExclusive() + override fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer { + return ForwardingFlowMultiplexer(engine) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt index 3906cb9a..7869d72d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.SimResourceSystem +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowSystem /** * A [SimHypervisorProvider] for the [SimSpaceSharedHypervisor] implementation. @@ -34,10 +34,10 @@ public class SimSpaceSharedHypervisorProvider : SimHypervisorProvider { override val id: String = "space-shared" override fun create( - interpreter: SimResourceInterpreter, - parent: SimResourceSystem?, + engine: FlowEngine, + parent: FlowSystem?, scalingGovernor: ScalingGovernor?, interferenceDomain: VmInterferenceDomain?, listener: SimHypervisor.Listener? - ): SimHypervisor = SimSpaceSharedHypervisor(interpreter) + ): SimHypervisor = SimSpaceSharedHypervisor(engine) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceDomain.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceDomain.kt index 1801fcd0..b737d61a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceDomain.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceDomain.kt @@ -22,8 +22,8 @@ package org.opendc.simulator.compute.kernel.interference -import org.opendc.simulator.resources.interference.InterferenceDomain -import org.opendc.simulator.resources.interference.InterferenceKey +import org.opendc.simulator.flow.interference.InterferenceDomain +import org.opendc.simulator.flow.interference.InterferenceKey /** * The interference domain of a hypervisor. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt index c2e00c8e..b3d72507 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt @@ -22,7 +22,7 @@ package org.opendc.simulator.compute.kernel.interference -import org.opendc.simulator.resources.interference.InterferenceKey +import org.opendc.simulator.flow.interference.InterferenceKey import java.util.* /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/PStatePowerDriver.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/PStatePowerDriver.kt index 6577fbfc..f71446f8 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/PStatePowerDriver.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/PStatePowerDriver.kt @@ -46,7 +46,7 @@ public class PStatePowerDriver(states: Map) : PowerDriver { for (cpu in cpus) { targetFreq = max(cpu.capacity, targetFreq) - totalSpeed += cpu.speed + totalSpeed += cpu.rate } val maxFreq = states.lastKey() diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt index bf7aeff1..34e91c35 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/power/SimplePowerDriver.kt @@ -37,7 +37,7 @@ public class SimplePowerDriver(private val model: PowerModel) : PowerDriver { for (cpu in cpus) { targetFreq += cpu.capacity - totalSpeed += cpu.speed + totalSpeed += cpu.rate } return model.computePower(totalSpeed / targetFreq) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt index a01fa20c..99f4a1e1 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt @@ -23,7 +23,7 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.source.FixedFlowSource /** * A [SimWorkload] that models applications as a static number of floating point operations ([flops]) executed on @@ -44,7 +44,7 @@ public class SimFlopsWorkload( override fun onStart(ctx: SimMachineContext) { val lifecycle = SimWorkloadLifecycle(ctx) for (cpu in ctx.cpus) { - cpu.startConsumer(lifecycle.waitFor(SimWorkConsumer(flops.toDouble() / ctx.cpus.size, utilization))) + cpu.startConsumer(lifecycle.waitFor(FixedFlowSource(flops.toDouble() / ctx.cpus.size, utilization))) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt index 4ee56689..2ef3bc43 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt @@ -23,7 +23,7 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.source.FixedFlowSource /** * A [SimWorkload] that models application execution as a single duration. @@ -44,7 +44,7 @@ public class SimRuntimeWorkload( val lifecycle = SimWorkloadLifecycle(ctx) for (cpu in ctx.cpus) { val limit = cpu.capacity * utilization - cpu.startConsumer(lifecycle.waitFor(SimWorkConsumer((limit / 1000) * duration, utilization))) + cpu.startConsumer(lifecycle.waitFor(FixedFlowSource((limit / 1000) * duration, utilization))) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index dd582bb2..a877dac1 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceContext +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowSource import kotlin.math.min /** @@ -78,12 +78,12 @@ public class SimTraceWorkload(public val trace: Sequence, private val return now >= timestamp + duration } - private inner class Consumer(val cpu: ProcessingUnit) : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { + private inner class Consumer(val cpu: ProcessingUnit) : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val fragment = pullFragment(now) if (fragment == null) { - ctx.close() + conn.close() return Long.MAX_VALUE } @@ -91,7 +91,7 @@ public class SimTraceWorkload(public val trace: Sequence, private val // Fragment is in the future if (timestamp > now) { - ctx.push(0.0) + conn.push(0.0) return timestamp - now } @@ -103,7 +103,7 @@ public class SimTraceWorkload(public val trace: Sequence, private val val deadline = timestamp + fragment.duration val duration = deadline - now - ctx.push(if (cpu.id < cores && usage > 0.0) usage else 0.0) + conn.push(if (cpu.id < cores && usage > 0.0) usage else 0.0) return duration } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt index 5dd18271..dabe60e0 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt @@ -23,9 +23,9 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceContext -import org.opendc.simulator.resources.SimResourceEvent +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource /** * A helper class to manage the lifecycle of a [SimWorkload] @@ -34,27 +34,27 @@ public class SimWorkloadLifecycle(private val ctx: SimMachineContext) { /** * The resource consumers which represent the lifecycle of the workload. */ - private val waiting = mutableSetOf() + private val waiting = mutableSetOf() /** * Wait for the specified [consumer] to complete before ending the lifecycle of the workload. */ - public fun waitFor(consumer: SimResourceConsumer): SimResourceConsumer { + public fun waitFor(consumer: FlowSource): FlowSource { waiting.add(consumer) - return object : SimResourceConsumer by consumer { - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { + return object : FlowSource by consumer { + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { try { - consumer.onEvent(ctx, event) + consumer.onEvent(conn, now, event) } finally { - if (event == SimResourceEvent.Exit) { + if (event == FlowEvent.Exit) { complete(consumer) } } } - override fun onFailure(ctx: SimResourceContext, cause: Throwable) { + override fun onFailure(conn: FlowConnection, cause: Throwable) { try { - consumer.onFailure(ctx, cause) + consumer.onFailure(conn, cause) } finally { complete(consumer) } @@ -65,9 +65,9 @@ public class SimWorkloadLifecycle(private val ctx: SimMachineContext) { } /** - * Complete the specified [SimResourceConsumer]. + * Complete the specified [FlowSource]. */ - private fun complete(consumer: SimResourceConsumer) { + private fun complete(consumer: FlowSource) { if (waiting.remove(consumer) && waiting.isEmpty()) { ctx.close() } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt index 81268879..0bb24ed8 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt @@ -34,10 +34,10 @@ import org.opendc.simulator.compute.workload.SimFlopsWorkload import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.compute.workload.SimWorkloadLifecycle import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.source.FixedFlowSource import org.opendc.simulator.network.SimNetworkSink import org.opendc.simulator.power.SimPowerSource -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.consumer.SimWorkConsumer /** * Test suite for the [SimBareMetalMachine] class. @@ -60,7 +60,7 @@ class SimMachineTest { @Test fun testFlopsWorkload() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -83,7 +83,7 @@ class SimMachineTest { memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -100,13 +100,13 @@ class SimMachineTest { @Test fun testPower() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, + engine, machineModel, SimplePowerDriver(LinearPowerModel(100.0, 50.0)) ) - val source = SimPowerSource(interpreter, capacity = 1000.0) + val source = SimPowerSource(engine, capacity = 1000.0) source.connect(machine.psu) try { @@ -125,7 +125,7 @@ class SimMachineTest { @Test fun testCapacityClamp() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -151,7 +151,7 @@ class SimMachineTest { @Test fun testMemory() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -171,7 +171,7 @@ class SimMachineTest { @Test fun testMemoryUsage() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -180,7 +180,7 @@ class SimMachineTest { machine.run(object : SimWorkload { override fun onStart(ctx: SimMachineContext) { val lifecycle = SimWorkloadLifecycle(ctx) - ctx.memory.startConsumer(lifecycle.waitFor(SimWorkConsumer(ctx.memory.capacity, utilization = 0.8))) + ctx.memory.startConsumer(lifecycle.waitFor(FixedFlowSource(ctx.memory.capacity, utilization = 0.8))) } }) @@ -192,22 +192,22 @@ class SimMachineTest { @Test fun testNetUsage() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) val adapter = (machine.peripherals[0] as SimNetworkAdapter) - adapter.connect(SimNetworkSink(interpreter, adapter.bandwidth)) + adapter.connect(SimNetworkSink(engine, adapter.bandwidth)) try { machine.run(object : SimWorkload { override fun onStart(ctx: SimMachineContext) { val lifecycle = SimWorkloadLifecycle(ctx) val iface = ctx.net[0] - iface.tx.startConsumer(lifecycle.waitFor(SimWorkConsumer(iface.bandwidth, utilization = 0.8))) + iface.tx.startConsumer(lifecycle.waitFor(FixedFlowSource(iface.bandwidth, utilization = 0.8))) } }) @@ -219,9 +219,9 @@ class SimMachineTest { @Test fun testDiskReadUsage() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -231,7 +231,7 @@ class SimMachineTest { override fun onStart(ctx: SimMachineContext) { val lifecycle = SimWorkloadLifecycle(ctx) val disk = ctx.storage[0] - disk.read.startConsumer(lifecycle.waitFor(SimWorkConsumer(disk.read.capacity, utilization = 0.8))) + disk.read.startConsumer(lifecycle.waitFor(FixedFlowSource(disk.read.capacity, utilization = 0.8))) } }) @@ -243,9 +243,9 @@ class SimMachineTest { @Test fun testDiskWriteUsage() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -255,7 +255,7 @@ class SimMachineTest { override fun onStart(ctx: SimMachineContext) { val lifecycle = SimWorkloadLifecycle(ctx) val disk = ctx.storage[0] - disk.write.startConsumer(lifecycle.waitFor(SimWorkConsumer(disk.write.capacity, utilization = 0.8))) + disk.write.startConsumer(lifecycle.waitFor(FixedFlowSource(disk.write.capacity, utilization = 0.8))) } }) @@ -268,7 +268,7 @@ class SimMachineTest { @Test fun testCancellation() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -290,7 +290,7 @@ class SimMachineTest { @Test fun testConcurrentRuns() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -313,7 +313,7 @@ class SimMachineTest { @Test fun testClose() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/device/SimPsuTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/device/SimPsuTest.kt index 6c9ec7bd..e5b509f0 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/device/SimPsuTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/device/SimPsuTest.kt @@ -29,8 +29,8 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.FlowEngine import org.opendc.simulator.power.SimPowerSource -import org.opendc.simulator.resources.SimResourceInterpreter /** * Test suite for [SimPsu] @@ -55,8 +55,8 @@ internal class SimPsuTest { val ratedOutputPower = 240.0 val energyEfficiency = mapOf(0.0 to 1.0) - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = ratedOutputPower) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = ratedOutputPower) val cpuLogic = mockk() every { cpuLogic.computePower() } returns 0.0 @@ -78,8 +78,8 @@ internal class SimPsuTest { 1.0 to 0.94, ) - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = ratedOutputPower) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = ratedOutputPower) val cpuLogic = mockk() every { cpuLogic.computePower() } returnsMany listOf(50.0, 100.0, 150.0, 200.0) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index 8cd535ad..058d5d28 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -40,7 +40,7 @@ import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine /** * Test suite for the [SimHypervisor] class. @@ -94,7 +94,7 @@ internal class SimHypervisorTest { ), ) - val platform = SimResourceInterpreter(coroutineContext, clock) + val platform = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(platform, model, SimplePowerDriver(ConstantPowerModel(0.0))) val hypervisor = SimFairShareHypervisor(platform, scalingGovernor = PerformanceScalingGovernor(), listener = listener) @@ -163,7 +163,7 @@ internal class SimHypervisorTest { ) ) - val platform = SimResourceInterpreter(coroutineContext, clock) + val platform = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -204,7 +204,7 @@ internal class SimHypervisorTest { memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) - val platform = SimResourceInterpreter(coroutineContext, clock) + val platform = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -234,7 +234,7 @@ internal class SimHypervisorTest { ) val interferenceModel = VmInterferenceModel(groups) - val platform = SimResourceInterpreter(coroutineContext, clock) + val platform = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index 55d6d7c4..95fb6679 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -40,7 +40,7 @@ import org.opendc.simulator.compute.workload.SimFlopsWorkload import org.opendc.simulator.compute.workload.SimRuntimeWorkload import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine /** * A test suite for the [SimSpaceSharedHypervisor]. @@ -74,11 +74,11 @@ internal class SimSpaceSharedHypervisorTest { ), ) - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val hypervisor = SimSpaceSharedHypervisor(engine) launch { machine.run(hypervisor) } val vm = hypervisor.createMachine(machineModel) @@ -98,11 +98,11 @@ internal class SimSpaceSharedHypervisorTest { fun testRuntimeWorkload() = runBlockingSimulation { val duration = 5 * 60L * 1000 val workload = SimRuntimeWorkload(duration) - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val hypervisor = SimSpaceSharedHypervisor(engine) launch { machine.run(hypervisor) } yield() @@ -121,11 +121,11 @@ internal class SimSpaceSharedHypervisorTest { fun testFlopsWorkload() = runBlockingSimulation { val duration = 5 * 60L * 1000 val workload = SimFlopsWorkload((duration * 3.2).toLong(), 1.0) - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val hypervisor = SimSpaceSharedHypervisor(engine) launch { machine.run(hypervisor) } yield() @@ -142,11 +142,11 @@ internal class SimSpaceSharedHypervisorTest { @Test fun testTwoWorkloads() = runBlockingSimulation { val duration = 5 * 60L * 1000 - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) + engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val hypervisor = SimSpaceSharedHypervisor(engine) launch { machine.run(hypervisor) } yield() @@ -170,11 +170,9 @@ internal class SimSpaceSharedHypervisorTest { */ @Test fun testConcurrentWorkloadFails() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val machine = SimBareMetalMachine( - interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) - ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) + val hypervisor = SimSpaceSharedHypervisor(engine) launch { machine.run(hypervisor) } yield() @@ -194,7 +192,7 @@ internal class SimSpaceSharedHypervisorTest { */ @Test fun testConcurrentWorkloadSucceeds() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val interpreter = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PStatePowerDriverTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PStatePowerDriverTest.kt index c39859bf..f557c8d3 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PStatePowerDriverTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PStatePowerDriverTest.kt @@ -55,7 +55,7 @@ internal class PStatePowerDriverTest { val cpu = mockk(relaxUnitFun = true) every { cpu.capacity } returns 3200.0 - every { cpu.speed } returns 1200.0 + every { cpu.rate } returns 1200.0 val driver = PStatePowerDriver( sortedMapOf( @@ -77,10 +77,10 @@ internal class PStatePowerDriverTest { val cpus = listOf(cpu, cpu) every { cpus[0].capacity } returns 1000.0 - every { cpus[0].speed } returns 1200.0 + every { cpus[0].rate } returns 1200.0 every { cpus[1].capacity } returns 3500.0 - every { cpus[1].speed } returns 1200.0 + every { cpus[1].rate } returns 1200.0 val driver = PStatePowerDriver( sortedMapOf( @@ -112,11 +112,11 @@ internal class PStatePowerDriverTest { val logic = driver.createLogic(machine, listOf(cpu)) - every { cpu.speed } returns 1400.0 + every { cpu.rate } returns 1400.0 every { cpu.capacity } returns 1400.0 assertEquals(150.0, logic.computePower()) - every { cpu.speed } returns 1400.0 + every { cpu.rate } returns 1400.0 every { cpu.capacity } returns 4000.0 assertEquals(235.0, logic.computePower()) } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt index 78019c2e..cdbffe4b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt @@ -31,7 +31,7 @@ import org.opendc.simulator.compute.model.* import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine /** * Test suite for the [SimTraceWorkloadTest] class. @@ -52,7 +52,7 @@ class SimTraceWorkloadTest { @Test fun testSmoke() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -79,7 +79,7 @@ class SimTraceWorkloadTest { @Test fun testOffset() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -106,7 +106,7 @@ class SimTraceWorkloadTest { @Test fun testSkipFragment() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -134,7 +134,7 @@ class SimTraceWorkloadTest { @Test fun testZeroCores() = runBlockingSimulation { val machine = SimBareMetalMachine( - SimResourceInterpreter(coroutineContext, clock), + FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) diff --git a/opendc-simulator/opendc-simulator-flow/build.gradle.kts b/opendc-simulator/opendc-simulator-flow/build.gradle.kts new file mode 100644 index 00000000..5a956fee --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/build.gradle.kts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +description = "High-performance flow simulator" + +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` + `benchmark-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(libs.kotlinx.coroutines) + implementation(projects.opendcUtils) + + testImplementation(projects.opendcSimulator.opendcSimulatorCore) +} diff --git a/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt b/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt new file mode 100644 index 00000000..4834f10f --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import org.opendc.simulator.core.SimulationCoroutineScope +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer +import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer +import org.opendc.simulator.flow.source.TraceFlowSource +import org.openjdk.jmh.annotations.* +import java.util.concurrent.ThreadLocalRandom +import java.util.concurrent.TimeUnit + +@State(Scope.Thread) +@Fork(1) +@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) +@OptIn(ExperimentalCoroutinesApi::class) +class FlowBenchmarks { + private lateinit var scope: SimulationCoroutineScope + private lateinit var engine: FlowEngine + + @Setup + fun setUp() { + scope = SimulationCoroutineScope() + engine = FlowEngine(scope.coroutineContext, scope.clock) + } + + @State(Scope.Thread) + class Workload { + lateinit var trace: Sequence + + @Setup + fun setUp() { + val random = ThreadLocalRandom.current() + val entries = List(10000) { TraceFlowSource.Fragment(1000, random.nextDouble(0.0, 4500.0)) } + trace = entries.asSequence() + } + } + + @Benchmark + fun benchmarkSink(state: Workload) { + return scope.runBlockingSimulation { + val provider = FlowSink(engine, 4200.0) + return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) + } + } + + @Benchmark + fun benchmarkForward(state: Workload) { + return scope.runBlockingSimulation { + val provider = FlowSink(engine, 4200.0) + val forwarder = FlowForwarder(engine) + provider.startConsumer(forwarder) + return@runBlockingSimulation forwarder.consume(TraceFlowSource(state.trace)) + } + } + + @Benchmark + fun benchmarkMuxMaxMinSingleSource(state: Workload) { + return scope.runBlockingSimulation { + val switch = MaxMinFlowMultiplexer(engine) + + switch.addOutput(FlowSink(engine, 3000.0)) + switch.addOutput(FlowSink(engine, 3000.0)) + + val provider = switch.newInput() + return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) + } + } + + @Benchmark + fun benchmarkMuxMaxMinTripleSource(state: Workload) { + return scope.runBlockingSimulation { + val switch = MaxMinFlowMultiplexer(engine) + + switch.addOutput(FlowSink(engine, 3000.0)) + switch.addOutput(FlowSink(engine, 3000.0)) + + repeat(3) { + launch { + val provider = switch.newInput() + provider.consume(TraceFlowSource(state.trace)) + } + } + } + } + + @Benchmark + fun benchmarkMuxExclusiveSingleSource(state: Workload) { + return scope.runBlockingSimulation { + val switch = ForwardingFlowMultiplexer(engine) + + switch.addOutput(FlowSink(engine, 3000.0)) + switch.addOutput(FlowSink(engine, 3000.0)) + + val provider = switch.newInput() + return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) + } + } + + @Benchmark + fun benchmarkMuxExclusiveTripleSource(state: Workload) { + return scope.runBlockingSimulation { + val switch = ForwardingFlowMultiplexer(engine) + + switch.addOutput(FlowSink(engine, 3000.0)) + switch.addOutput(FlowSink(engine, 3000.0)) + + repeat(2) { + launch { + val provider = switch.newInput() + provider.consume(TraceFlowSource(state.trace)) + } + } + } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt new file mode 100644 index 00000000..c8092082 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import org.opendc.simulator.flow.internal.FlowCountersImpl + +/** + * Abstract implementation of the [FlowConsumer] which can be re-used by other implementations. + */ +public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initialCapacity: Double) : FlowConsumer { + /** + * A flag to indicate that the flow consumer is active. + */ + public override val isActive: Boolean + get() = ctx != null + + /** + * The capacity of the consumer. + */ + public override var capacity: Double = initialCapacity + set(value) { + field = value + ctx?.capacity = value + } + + /** + * The current processing rate of the consumer. + */ + public override val rate: Double + get() = ctx?.rate ?: 0.0 + + /** + * The flow processing rate demand at this instant. + */ + public override val demand: Double + get() = ctx?.demand ?: 0.0 + + /** + * The flow counters to track the flow metrics of the consumer. + */ + public override val counters: FlowCounters + get() = _counters + private val _counters = FlowCountersImpl() + + /** + * The [FlowConsumerContext] that is currently running. + */ + protected var ctx: FlowConsumerContext? = null + private set + + /** + * Construct the [FlowConsumerLogic] instance for a new source. + */ + protected abstract fun createLogic(): FlowConsumerLogic + + /** + * Start the specified [FlowConsumerContext]. + */ + protected open fun start(ctx: FlowConsumerContext) { + ctx.start() + } + + /** + * The previous demand for the consumer. + */ + private var previousDemand = 0.0 + + /** + * Update the counters of the flow consumer. + */ + protected fun updateCounters(ctx: FlowConnection, delta: Long) { + val demand = previousDemand + previousDemand = ctx.demand + + if (delta <= 0) { + return + } + + val counters = _counters + val deltaS = delta / 1000.0 + val work = demand * deltaS + val actualWork = ctx.rate * deltaS + val remainingWork = work - actualWork + + counters.demand += work + counters.actual += actualWork + counters.overcommit += remainingWork + } + + /** + * Update the counters of the flow consumer. + */ + protected fun updateCounters(demand: Double, actual: Double, overcommit: Double) { + val counters = _counters + counters.demand += demand + counters.actual += actual + counters.overcommit += overcommit + } + + final override fun startConsumer(source: FlowSource) { + check(ctx == null) { "Consumer is in invalid state" } + val ctx = engine.newContext(source, createLogic()) + + ctx.capacity = capacity + this.ctx = ctx + + start(ctx) + } + + final override fun pull() { + ctx?.pull() + } + + final override fun cancel() { + val ctx = ctx + if (ctx != null) { + this.ctx = null + ctx.close() + } + } + + override fun toString(): String = "AbstractFlowConsumer[capacity=$capacity]" +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt new file mode 100644 index 00000000..fa833961 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * An active connection between a [FlowSource] and [FlowConsumer]. + */ +public interface FlowConnection : AutoCloseable { + /** + * The capacity of the connection. + */ + public val capacity: Double + + /** + * The flow rate over the connection. + */ + public val rate: Double + + /** + * The flow demand of the source. + */ + public val demand: Double + + /** + * Pull the source. + */ + public fun pull() + + /** + * Push the given flow [rate] over this connection. + * + * @param rate The rate of the flow to push. + */ + public fun push(rate: Double) + + /** + * Disconnect the consumer from its source. + */ + public override fun close() +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt new file mode 100644 index 00000000..3a6e2e97 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException + +/** + * A consumer of a [FlowSource]. + */ +public interface FlowConsumer { + /** + * A flag to indicate that the consumer is currently consuming a [FlowSource]. + */ + public val isActive: Boolean + + /** + * The flow capacity of this consumer. + */ + public val capacity: Double + + /** + * The current flow rate of the consumer. + */ + public val rate: Double + + /** + * The current flow demand. + */ + public val demand: Double + + /** + * The flow counters to track the flow metrics of the consumer. + */ + public val counters: FlowCounters + + /** + * Start consuming the specified [source]. + * + * @throws IllegalStateException if the consumer is already active. + */ + public fun startConsumer(source: FlowSource) + + /** + * Ask the consumer to pull its source. + * + * If the consumer is not active, this operation will be a no-op. + */ + public fun pull() + + /** + * Disconnect the consumer from its source. + * + * If the consumer is not active, this operation will be a no-op. + */ + public fun cancel() +} + +/** + * Consume the specified [source] and suspend execution until the source is fully consumed or failed. + */ +public suspend fun FlowConsumer.consume(source: FlowSource) { + return suspendCancellableCoroutine { cont -> + startConsumer(object : FlowSource by source { + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + source.onEvent(conn, now, event) + + if (event == FlowEvent.Exit && !cont.isCompleted) { + cont.resume(Unit) + } + } + + override fun onFailure(conn: FlowConnection, cause: Throwable) { + try { + source.onFailure(conn, cause) + cont.resumeWithException(cause) + } catch (e: Throwable) { + e.addSuppressed(cause) + cont.resumeWithException(e) + } + } + + override fun toString(): String = "SuspendingFlowSource" + }) + + cont.invokeOnCancellation { cancel() } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt new file mode 100644 index 00000000..75b2d25b --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A controllable [FlowConnection]. + * + * This interface is used by [FlowConsumer]s to control the connection between it and the source. + */ +public interface FlowConsumerContext : FlowConnection { + /** + * The capacity of the connection. + */ + public override var capacity: Double + + /** + * Start the flow over the connection. + */ + public fun start() + + /** + * Synchronously flush the changes of the connection. + */ + public fun flush() +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt new file mode 100644 index 00000000..c69cb17e --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A collection of callbacks associated with a [FlowConsumer]. + */ +public interface FlowConsumerLogic { + /** + * This method is invoked when a [FlowSource] changes the rate of flow to this consumer. + * + * @param ctx The context in which the provider runs. + * @param now The virtual timestamp in milliseconds at which the update is occurring. + * @param delta The virtual duration between this call and the last call to [onPush] in milliseconds. + * @param rate The requested processing rate of the source. + */ + public fun onPush(ctx: FlowConsumerContext, now: Long, delta: Long, rate: Double) {} + + /** + * This method is invoked when the flow graph has converged into a steady-state system. + * + * @param ctx The context in which the provider runs. + * @param now The virtual timestamp in milliseconds at which the system converged. + * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. + */ + public fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) {} + + /** + * This method is invoked when the [FlowSource] is completed. + * + * @param ctx The context in which the provider runs. + * @param now The virtual timestamp in milliseconds at which the provider finished. + * @param delta The virtual duration between this call and the last call to [onPush] in milliseconds. + */ + public fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long) {} +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt new file mode 100644 index 00000000..e15d7643 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * An interface that tracks cumulative counts of the flow accumulation over a stage. + */ +public interface FlowCounters { + /** + * The accumulated flow that a source wanted to push over the connection. + */ + public val demand: Double + + /** + * The accumulated flow that was actually transferred over the connection. + */ + public val actual: Double + + /** + * The accumulated flow that could not be transferred over the connection. + */ + public val overcommit: Double + + /** + * The accumulated flow lost due to interference between sources. + */ + public val interference: Double + + /** + * Reset the flow counters. + */ + public fun reset() +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEngine.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEngine.kt new file mode 100644 index 00000000..65224827 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEngine.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import org.opendc.simulator.flow.internal.FlowEngineImpl +import java.time.Clock +import kotlin.coroutines.CoroutineContext + +/** + * A [FlowEngine] is responsible for managing the interaction between [FlowSource]s and [FlowConsumer]s. + * + * The engine centralizes the scheduling logic of state updates of flow connections, allowing update propagation + * to happen more efficiently. and overall, reducing the work necessary to transition into a steady state. + */ +public interface FlowEngine { + /** + * The virtual [Clock] associated with this engine. + */ + public val clock: Clock + + /** + * Create a new [FlowConsumerContext] with the given [provider]. + * + * @param consumer The consumer logic. + * @param provider The logic of the resource provider. + */ + public fun newContext(consumer: FlowSource, provider: FlowConsumerLogic): FlowConsumerContext + + /** + * Start batching the execution of resource updates until [popBatch] is called. + * + * This method is useful if you want to propagate multiple resources updates (e.g., starting multiple CPUs + * simultaneously) in a single state update. + * + * Multiple calls to this method requires the same number of [popBatch] calls in order to properly flush the + * resource updates. This allows nested calls to [pushBatch], but might cause issues if [popBatch] is not called + * the same amount of times. To simplify batching, see [batch]. + */ + public fun pushBatch() + + /** + * Stop the batching of resource updates and run the interpreter on the batch. + * + * Note that method will only flush the event once the first call to [pushBatch] has received a [popBatch] call. + */ + public fun popBatch() + + public companion object { + /** + * Construct a new [FlowEngine] implementation. + * + * @param context The coroutine context to use. + * @param clock The virtual simulation clock. + */ + @JvmStatic + @JvmName("create") + public operator fun invoke(context: CoroutineContext, clock: Clock): FlowEngine { + return FlowEngineImpl(context, clock) + } + } +} + +/** + * Batch the execution of several interrupts into a single call. + * + * This method is useful if you want to propagate the start of multiple resources (e.g., CPUs) in a single update. + */ +public inline fun FlowEngine.batch(block: () -> Unit) { + try { + pushBatch() + block() + } finally { + popBatch() + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt new file mode 100644 index 00000000..14c85183 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A flow event that is communicated to a [FlowSource]. + */ +public enum class FlowEvent { + /** + * This event is emitted to the source when it has started. + */ + Start, + + /** + * This event is emitted to the source when it is stopped. + */ + Exit, + + /** + * This event is emitted to the source when the system has converged into a steady state. + */ + Converge, + + /** + * This event is emitted to the source when the capacity of the consumer has changed. + */ + Capacity, +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt new file mode 100644 index 00000000..2074033e --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import org.opendc.simulator.flow.internal.FlowCountersImpl + +/** + * A class that acts as a [FlowSource] and [FlowConsumer] at the same time. + * + * @param engine The [FlowEngine] the forwarder runs in. + * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. + */ +public class FlowForwarder(private val engine: FlowEngine, private val isCoupled: Boolean = false) : FlowSource, FlowConsumer, AutoCloseable { + /** + * The delegate [FlowSource]. + */ + private var delegate: FlowSource? = null + + /** + * A flag to indicate that the delegate was started. + */ + private var hasDelegateStarted: Boolean = false + + /** + * The exposed [FlowConnection]. + */ + private val _ctx = object : FlowConnection { + override val capacity: Double + get() = _innerCtx?.capacity ?: 0.0 + + override val demand: Double + get() = _innerCtx?.demand ?: 0.0 + + override val rate: Double + get() = _innerCtx?.rate ?: 0.0 + + override fun pull() { + _innerCtx?.pull() + } + + override fun push(rate: Double) { + _innerCtx?.push(rate) + _demand = rate + } + + override fun close() { + val delegate = checkNotNull(delegate) { "Delegate not active" } + + if (isCoupled) + _innerCtx?.close() + else + _innerCtx?.push(0.0) + + // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we + // reset beforehand the existing state and check whether it has been updated afterwards + reset() + + delegate.onEvent(this, engine.clock.millis(), FlowEvent.Exit) + } + } + + /** + * The [FlowConnection] in which the forwarder runs. + */ + private var _innerCtx: FlowConnection? = null + + override val isActive: Boolean + get() = delegate != null + + override val capacity: Double + get() = _ctx.capacity + + override val rate: Double + get() = _ctx.rate + + override val demand: Double + get() = _ctx.demand + + override val counters: FlowCounters + get() = _counters + private val _counters = FlowCountersImpl() + + override fun startConsumer(source: FlowSource) { + check(delegate == null) { "Forwarder already active" } + + delegate = source + + // Pull to replace the source + pull() + } + + override fun pull() { + _ctx.pull() + } + + override fun cancel() { + val delegate = delegate + val ctx = _innerCtx + + if (delegate != null) { + this.delegate = null + + if (ctx != null) { + delegate.onEvent(this._ctx, engine.clock.millis(), FlowEvent.Exit) + } + } + } + + override fun close() { + val ctx = _innerCtx + + if (ctx != null) { + this._innerCtx = null + ctx.pull() + } + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val delegate = delegate + + if (!hasDelegateStarted) { + start() + } + + updateCounters(conn, delta) + + return delegate?.onPull(this._ctx, now, delta) ?: Long.MAX_VALUE + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + when (event) { + FlowEvent.Start -> { + _innerCtx = conn + } + FlowEvent.Exit -> { + _innerCtx = null + + val delegate = delegate + if (delegate != null) { + reset() + delegate.onEvent(this._ctx, now, FlowEvent.Exit) + } + } + else -> delegate?.onEvent(this._ctx, now, event) + } + } + + override fun onFailure(conn: FlowConnection, cause: Throwable) { + _innerCtx = null + + val delegate = delegate + if (delegate != null) { + reset() + delegate.onFailure(this._ctx, cause) + } + } + + /** + * Start the delegate. + */ + private fun start() { + val delegate = delegate ?: return + delegate.onEvent(checkNotNull(_innerCtx), engine.clock.millis(), FlowEvent.Start) + + hasDelegateStarted = true + } + + /** + * Reset the delegate. + */ + private fun reset() { + delegate = null + hasDelegateStarted = false + } + + /** + * The requested flow rate. + */ + private var _demand: Double = 0.0 + + /** + * Update the flow counters for the transformer. + */ + private fun updateCounters(ctx: FlowConnection, delta: Long) { + if (delta <= 0) { + return + } + + val counters = _counters + val deltaS = delta / 1000.0 + val work = _demand * deltaS + val actualWork = ctx.rate * deltaS + counters.demand += work + counters.actual += actualWork + counters.overcommit += (work - actualWork) + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt new file mode 100644 index 00000000..fb6ca85d --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A [FlowSink] represents a sink with a fixed capacity. + * + * @param initialCapacity The initial capacity of the resource. + * @param engine The engine that is used for driving the flow simulation. + * @param parent The parent flow system. + */ +public class FlowSink( + private val engine: FlowEngine, + initialCapacity: Double, + private val parent: FlowSystem? = null +) : AbstractFlowConsumer(engine, initialCapacity) { + + override fun createLogic(): FlowConsumerLogic { + return object : FlowConsumerLogic { + override fun onPush( + ctx: FlowConsumerContext, + now: Long, + delta: Long, + rate: Double + ) { + updateCounters(ctx, delta) + } + + override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long) { + updateCounters(ctx, delta) + cancel() + } + + override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { + parent?.onConverge(now) + } + } + } + + override fun toString(): String = "FlowSink[capacity=$capacity]" +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt new file mode 100644 index 00000000..077b4d38 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A source of flow that is consumed by a [FlowConsumer]. + * + * Implementations of this interface should be considered stateful and must be assumed not to be re-usable + * (concurrently) for multiple [FlowConsumer]s, unless explicitly said otherwise. + */ +public interface FlowSource { + /** + * This method is invoked when the source is pulled. + * + * @param conn The connection between the source and consumer. + * @param now The virtual timestamp in milliseconds at which the pull is occurring. + * @param delta The virtual duration between this call and the last call to [onPull] in milliseconds. + * @return The duration after which the resource consumer should be pulled again. + */ + public fun onPull(conn: FlowConnection, now: Long, delta: Long): Long + + /** + * This method is invoked when an event has occurred. + * + * @param conn The connection between the source and consumer. + * @param now The virtual timestamp in milliseconds at which the event is occurring. + * @param event The event that has occurred. + */ + public fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) {} + + /** + * This method is invoked when the source throws an exception. + * + * @param conn The connection between the source and consumer. + * @param cause The cause of the failure. + */ + public fun onFailure(conn: FlowConnection, cause: Throwable) {} +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt new file mode 100644 index 00000000..db6aa69f --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A system of possible multiple sub-resources. + * + * This interface is used to model hierarchies of resource providers, which can listen efficiently to changes of the + * resource provider. + */ +public interface FlowSystem { + /** + * The parent system to which this system belongs or `null` if it has no parent. + */ + public val parent: FlowSystem? + + /** + * This method is invoked when the system has converged to a steady-state. + * + * @param timestamp The timestamp at which the system converged. + */ + public fun onConverge(timestamp: Long) +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceDomain.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceDomain.kt new file mode 100644 index 00000000..aa2713b6 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceDomain.kt @@ -0,0 +1,19 @@ +package org.opendc.simulator.flow.interference + +import org.opendc.simulator.flow.FlowSource + +/** + * An interference domain represents a system of flow stages where [flow sources][FlowSource] may incur + * performance variability due to operating on the same resource and therefore causing interference. + */ +public interface InterferenceDomain { + /** + * Compute the performance score of a participant in this interference domain. + * + * @param key The participant to obtain the score of or `null` if the participant has no key. + * @param load The overall load on the interference domain. + * @return A score representing the performance score to be applied to the resource consumer, with 1 + * meaning no influence, <1 means that performance degrades, and >1 means that performance improves. + */ + public fun apply(key: InterferenceKey?, load: Double): Double +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceKey.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceKey.kt new file mode 100644 index 00000000..d28ebde5 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/interference/InterferenceKey.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.interference + +/** + * A key that uniquely identifies a participant of an interference domain. + */ +public interface InterferenceKey diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt new file mode 100644 index 00000000..9f3afc4d --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +import org.opendc.simulator.flow.* +import java.util.ArrayDeque +import kotlin.math.max +import kotlin.math.min + +/** + * Implementation of a [FlowConnection] managing the communication between flow sources and consumers. + */ +internal class FlowConsumerContextImpl( + private val engine: FlowEngineImpl, + private val source: FlowSource, + private val logic: FlowConsumerLogic +) : FlowConsumerContext { + /** + * The clock to track simulation time. + */ + private val _clock = engine.clock + + /** + * The capacity of the resource. + */ + override var capacity: Double = 0.0 + set(value) { + val oldValue = field + + // Only changes will be propagated + if (value != oldValue) { + field = value + onCapacityChange() + } + } + + /** + * A flag to indicate the state of the context. + */ + private var _state = State.Pending + + /** + * The current processing speed of the resource. + */ + override val rate: Double + get() = _rate + private var _rate = 0.0 + + /** + * The current resource processing demand. + */ + override val demand: Double + get() = _limit + + /** + * The current state of the resource context. + */ + private var _limit: Double = 0.0 + private var _activeLimit: Double = 0.0 + private var _deadline: Long = Long.MIN_VALUE + + /** + * A flag to indicate that an update is active. + */ + private var _updateActive = false + + /** + * The update flag indicating why the update was triggered. + */ + private var _flag: Int = 0 + + /** + * The timestamp of calls to the callbacks. + */ + private var _lastUpdate: Long = Long.MIN_VALUE + private var _lastConvergence: Long = Long.MAX_VALUE + + /** + * The timers at which the context is scheduled to be interrupted. + */ + private val _timers: ArrayDeque = ArrayDeque() + + override fun start() { + check(_state == State.Pending) { "Consumer is already started" } + engine.batch { + source.onEvent(this, _clock.millis(), FlowEvent.Start) + _state = State.Active + pull() + } + } + + override fun close() { + if (_state == State.Stopped) { + return + } + + engine.batch { + _state = State.Stopped + if (!_updateActive) { + val now = _clock.millis() + val delta = max(0, now - _lastUpdate) + doStop(now, delta) + + // FIX: Make sure the context converges + _flag = _flag or FLAG_INVALIDATE + scheduleUpdate(_clock.millis()) + } + } + } + + override fun pull() { + if (_state == State.Stopped) { + return + } + + _flag = _flag or FLAG_INTERRUPT + scheduleUpdate(_clock.millis()) + } + + override fun flush() { + if (_state == State.Stopped) { + return + } + + engine.scheduleSync(_clock.millis(), this) + } + + override fun push(rate: Double) { + if (_limit == rate) { + return + } + + _limit = rate + + // Invalidate only if the active limit is change and no update is active + // If an update is active, it will already get picked up at the end of the update + if (_activeLimit != rate && !_updateActive) { + _flag = _flag or FLAG_INVALIDATE + scheduleUpdate(_clock.millis()) + } + } + + /** + * Determine whether the state of the resource context should be updated. + */ + fun shouldUpdate(timestamp: Long): Boolean { + // Either the resource context is flagged or there is a pending update at this timestamp + return _flag != 0 || _limit != _activeLimit || _deadline == timestamp + } + + /** + * Update the state of the resource context. + */ + fun doUpdate(now: Long) { + val oldState = _state + if (oldState != State.Active) { + return + } + + val lastUpdate = _lastUpdate + + _lastUpdate = now + _updateActive = true + + val delta = max(0, now - lastUpdate) + + try { + val duration = source.onPull(this, now, delta) + val newDeadline = if (duration != Long.MAX_VALUE) now + duration else duration + + // Reset update flags + _flag = 0 + + // Check whether the state has changed after [consumer.onNext] + when (_state) { + State.Active -> { + logic.onPush(this, now, delta, _limit) + + // Schedule an update at the new deadline + scheduleUpdate(now, newDeadline) + } + State.Stopped -> doStop(now, delta) + State.Pending -> throw IllegalStateException("Illegal transition to pending state") + } + + // Note: pending limit might be changed by [logic.onConsume], so re-fetch the value + val newLimit = _limit + + // Flush the changes to the flow + _activeLimit = newLimit + _deadline = newDeadline + _rate = min(capacity, newLimit) + } catch (cause: Throwable) { + doFail(now, delta, cause) + } finally { + _updateActive = false + } + } + + /** + * Prune the elapsed timers from this context. + */ + fun pruneTimers(now: Long) { + val timers = _timers + while (true) { + val head = timers.peek() + if (head == null || head.target > now) { + break + } + timers.poll() + } + } + + /** + * Try to re-schedule the resource context in case it was skipped. + */ + fun tryReschedule(now: Long) { + val deadline = _deadline + if (deadline > now && deadline != Long.MAX_VALUE) { + scheduleUpdate(now, deadline) + } + } + + /** + * This method is invoked when the system converges into a steady state. + */ + fun onConverge(timestamp: Long) { + val delta = max(0, timestamp - _lastConvergence) + _lastConvergence = timestamp + + try { + if (_state == State.Active) { + source.onEvent(this, timestamp, FlowEvent.Converge) + } + + logic.onConverge(this, timestamp, delta) + } catch (cause: Throwable) { + doFail(timestamp, max(0, timestamp - _lastUpdate), cause) + } + } + + override fun toString(): String = "FlowConsumerContextImpl[capacity=$capacity,rate=$_rate]" + + /** + * Stop the resource context. + */ + private fun doStop(now: Long, delta: Long) { + try { + source.onEvent(this, now, FlowEvent.Exit) + logic.onFinish(this, now, delta) + } catch (cause: Throwable) { + doFail(now, delta, cause) + } finally { + _deadline = Long.MAX_VALUE + _limit = 0.0 + } + } + + /** + * Fail the resource consumer. + */ + private fun doFail(now: Long, delta: Long, cause: Throwable) { + try { + source.onFailure(this, cause) + } catch (e: Throwable) { + e.addSuppressed(cause) + e.printStackTrace() + } + + logic.onFinish(this, now, delta) + } + + /** + * Indicate that the capacity of the resource has changed. + */ + private fun onCapacityChange() { + // Do not inform the consumer if it has not been started yet + if (_state != State.Active) { + return + } + + engine.batch { + // Inform the consumer of the capacity change. This might already trigger an interrupt. + source.onEvent(this, _clock.millis(), FlowEvent.Capacity) + + pull() + } + } + + /** + * Schedule an update for this resource context. + */ + private fun scheduleUpdate(now: Long) { + engine.scheduleImmediate(now, this) + } + + /** + * Schedule a delayed update for this resource context. + */ + private fun scheduleUpdate(now: Long, target: Long) { + val timers = _timers + if (target != Long.MAX_VALUE && (timers.isEmpty() || target < timers.peek().target)) { + timers.addFirst(engine.scheduleDelayed(now, this, target)) + } + } + + /** + * The state of a resource context. + */ + private enum class State { + /** + * The resource context is pending and the resource is waiting to be consumed. + */ + Pending, + + /** + * The resource context is active and the resource is currently being consumed. + */ + Active, + + /** + * The resource context is stopped and the resource cannot be consumed anymore. + */ + Stopped + } + + /** + * A flag to indicate that the context should be invalidated. + */ + private val FLAG_INVALIDATE = 0b01 + + /** + * A flag to indicate that the context should be interrupted. + */ + private val FLAG_INTERRUPT = 0b10 +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt new file mode 100644 index 00000000..141d335d --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +import org.opendc.simulator.flow.FlowCounters + +/** + * Mutable implementation of the [FlowCounters] interface. + */ +internal class FlowCountersImpl : FlowCounters { + override var demand: Double = 0.0 + override var actual: Double = 0.0 + override var overcommit: Double = 0.0 + override var interference: Double = 0.0 + + override fun reset() { + demand = 0.0 + actual = 0.0 + overcommit = 0.0 + interference = 0.0 + } + + override fun toString(): String { + return "FlowCounters[demand=$demand,actual=$actual,overcommit=$overcommit,interference=$interference]" + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt new file mode 100644 index 00000000..1a50da2c --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +import kotlinx.coroutines.Delay +import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.InternalCoroutinesApi +import kotlinx.coroutines.Runnable +import org.opendc.simulator.flow.* +import java.time.Clock +import java.util.* +import kotlin.coroutines.ContinuationInterceptor +import kotlin.coroutines.CoroutineContext + +/** + * Internal implementation of the [FlowEngine] interface. + * + * @param context The coroutine context to use. + * @param clock The virtual simulation clock. + */ +internal class FlowEngineImpl(private val context: CoroutineContext, override val clock: Clock) : FlowEngine { + /** + * The [Delay] instance that provides scheduled execution of [Runnable]s. + */ + @OptIn(InternalCoroutinesApi::class) + private val delay = requireNotNull(context[ContinuationInterceptor] as? Delay) { "Invalid CoroutineDispatcher: no delay implementation" } + + /** + * The queue of connection updates that are scheduled for immediate execution. + */ + private val queue = ArrayDeque() + + /** + * A priority queue containing the connection updates to be scheduled in the future. + */ + private val futureQueue = PriorityQueue() + + /** + * The stack of engine invocations to occur in the future. + */ + private val futureInvocations = ArrayDeque() + + /** + * The systems that have been visited during the engine cycle. + */ + private val visited = linkedSetOf() + + /** + * The index in the batch stack. + */ + private var batchIndex = 0 + + /** + * A flag to indicate that the engine is currently active. + */ + private val isRunning: Boolean + get() = batchIndex > 0 + + /** + * Update the specified [ctx] synchronously. + */ + fun scheduleSync(now: Long, ctx: FlowConsumerContextImpl) { + ctx.doUpdate(now) + visited.add(ctx) + + // In-case the engine is already running in the call-stack, return immediately. The changes will be picked + // up by the active engine. + if (isRunning) { + return + } + + try { + batchIndex++ + runEngine(now) + } finally { + batchIndex-- + } + } + + /** + * Enqueue the specified [ctx] to be updated immediately during the active engine cycle. + * + * This method should be used when the state of a flow context is invalidated/interrupted and needs to be + * re-computed. In case no engine is currently active, the engine will be started. + */ + fun scheduleImmediate(now: Long, ctx: FlowConsumerContextImpl) { + queue.add(ctx) + + // In-case the engine is already running in the call-stack, return immediately. The changes will be picked + // up by the active engine. + if (isRunning) { + return + } + + try { + batchIndex++ + runEngine(now) + } finally { + batchIndex-- + } + } + + /** + * Schedule the engine to run at [target] to update the flow contexts. + * + * This method will override earlier calls to this method for the same [ctx]. + * + * @param now The current virtual timestamp. + * @param ctx The flow context to which the event applies. + * @param target The timestamp when the interrupt should happen. + */ + fun scheduleDelayed(now: Long, ctx: FlowConsumerContextImpl, target: Long): Timer { + val futureQueue = futureQueue + + require(target >= now) { "Timestamp must be in the future" } + + val timer = Timer(ctx, target) + futureQueue.add(timer) + + return timer + } + + override fun newContext(consumer: FlowSource, provider: FlowConsumerLogic): FlowConsumerContext = FlowConsumerContextImpl(this, consumer, provider) + + override fun pushBatch() { + batchIndex++ + } + + override fun popBatch() { + try { + // Flush the work if the platform is not already running + if (batchIndex == 1 && queue.isNotEmpty()) { + runEngine(clock.millis()) + } + } finally { + batchIndex-- + } + } + + /** + * Run all the enqueued actions for the specified [timestamp][now]. + */ + private fun runEngine(now: Long) { + val queue = queue + val futureQueue = futureQueue + val futureInvocations = futureInvocations + val visited = visited + + // Remove any entries in the `futureInvocations` queue from the past + while (true) { + val head = futureInvocations.peek() + if (head == null || head.timestamp > now) { + break + } + futureInvocations.poll() + } + + // Execute all scheduled updates at current timestamp + while (true) { + val timer = futureQueue.peek() ?: break + val ctx = timer.ctx + val target = timer.target + + assert(target >= now) { "Internal inconsistency: found update of the past" } + + if (target > now) { + break + } + + futureQueue.poll() + + ctx.pruneTimers(now) + + if (ctx.shouldUpdate(now)) { + ctx.doUpdate(now) + visited.add(ctx) + } else { + ctx.tryReschedule(now) + } + } + + // Repeat execution of all immediate updates until the system has converged to a steady-state + // We have to take into account that the onConverge callback can also trigger new actions. + do { + // Execute all immediate updates + while (true) { + val ctx = queue.poll() ?: break + + if (ctx.shouldUpdate(now)) { + ctx.doUpdate(now) + visited.add(ctx) + } + } + + for (system in visited) { + system.onConverge(now) + } + + visited.clear() + } while (queue.isNotEmpty()) + + // Schedule an engine invocation for the next update to occur. + val headTimer = futureQueue.peek() + if (headTimer != null) { + trySchedule(now, futureInvocations, headTimer.target) + } + } + + /** + * Try to schedule an engine invocation at the specified [target]. + * + * @param now The current virtual timestamp. + * @param target The virtual timestamp at which the engine invocation should happen. + * @param scheduled The queue of scheduled invocations. + */ + private fun trySchedule(now: Long, scheduled: ArrayDeque, target: Long) { + while (true) { + val invocation = scheduled.peekFirst() + if (invocation == null || invocation.timestamp > target) { + // Case 2: A new timer was registered ahead of the other timers. + // Solution: Schedule a new scheduler invocation + @OptIn(InternalCoroutinesApi::class) + val handle = delay.invokeOnTimeout( + target - now, + { + try { + batchIndex++ + runEngine(target) + } finally { + batchIndex-- + } + }, + context + ) + scheduled.addFirst(Invocation(target, handle)) + break + } else if (invocation.timestamp < target) { + // Case 2: A timer was cancelled and the head of the timer queue is now later than excepted + // Solution: Cancel the next scheduler invocation + scheduled.pollFirst() + + invocation.cancel() + } else { + break + } + } + } + + /** + * A future engine invocation. + * + * This class is used to keep track of the future engine invocations created using the [Delay] instance. In case + * the invocation is not needed anymore, it can be cancelled via [cancel]. + */ + private data class Invocation( + @JvmField val timestamp: Long, + @JvmField val handle: DisposableHandle + ) { + /** + * Cancel the engine invocation. + */ + fun cancel() = handle.dispose() + } + + /** + * An update call for [ctx] that is scheduled for [target]. + * + * This class represents an update in the future at [target] requested by [ctx]. + */ + class Timer(@JvmField val ctx: FlowConsumerContextImpl, @JvmField val target: Long) : Comparable { + override fun compareTo(other: Timer): Int { + return target.compareTo(other.target) + } + + override fun toString(): String = "Timer[ctx=$ctx,timestamp=$target]" + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt new file mode 100644 index 00000000..17b82391 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import org.opendc.simulator.flow.FlowConsumer +import org.opendc.simulator.flow.FlowCounters +import org.opendc.simulator.flow.FlowSource +import org.opendc.simulator.flow.interference.InterferenceKey + +/** + * A [FlowMultiplexer] enables multiplexing multiple [FlowSource]s over possibly multiple [FlowConsumer]s. + */ +public interface FlowMultiplexer { + /** + * The inputs of the multiplexer that can be used to consume sources. + */ + public val inputs: Set + + /** + * The outputs of the multiplexer over which the flows will be distributed. + */ + public val outputs: Set + + /** + * The flow counters to track the flow metrics of all multiplexer inputs. + */ + public val counters: FlowCounters + + /** + * Create a new input on this multiplexer. + * + * @param key The key of the interference member to which the input belongs. + */ + public fun newInput(key: InterferenceKey? = null): FlowConsumer + + /** + * Remove [input] from this multiplexer. + */ + public fun removeInput(input: FlowConsumer) + + /** + * Add the specified [output] to the multiplexer. + */ + public fun addOutput(output: FlowConsumer) + + /** + * Clear all inputs and outputs from the switch. + */ + public fun clear() +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt new file mode 100644 index 00000000..811d9460 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.interference.InterferenceKey +import java.util.ArrayDeque + +/** + * A [FlowMultiplexer] implementation that allocates inputs to the outputs of the multiplexer exclusively. This means + * that a single input is directly connected to an output and that the multiplexer can only support as many + * inputs as outputs. + * + * @param engine The [FlowEngine] driving the simulation. + */ +public class ForwardingFlowMultiplexer(private val engine: FlowEngine) : FlowMultiplexer { + override val inputs: Set + get() = _inputs + private val _inputs = mutableSetOf() + + override val outputs: Set + get() = _outputs + private val _outputs = mutableSetOf() + private val _availableOutputs = ArrayDeque() + + override val counters: FlowCounters = object : FlowCounters { + override val demand: Double + get() = _outputs.sumOf { it.counters.demand } + override val actual: Double + get() = _outputs.sumOf { it.counters.actual } + override val overcommit: Double + get() = _outputs.sumOf { it.counters.overcommit } + override val interference: Double + get() = _outputs.sumOf { it.counters.interference } + + override fun reset() { + for (input in _outputs) { + input.counters.reset() + } + } + + override fun toString(): String = "FlowCounters[demand=$demand,actual=$actual,overcommit=$overcommit]" + } + + override fun newInput(key: InterferenceKey?): FlowConsumer { + val forwarder = checkNotNull(_availableOutputs.poll()) { "No capacity to serve request" } + val output = Input(forwarder) + _inputs += output + return output + } + + override fun removeInput(input: FlowConsumer) { + if (!_inputs.remove(input)) { + return + } + + (input as Input).close() + } + + override fun addOutput(output: FlowConsumer) { + if (output in outputs) { + return + } + + val forwarder = FlowForwarder(engine) + + _outputs += output + _availableOutputs += forwarder + + output.startConsumer(object : FlowSource by forwarder { + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + if (event == FlowEvent.Exit) { + // De-register the output after it has finished + _outputs -= output + } + + forwarder.onEvent(conn, now, event) + } + }) + } + + override fun clear() { + for (input in _outputs) { + input.cancel() + } + _outputs.clear() + + // Inputs are implicitly cancelled by the output forwarders + _inputs.clear() + } + + /** + * An input on the multiplexer. + */ + private inner class Input(private val forwarder: FlowForwarder) : FlowConsumer by forwarder { + /** + * Close the input. + */ + fun close() { + // We explicitly do not close the forwarder here in order to re-use it across input resources. + _inputs -= this + _availableOutputs += forwarder + } + + override fun toString(): String = "ForwardingFlowMultiplexer.Input" + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt new file mode 100644 index 00000000..9735f121 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.interference.InterferenceDomain +import org.opendc.simulator.flow.interference.InterferenceKey +import org.opendc.simulator.flow.internal.FlowCountersImpl +import kotlin.math.max +import kotlin.math.min + +/** + * A [FlowMultiplexer] implementation that multiplexes flows over the available outputs using max-min fair sharing. + * + * @param engine The [FlowEngine] to drive the flow simulation. + * @param parent The parent flow system of the multiplexer. + * @param interferenceDomain The interference domain of the multiplexer. + */ +public class MaxMinFlowMultiplexer( + private val engine: FlowEngine, + private val parent: FlowSystem? = null, + private val interferenceDomain: InterferenceDomain? = null +) : FlowMultiplexer { + /** + * The inputs of the multiplexer. + */ + override val inputs: Set + get() = _inputs + private val _inputs = mutableSetOf() + private val _activeInputs = mutableListOf() + + /** + * The outputs of the multiplexer. + */ + override val outputs: Set + get() = _outputs + private val _outputs = mutableSetOf() + private val _activeOutputs = mutableListOf() + + /** + * The flow counters of this multiplexer. + */ + public override val counters: FlowCounters + get() = _counters + private val _counters = FlowCountersImpl() + + /** + * The actual processing rate of the multiplexer. + */ + private var _rate = 0.0 + + /** + * The demanded processing rate of the input. + */ + private var _demand = 0.0 + + /** + * The capacity of the outputs. + */ + private var _capacity = 0.0 + + /** + * Flag to indicate that the scheduler is active. + */ + private var _schedulerActive = false + + override fun newInput(key: InterferenceKey?): FlowConsumer { + val provider = Input(_capacity, key) + _inputs.add(provider) + return provider + } + + override fun addOutput(output: FlowConsumer) { + val consumer = Output(output) + if (_outputs.add(output)) { + _activeOutputs.add(consumer) + output.startConsumer(consumer) + } + } + + override fun removeInput(input: FlowConsumer) { + if (!_inputs.remove(input)) { + return + } + // This cast should always succeed since only `Input` instances should be added to `_inputs` + (input as Input).close() + } + + override fun clear() { + for (input in _activeOutputs) { + input.cancel() + } + _activeOutputs.clear() + + for (output in _activeInputs) { + output.cancel() + } + _activeInputs.clear() + } + + /** + * Converge the scheduler of the multiplexer. + */ + private fun runScheduler(now: Long) { + if (_schedulerActive) { + return + } + + _schedulerActive = true + try { + doSchedule(now) + } finally { + _schedulerActive = false + } + } + + /** + * Schedule the inputs over the outputs. + */ + private fun doSchedule(now: Long) { + val activeInputs = _activeInputs + val activeOutputs = _activeOutputs + + // If there is no work yet, mark the inputs as idle. + if (activeInputs.isEmpty()) { + return + } + + val capacity = _capacity + var availableCapacity = capacity + + // Pull in the work of the outputs + val inputIterator = activeInputs.listIterator() + for (input in inputIterator) { + input.pull(now) + + // Remove outputs that have finished + if (!input.isActive) { + inputIterator.remove() + } + } + + var demand = 0.0 + + // Sort in-place the inputs based on their pushed flow. + // Profiling shows that it is faster than maintaining some kind of sorted set. + activeInputs.sort() + + // Divide the available output capacity fairly over the inputs using max-min fair sharing + var remaining = activeInputs.size + for (input in activeInputs) { + val availableShare = availableCapacity / remaining-- + val grantedRate = min(input.allowedRate, availableShare) + + // Ignore empty sources + if (grantedRate <= 0.0) { + input.actualRate = 0.0 + continue + } + + input.actualRate = grantedRate + demand += input.limit + availableCapacity -= grantedRate + } + + val rate = capacity - availableCapacity + + _demand = demand + _rate = rate + + // Sort all consumers by their capacity + activeOutputs.sort() + + // Divide the requests over the available capacity of the input resources fairly + for (output in activeOutputs) { + val inputCapacity = output.capacity + val fraction = inputCapacity / capacity + val grantedSpeed = rate * fraction + + output.push(grantedSpeed) + } + } + + /** + * Recompute the capacity of the multiplexer. + */ + private fun updateCapacity() { + val newCapacity = _activeOutputs.sumOf(Output::capacity) + + // No-op if the capacity is unchanged + if (_capacity == newCapacity) { + return + } + + _capacity = newCapacity + + for (input in _inputs) { + input.capacity = newCapacity + } + } + + /** + * An internal [FlowConsumer] implementation for multiplexer inputs. + */ + private inner class Input(capacity: Double, val key: InterferenceKey?) : + AbstractFlowConsumer(engine, capacity), + FlowConsumerLogic, + Comparable { + /** + * The requested limit. + */ + @JvmField var limit: Double = 0.0 + + /** + * The actual processing speed. + */ + @JvmField var actualRate: Double = 0.0 + + /** + * The processing rate that is allowed by the model constraints. + */ + val allowedRate: Double + get() = min(capacity, limit) + + /** + * A flag to indicate that the input is closed. + */ + private var _isClosed: Boolean = false + + /** + * The timestamp at which we received the last command. + */ + private var _lastPull: Long = Long.MIN_VALUE + + /** + * Close the input. + * + * This method is invoked when the user removes an input from the switch. + */ + fun close() { + _isClosed = true + cancel() + } + + /* AbstractFlowConsumer */ + override fun createLogic(): FlowConsumerLogic = this + + override fun start(ctx: FlowConsumerContext) { + check(!_isClosed) { "Cannot re-use closed input" } + + _activeInputs += this + super.start(ctx) + } + + /* FlowConsumerLogic */ + override fun onPush( + ctx: FlowConsumerContext, + now: Long, + delta: Long, + rate: Double + ) { + doUpdateCounters(delta) + + actualRate = 0.0 + this.limit = rate + _lastPull = now + + runScheduler(now) + } + + override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { + parent?.onConverge(now) + } + + override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long) { + doUpdateCounters(delta) + + limit = 0.0 + actualRate = 0.0 + _lastPull = now + } + + /* Comparable */ + override fun compareTo(other: Input): Int = allowedRate.compareTo(other.allowedRate) + + /** + * Pull the source if necessary. + */ + fun pull(now: Long) { + val ctx = ctx + if (ctx != null && _lastPull < now) { + ctx.flush() + } + } + + /** + * Helper method to update the flow counters of the multiplexer. + */ + private fun doUpdateCounters(delta: Long) { + if (delta <= 0L) { + return + } + + // Compute the performance penalty due to flow interference + val perfScore = if (interferenceDomain != null) { + val load = _rate / capacity + interferenceDomain.apply(key, load) + } else { + 1.0 + } + + val deltaS = delta / 1000.0 + val work = limit * deltaS + val actualWork = actualRate * deltaS + val remainingWork = work - actualWork + + updateCounters(work, actualWork, remainingWork) + + val distCounters = _counters + distCounters.demand += work + distCounters.actual += actualWork + distCounters.overcommit += remainingWork + distCounters.interference += actualWork * max(0.0, 1 - perfScore) + } + } + + /** + * An internal [FlowSource] implementation for multiplexer outputs. + */ + private inner class Output(private val provider: FlowConsumer) : FlowSource, Comparable { + /** + * The active [FlowConnection] of this source. + */ + private var _ctx: FlowConnection? = null + + /** + * The capacity of this output. + */ + val capacity: Double + get() = _ctx?.capacity ?: 0.0 + + /** + * Push the specified rate to the consumer. + */ + fun push(rate: Double) { + _ctx?.push(rate) + } + + /** + * Cancel this output. + */ + fun cancel() { + provider.cancel() + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + runScheduler(now) + return Long.MAX_VALUE + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + when (event) { + FlowEvent.Start -> { + assert(_ctx == null) { "Source running concurrently" } + _ctx = conn + updateCapacity() + } + FlowEvent.Exit -> { + _ctx = null + updateCapacity() + } + FlowEvent.Capacity -> updateCapacity() + else -> {} + } + } + + override fun compareTo(other: Output): Int = capacity.compareTo(other.capacity) + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FixedFlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FixedFlowSource.kt new file mode 100644 index 00000000..d9779c6a --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FixedFlowSource.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.source + +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowSource +import kotlin.math.roundToLong + +/** + * A [FlowSource] that contains a fixed [amount] and is pushed with a given [utilization]. + */ +public class FixedFlowSource(private val amount: Double, private val utilization: Double) : FlowSource { + + init { + require(amount >= 0.0) { "Amount must be positive" } + require(utilization > 0.0) { "Utilization must be positive" } + } + + private var remainingAmount = amount + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val consumed = conn.rate * delta / 1000.0 + val limit = conn.capacity * utilization + + remainingAmount -= consumed + + val duration = (remainingAmount / limit * 1000).roundToLong() + + return if (duration > 0) { + conn.push(limit) + duration + } else { + conn.close() + Long.MAX_VALUE + } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceBarrier.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceBarrier.kt new file mode 100644 index 00000000..b3191ad3 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceBarrier.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.source + +/** + * The [FlowSourceBarrier] is a barrier that allows multiple sources to wait for a select number of other sources to + * finish a pull, before proceeding its operation. + */ +public class FlowSourceBarrier(public val parties: Int) { + private var counter = 0 + + /** + * Enter the barrier and determine whether the caller is the last to reach the barrier. + * + * @return `true` if the caller is the last to reach the barrier, `false` otherwise. + */ + public fun enter(): Boolean { + val last = ++counter == parties + if (last) { + counter = 0 + return true + } + return false + } + + /** + * Reset the barrier. + */ + public fun reset() { + counter = 0 + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt new file mode 100644 index 00000000..7fcc0405 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.source + +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource +import kotlin.math.min + +/** + * Helper class to expose an observable [speed] field describing the speed of the consumer. + */ +public class FlowSourceRateAdapter( + private val delegate: FlowSource, + private val callback: (Double) -> Unit = {} +) : FlowSource by delegate { + /** + * The resource processing speed at this instant. + */ + public var speed: Double = 0.0 + private set(value) { + if (field != value) { + callback(value) + field = value + } + } + + init { + callback(0.0) + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return delegate.onPull(conn, now, delta) + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + val oldSpeed = speed + + delegate.onEvent(conn, now, event) + + when (event) { + FlowEvent.Converge -> speed = conn.rate + FlowEvent.Capacity -> { + // Check if the consumer interrupted the consumer and updated the resource consumption. If not, we might + // need to update the current speed. + if (oldSpeed == speed) { + speed = min(conn.capacity, speed) + } + } + FlowEvent.Exit -> speed = 0.0 + else -> {} + } + } + + override fun onFailure(conn: FlowConnection, cause: Throwable) { + speed = 0.0 + + delegate.onFailure(conn, cause) + } + + override fun toString(): String = "FlowSourceRateAdapter[delegate=$delegate]" +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt new file mode 100644 index 00000000..4d3ae61a --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.source + +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource + +/** + * A [FlowSource] that replays a sequence of [Fragment], each indicating the flow rate for some period of time. + */ +public class TraceFlowSource(private val trace: Sequence) : FlowSource { + private var _iterator: Iterator? = null + private var _nextTarget = Long.MIN_VALUE + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + // Check whether the trace fragment was fully consumed, otherwise wait until we have done so + val nextTarget = _nextTarget + if (nextTarget > now) { + return now - nextTarget + } + + val iterator = checkNotNull(_iterator) + return if (iterator.hasNext()) { + val fragment = iterator.next() + _nextTarget = now + fragment.duration + conn.push(fragment.usage) + fragment.duration + } else { + conn.close() + Long.MAX_VALUE + } + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + when (event) { + FlowEvent.Start -> { + check(_iterator == null) { "Source already running" } + _iterator = trace.iterator() + } + FlowEvent.Exit -> { + _iterator = null + } + else -> {} + } + } + + /** + * A fragment of the tgrace. + */ + public data class Fragment(val duration: Long, val usage: Double) +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt new file mode 100644 index 00000000..061ebea6 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import io.mockk.* +import kotlinx.coroutines.* +import org.junit.jupiter.api.* +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.internal.FlowConsumerContextImpl +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource + +/** + * A test suite for the [FlowConsumerContextImpl] class. + */ +class FlowConsumerContextTest { + @Test + fun testFlushWithoutCommand() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val consumer = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (now == 0L) { + conn.push(1.0) + 1000 + } else { + conn.close() + Long.MAX_VALUE + } + } + } + + val logic = object : FlowConsumerLogic {} + val context = FlowConsumerContextImpl(engine, consumer, logic) + + engine.scheduleSync(engine.clock.millis(), context) + } + + @Test + fun testIntermediateFlush() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val consumer = FixedFlowSource(1.0, 1.0) + + val logic = spyk(object : FlowConsumerLogic {}) + val context = FlowConsumerContextImpl(engine, consumer, logic) + context.capacity = 1.0 + + context.start() + delay(1) // Delay 1 ms to prevent hitting the fast path + engine.scheduleSync(engine.clock.millis(), context) + + verify(exactly = 2) { logic.onPush(any(), any(), any(), any()) } + } + + @Test + fun testDoubleStart() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val consumer = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (now == 0L) { + conn.push(0.0) + 1000 + } else { + conn.close() + Long.MAX_VALUE + } + } + } + + val logic = object : FlowConsumerLogic {} + val context = FlowConsumerContextImpl(engine, consumer, logic) + + context.start() + + assertThrows { + context.start() + } + } + + @Test + fun testIdempotentCapacityChange() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val consumer = spyk(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (now == 0L) { + conn.push(1.0) + 1000 + } else { + conn.close() + Long.MAX_VALUE + } + } + }) + + val logic = object : FlowConsumerLogic {} + val context = FlowConsumerContextImpl(engine, consumer, logic) + context.capacity = 4200.0 + context.start() + context.capacity = 4200.0 + + verify(exactly = 0) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } + } + + @Test + fun testFailureNoInfiniteLoop() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val consumer = spyk(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + conn.close() + return Long.MAX_VALUE + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + if (event == FlowEvent.Exit) throw IllegalStateException("onEvent") + } + + override fun onFailure(conn: FlowConnection, cause: Throwable) { + throw IllegalStateException("onFailure") + } + }) + + val logic = object : FlowConsumerLogic {} + + val context = FlowConsumerContextImpl(engine, consumer, logic) + + context.start() + + delay(1) + + verify(exactly = 1) { consumer.onFailure(any(), any()) } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt new file mode 100644 index 00000000..cbc48a4e --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import io.mockk.spyk +import io.mockk.verify +import kotlinx.coroutines.* +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource + +/** + * A test suite for the [FlowForwarder] class. + */ +internal class FlowForwarderTest { + @Test + fun testCancelImmediately() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 2000.0) + + launch { source.consume(forwarder) } + + forwarder.consume(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + conn.close() + return Long.MAX_VALUE + } + }) + + forwarder.close() + source.cancel() + } + + @Test + fun testCancel() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 2000.0) + + launch { source.consume(forwarder) } + + forwarder.consume(object : FlowSource { + var isFirst = true + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + conn.push(1.0) + 10 * 1000 + } else { + conn.close() + Long.MAX_VALUE + } + } + }) + + forwarder.close() + source.cancel() + } + + @Test + fun testState() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val consumer = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + conn.close() + return Long.MAX_VALUE + } + } + + assertFalse(forwarder.isActive) + + forwarder.startConsumer(consumer) + assertTrue(forwarder.isActive) + + assertThrows { forwarder.startConsumer(consumer) } + + forwarder.cancel() + assertFalse(forwarder.isActive) + + forwarder.close() + assertFalse(forwarder.isActive) + } + + @Test + fun testCancelPendingDelegate() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + + val consumer = spyk(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + conn.close() + return Long.MAX_VALUE + } + }) + + forwarder.startConsumer(consumer) + forwarder.cancel() + + verify(exactly = 0) { consumer.onEvent(any(), any(), FlowEvent.Exit) } + } + + @Test + fun testCancelStartedDelegate() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 2000.0) + + val consumer = spyk(FixedFlowSource(2000.0, 1.0)) + + source.startConsumer(forwarder) + yield() + forwarder.startConsumer(consumer) + yield() + forwarder.cancel() + + verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Start) } + verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Exit) } + } + + @Test + fun testCancelPropagation() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 2000.0) + + val consumer = spyk(FixedFlowSource(2000.0, 1.0)) + + source.startConsumer(forwarder) + yield() + forwarder.startConsumer(consumer) + yield() + source.cancel() + + verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Start) } + verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Exit) } + } + + @Test + fun testExitPropagation() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine, isCoupled = true) + val source = FlowSink(engine, 2000.0) + + val consumer = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + conn.close() + return Long.MAX_VALUE + } + } + + source.startConsumer(forwarder) + forwarder.consume(consumer) + yield() + + assertFalse(forwarder.isActive) + } + + @Test + fun testAdjustCapacity() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 1.0) + + val consumer = spyk(FixedFlowSource(2.0, 1.0)) + source.startConsumer(forwarder) + + coroutineScope { + launch { forwarder.consume(consumer) } + delay(1000) + source.capacity = 0.5 + } + + assertEquals(3000, clock.millis()) + verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } + } + + @Test + fun testCounters() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 1.0) + + val consumer = FixedFlowSource(2.0, 1.0) + source.startConsumer(forwarder) + + forwarder.consume(consumer) + + yield() + + assertEquals(2.0, source.counters.actual) + assertEquals(source.counters.actual, forwarder.counters.actual) { "Actual work" } + assertEquals(source.counters.demand, forwarder.counters.demand) { "Work demand" } + assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } + assertEquals(2000, clock.millis()) + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt new file mode 100644 index 00000000..010a985e --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import kotlinx.coroutines.* +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource +import org.opendc.simulator.flow.source.FlowSourceRateAdapter + +/** + * A test suite for the [FlowSink] class. + */ +internal class FlowSinkTest { + @Test + fun testSpeed() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = FixedFlowSource(4200.0, 1.0) + + val res = mutableListOf() + val adapter = FlowSourceRateAdapter(consumer, res::add) + + provider.consume(adapter) + + assertEquals(listOf(0.0, capacity, 0.0), res) { "Speed is reported correctly" } + } + + @Test + fun testAdjustCapacity() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val provider = FlowSink(engine, 1.0) + + val consumer = spyk(FixedFlowSource(2.0, 1.0)) + + coroutineScope { + launch { provider.consume(consumer) } + delay(1000) + provider.capacity = 0.5 + } + assertEquals(3000, clock.millis()) + verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } + } + + @Test + fun testSpeedLimit() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = FixedFlowSource(capacity, 2.0) + + val res = mutableListOf() + val adapter = FlowSourceRateAdapter(consumer, res::add) + + provider.consume(adapter) + + assertEquals(listOf(0.0, capacity, 0.0), res) { "Speed is reported correctly" } + } + + /** + * Test to see whether no infinite recursion occurs when interrupting during [FlowSource.onStart] or + * [FlowSource.onPull]. + */ + @Test + fun testIntermediateInterrupt() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + conn.close() + return Long.MAX_VALUE + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + conn.pull() + } + } + + provider.consume(consumer) + } + + @Test + fun testInterrupt() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + lateinit var resCtx: FlowConnection + + val consumer = object : FlowSource { + var isFirst = true + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + when (event) { + FlowEvent.Start -> resCtx = conn + else -> {} + } + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + conn.push(1.0) + 4000 + } else { + conn.close() + Long.MAX_VALUE + } + } + } + + launch { + yield() + resCtx.pull() + } + provider.consume(consumer) + + assertEquals(0, clock.millis()) + } + + @Test + fun testFailure() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = mockk(relaxUnitFun = true) + every { consumer.onEvent(any(), any(), eq(FlowEvent.Start)) } + .throws(IllegalStateException()) + + assertThrows { + provider.consume(consumer) + } + } + + @Test + fun testExceptionPropagationOnNext() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = object : FlowSource { + var isFirst = true + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + conn.push(1.0) + 1000 + } else { + throw IllegalStateException() + } + } + } + + assertThrows { + provider.consume(consumer) + } + } + + @Test + fun testConcurrentConsumption() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = FixedFlowSource(capacity, 1.0) + + assertThrows { + coroutineScope { + launch { provider.consume(consumer) } + provider.consume(consumer) + } + } + } + + @Test + fun testCancelDuringConsumption() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = FixedFlowSource(capacity, 1.0) + + launch { provider.consume(consumer) } + delay(500) + provider.cancel() + + yield() + + assertEquals(500, clock.millis()) + } + + @Test + fun testInfiniteSleep() { + assertThrows { + runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val capacity = 4200.0 + val provider = FlowSink(engine, capacity) + + val consumer = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long = Long.MAX_VALUE + } + + provider.consume(consumer) + } + } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt new file mode 100644 index 00000000..b503087e --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import kotlinx.coroutines.yield +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource +import org.opendc.simulator.flow.source.FlowSourceRateAdapter +import org.opendc.simulator.flow.source.TraceFlowSource + +/** + * Test suite for the [ForwardingFlowMultiplexer] class. + */ +internal class SimResourceSwitchExclusiveTest { + /** + * Test a trace workload. + */ + @Test + fun testTrace() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val speed = mutableListOf() + + val duration = 5 * 60L + val workload = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + val forwarder = FlowForwarder(engine) + val adapter = FlowSourceRateAdapter(forwarder, speed::add) + source.startConsumer(adapter) + switch.addOutput(forwarder) + + val provider = switch.newInput() + provider.consume(workload) + yield() + + assertAll( + { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, + { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } + ) + } + + /** + * Test runtime workload on hypervisor. + */ + @Test + fun testRuntimeWorkload() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L * 1000 + val workload = FixedFlowSource(duration * 3.2, 1.0) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + switch.addOutput(source) + + val provider = switch.newInput() + provider.consume(workload) + yield() + + assertEquals(duration, clock.millis()) { "Took enough time" } + } + + /** + * Test two workloads running sequentially. + */ + @Test + fun testTwoWorkloads() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L * 1000 + val workload = object : FlowSource { + var isFirst = true + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + when (event) { + FlowEvent.Start -> isFirst = true + else -> {} + } + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + conn.push(1.0) + duration + } else { + conn.close() + Long.MAX_VALUE + } + } + } + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + switch.addOutput(source) + + val provider = switch.newInput() + provider.consume(workload) + yield() + provider.consume(workload) + assertEquals(duration * 2, clock.millis()) { "Took enough time" } + } + + /** + * Test concurrent workloads on the machine. + */ + @Test + fun testConcurrentWorkloadFails() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + switch.addOutput(source) + + switch.newInput() + assertThrows { switch.newInput() } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt new file mode 100644 index 00000000..089a8d78 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.FlowSink +import org.opendc.simulator.flow.consume +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource +import org.opendc.simulator.flow.source.TraceFlowSource + +/** + * Test suite for the [FlowMultiplexer] implementations + */ +internal class SimResourceSwitchMaxMinTest { + @Test + fun testSmoke() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + val switch = MaxMinFlowMultiplexer(scheduler) + + val sources = List(2) { FlowSink(scheduler, 2000.0) } + sources.forEach { switch.addOutput(it) } + + val provider = switch.newInput() + val consumer = FixedFlowSource(2000.0, 1.0) + + try { + provider.consume(consumer) + yield() + } finally { + switch.clear() + } + } + + /** + * Test overcommitting of resources via the hypervisor with a single VM. + */ + @Test + fun testOvercommittedSingle() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L + val workload = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + + val switch = MaxMinFlowMultiplexer(scheduler) + val provider = switch.newInput() + + try { + switch.addOutput(FlowSink(scheduler, 3200.0)) + provider.consume(workload) + yield() + } finally { + switch.clear() + } + + assertAll( + { assertEquals(1113300.0, switch.counters.demand, "Requested work does not match") }, + { assertEquals(1023300.0, switch.counters.actual, "Actual work does not match") }, + { assertEquals(90000.0, switch.counters.overcommit, "Overcommitted work does not match") }, + { assertEquals(1200000, clock.millis()) } + ) + } + + /** + * Test overcommitting of resources via the hypervisor with two VMs. + */ + @Test + fun testOvercommittedDual() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L + val workloadA = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + val workloadB = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3100.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 73.0) + ) + ) + + val switch = MaxMinFlowMultiplexer(scheduler) + val providerA = switch.newInput() + val providerB = switch.newInput() + + try { + switch.addOutput(FlowSink(scheduler, 3200.0)) + + coroutineScope { + launch { providerA.consume(workloadA) } + providerB.consume(workloadB) + } + + yield() + } finally { + switch.clear() + } + assertAll( + { assertEquals(2073600.0, switch.counters.demand, "Requested work does not match") }, + { assertEquals(1053600.0, switch.counters.actual, "Granted work does not match") }, + { assertEquals(1020000.0, switch.counters.overcommit, "Overcommitted work does not match") }, + { assertEquals(1200000, clock.millis()) } + ) + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/source/FixedFlowSourceTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/source/FixedFlowSourceTest.kt new file mode 100644 index 00000000..8396d346 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/source/FixedFlowSourceTest.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.source + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.FlowSink +import org.opendc.simulator.flow.consume +import org.opendc.simulator.flow.internal.FlowEngineImpl + +/** + * A test suite for the [FixedFlowSource] class. + */ +internal class FixedFlowSourceTest { + @Test + fun testSmoke() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + val provider = FlowSink(scheduler, 1.0) + + val consumer = FixedFlowSource(1.0, 1.0) + + provider.consume(consumer) + assertEquals(1000, clock.millis()) + } + + @Test + fun testUtilization() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + val provider = FlowSink(scheduler, 1.0) + + val consumer = FixedFlowSource(1.0, 0.5) + + provider.consume(consumer) + assertEquals(2000, clock.millis()) + } +} diff --git a/opendc-simulator/opendc-simulator-network/build.gradle.kts b/opendc-simulator/opendc-simulator-network/build.gradle.kts index eb9adcd1..a8f94602 100644 --- a/opendc-simulator/opendc-simulator-network/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-network/build.gradle.kts @@ -30,6 +30,6 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) - api(projects.opendcSimulator.opendcSimulatorResources) + api(projects.opendcSimulator.opendcSimulatorFlow) implementation(projects.opendcSimulator.opendcSimulatorCore) } diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt index 102e5625..4b66d5cf 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt @@ -22,8 +22,8 @@ package org.opendc.simulator.network -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceProvider +import org.opendc.simulator.flow.FlowConsumer +import org.opendc.simulator.flow.FlowSource /** * A network port allows network devices to be connected to network through links. @@ -78,14 +78,14 @@ public abstract class SimNetworkPort { } /** - * Create a [SimResourceConsumer] which generates the outgoing traffic of this port. + * Create a [FlowSource] which generates the outgoing traffic of this port. */ - protected abstract fun createConsumer(): SimResourceConsumer + protected abstract fun createConsumer(): FlowSource /** - * The [SimResourceProvider] which processes the ingoing traffic of this port. + * The [FlowConsumer] which processes the ingoing traffic of this port. */ - protected abstract val provider: SimResourceProvider + protected abstract val provider: FlowConsumer override fun toString(): String = "SimNetworkPort[isConnected=$isConnected]" } diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt index 7db0f176..4b0d7bbd 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt @@ -22,22 +22,22 @@ package org.opendc.simulator.network -import org.opendc.simulator.resources.* +import org.opendc.simulator.flow.* /** * A network sink which discards all received traffic and does not generate any traffic itself. */ public class SimNetworkSink( - interpreter: SimResourceInterpreter, + engine: FlowEngine, public val capacity: Double ) : SimNetworkPort() { - override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long = Long.MAX_VALUE + override fun createConsumer(): FlowSource = object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long = Long.MAX_VALUE override fun toString(): String = "SimNetworkSink.Consumer" } - override val provider: SimResourceProvider = SimResourceSource(capacity, interpreter) + override val provider: FlowConsumer = FlowSink(engine, capacity) override fun toString(): String = "SimNetworkSink[capacity=$capacity]" } diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt index 2267715e..2b7c1ad7 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt @@ -22,12 +22,13 @@ package org.opendc.simulator.network -import org.opendc.simulator.resources.* +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer /** * A [SimNetworkSwitch] that can support new networking ports on demand. */ -public class SimNetworkSwitchVirtual(interpreter: SimResourceInterpreter) : SimNetworkSwitch { +public class SimNetworkSwitchVirtual(private val engine: FlowEngine) : SimNetworkSwitch { /** * The ports of this switch. */ @@ -36,9 +37,9 @@ public class SimNetworkSwitchVirtual(interpreter: SimResourceInterpreter) : SimN private val _ports = mutableListOf() /** - * The [SimResourceSwitchMaxMin] to actually perform the switching. + * The [MaxMinFlowMultiplexer] to actually perform the switching. */ - private val switch = SimResourceSwitchMaxMin(interpreter) + private val mux = MaxMinFlowMultiplexer(engine) /** * Open a new port on the switch. @@ -58,19 +59,19 @@ public class SimNetworkSwitchVirtual(interpreter: SimResourceInterpreter) : SimN */ private var isClosed: Boolean = false - override val provider: SimResourceProvider + override val provider: FlowConsumer get() = _provider - private val _provider = switch.newOutput() + private val _provider = mux.newInput() - override fun createConsumer(): SimResourceConsumer { - val forwarder = SimResourceForwarder(isCoupled = true) - switch.addInput(forwarder) + override fun createConsumer(): FlowSource { + val forwarder = FlowForwarder(engine, isCoupled = true) + mux.addOutput(forwarder) return forwarder } override fun close() { isClosed = true - switch.removeOutput(_provider) + mux.removeInput(_provider) _ports.remove(this) } } diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt index b8c4b00d..45d0bcf0 100644 --- a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt @@ -31,8 +31,8 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.* -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.source.FixedFlowSource /** * Test suite for the [SimNetworkSink] class. @@ -40,8 +40,8 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer class SimNetworkSinkTest { @Test fun testInitialState() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) assertFalse(sink.isConnected) assertNull(sink.link) @@ -50,8 +50,8 @@ class SimNetworkSinkTest { @Test fun testDisconnectIdempotent() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) assertDoesNotThrow { sink.disconnect() } assertFalse(sink.isConnected) @@ -59,8 +59,8 @@ class SimNetworkSinkTest { @Test fun testConnectCircular() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) assertThrows { sink.connect(sink) @@ -69,8 +69,8 @@ class SimNetworkSinkTest { @Test fun testConnectAlreadyConnectedTarget() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) val source = mockk(relaxUnitFun = true) every { source.isConnected } returns true @@ -81,9 +81,9 @@ class SimNetworkSinkTest { @Test fun testConnectAlreadyConnected() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) - val source1 = Source(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) + val source1 = Source(engine) val source2 = mockk(relaxUnitFun = true) @@ -97,9 +97,9 @@ class SimNetworkSinkTest { @Test fun testConnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) - val source = spyk(Source(interpreter)) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) + val source = spyk(Source(engine)) val consumer = source.consumer sink.connect(source) @@ -108,14 +108,14 @@ class SimNetworkSinkTest { assertTrue(source.isConnected) verify { source.createConsumer() } - verify { consumer.onEvent(any(), SimResourceEvent.Start) } + verify { consumer.onEvent(any(), any(), FlowEvent.Start) } } @Test fun testDisconnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) - val source = spyk(Source(interpreter)) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) + val source = spyk(Source(engine)) val consumer = source.consumer sink.connect(source) @@ -124,14 +124,14 @@ class SimNetworkSinkTest { assertFalse(sink.isConnected) assertFalse(source.isConnected) - verify { consumer.onEvent(any(), SimResourceEvent.Exit) } + verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } } - private class Source(interpreter: SimResourceInterpreter) : SimNetworkPort() { - val consumer = spyk(SimWorkConsumer(Double.POSITIVE_INFINITY, utilization = 0.8)) + private class Source(engine: FlowEngine) : SimNetworkPort() { + val consumer = spyk(FixedFlowSource(Double.POSITIVE_INFINITY, utilization = 0.8)) - public override fun createConsumer(): SimResourceConsumer = consumer + public override fun createConsumer(): FlowSource = consumer - override val provider: SimResourceProvider = SimResourceSource(0.0, interpreter) + override val provider: FlowConsumer = FlowSink(engine, 0.0) } } diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt index 3a749bfe..4aa2fa92 100644 --- a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt @@ -28,8 +28,8 @@ import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.* -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.source.FixedFlowSource /** * Test suite for the [SimNetworkSwitchVirtual] class. @@ -37,10 +37,10 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer class SimNetworkSwitchVirtualTest { @Test fun testConnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) - val source = spyk(Source(interpreter)) - val switch = SimNetworkSwitchVirtual(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) + val source = spyk(Source(engine)) + val switch = SimNetworkSwitchVirtual(engine) val consumer = source.consumer switch.newPort().connect(sink) @@ -50,14 +50,14 @@ class SimNetworkSwitchVirtualTest { assertTrue(source.isConnected) verify { source.createConsumer() } - verify { consumer.onEvent(any(), SimResourceEvent.Start) } + verify { consumer.onEvent(any(), any(), FlowEvent.Start) } } @Test fun testConnectClosedPort() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val sink = SimNetworkSink(interpreter, capacity = 100.0) - val switch = SimNetworkSwitchVirtual(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val sink = SimNetworkSink(engine, capacity = 100.0) + val switch = SimNetworkSwitchVirtual(engine) val port = switch.newPort() port.close() @@ -67,11 +67,11 @@ class SimNetworkSwitchVirtualTest { } } - private class Source(interpreter: SimResourceInterpreter) : SimNetworkPort() { - val consumer = spyk(SimWorkConsumer(Double.POSITIVE_INFINITY, utilization = 0.8)) + private class Source(engine: FlowEngine) : SimNetworkPort() { + val consumer = spyk(FixedFlowSource(Double.POSITIVE_INFINITY, utilization = 0.8)) - public override fun createConsumer(): SimResourceConsumer = consumer + public override fun createConsumer(): FlowSource = consumer - override val provider: SimResourceProvider = SimResourceSource(0.0, interpreter) + override val provider: FlowConsumer = FlowSink(engine, 0.0) } } diff --git a/opendc-simulator/opendc-simulator-power/build.gradle.kts b/opendc-simulator/opendc-simulator-power/build.gradle.kts index f2a49964..e4342a6a 100644 --- a/opendc-simulator/opendc-simulator-power/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-power/build.gradle.kts @@ -30,6 +30,6 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) - api(projects.opendcSimulator.opendcSimulatorResources) + api(projects.opendcSimulator.opendcSimulatorFlow) implementation(projects.opendcSimulator.opendcSimulatorCore) } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index 1a12a52a..c33f5186 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -22,46 +22,48 @@ package org.opendc.simulator.power -import org.opendc.simulator.resources.* +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.mux.FlowMultiplexer +import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer /** * A model of a Power Distribution Unit (PDU). * - * @param interpreter The underlying [SimResourceInterpreter] to drive the simulation under the hood. + * @param engine The underlying [FlowEngine] to drive the simulation under the hood. * @param idlePower The idle power consumption of the PDU independent of the load on the PDU. * @param lossCoefficient The coefficient for the power loss of the PDU proportional to the square load. */ public class SimPdu( - interpreter: SimResourceInterpreter, + engine: FlowEngine, private val idlePower: Double = 0.0, private val lossCoefficient: Double = 0.0, ) : SimPowerInlet() { /** - * The [SimResourceSwitch] that distributes the electricity over the PDU outlets. + * The [FlowMultiplexer] that distributes the electricity over the PDU outlets. */ - private val switch = SimResourceSwitchMaxMin(interpreter) + private val mux = MaxMinFlowMultiplexer(engine) /** - * The [SimResourceForwarder] that represents the input of the PDU. + * The [FlowForwarder] that represents the input of the PDU. */ - private val forwarder = SimResourceForwarder() + private val forwarder = FlowForwarder(engine) /** * Create a new PDU outlet. */ - public fun newOutlet(): Outlet = Outlet(switch, switch.newOutput()) + public fun newOutlet(): Outlet = Outlet(mux, mux.newInput()) init { - switch.addInput(forwarder) + mux.addOutput(forwarder) } - override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer by forwarder { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val duration = forwarder.onNext(ctx, now, delta) - val loss = computePowerLoss(ctx.demand) - val newLimit = ctx.demand + loss + override fun createConsumer(): FlowSource = object : FlowSource by forwarder { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val duration = forwarder.onPull(conn, now, delta) + val loss = computePowerLoss(conn.demand) + val newLimit = conn.demand + loss - ctx.push(newLimit) + conn.push(newLimit) return duration } @@ -81,7 +83,7 @@ public class SimPdu( /** * A PDU outlet. */ - public class Outlet(private val switch: SimResourceSwitch, private val provider: SimResourceProvider) : SimPowerOutlet(), AutoCloseable { + public class Outlet(private val switch: FlowMultiplexer, private val provider: FlowConsumer) : SimPowerOutlet(), AutoCloseable { override fun onConnect(inlet: SimPowerInlet) { provider.startConsumer(inlet.createConsumer()) } @@ -94,7 +96,7 @@ public class SimPdu( * Remove the outlet from the PDU. */ override fun close() { - switch.removeOutput(provider) + switch.removeInput(provider) } override fun toString(): String = "SimPdu.Outlet" diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt index 0ac1f199..851b28a5 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt @@ -22,7 +22,7 @@ package org.opendc.simulator.power -import org.opendc.simulator.resources.SimResourceConsumer +import org.opendc.simulator.flow.FlowSource /** * An abstract inlet that consumes electricity from a power outlet. @@ -42,7 +42,7 @@ public abstract class SimPowerInlet { internal var _outlet: SimPowerOutlet? = null /** - * Create a [SimResourceConsumer] which represents the consumption of electricity from the power outlet. + * Create a [FlowSource] which represents the consumption of electricity from the power outlet. */ - public abstract fun createConsumer(): SimResourceConsumer + public abstract fun createConsumer(): FlowSource } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt index 3ef8ccc6..7faebd75 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt @@ -22,25 +22,25 @@ package org.opendc.simulator.power -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.SimResourceSource +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowSink /** * A [SimPowerOutlet] that represents a source of electricity. * - * @param interpreter The underlying [SimResourceInterpreter] to drive the simulation under the hood. + * @param engine The underlying [FlowEngine] to drive the simulation under the hood. */ -public class SimPowerSource(interpreter: SimResourceInterpreter, public val capacity: Double) : SimPowerOutlet() { +public class SimPowerSource(engine: FlowEngine, public val capacity: Double) : SimPowerOutlet() { /** * The resource source that drives this power source. */ - private val source = SimResourceSource(capacity, interpreter) + private val source = FlowSink(engine, capacity) /** * The power draw at this instant. */ public val powerDraw: Double - get() = source.speed + get() = source.rate override fun onConnect(inlet: SimPowerInlet) { source.startConsumer(inlet.createConsumer()) diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 9c7400ed..5eaa91af 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -22,50 +22,51 @@ package org.opendc.simulator.power -import org.opendc.simulator.resources.* +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer /** * A model of an Uninterruptible Power Supply (UPS). * * This model aggregates multiple power sources into a single source in order to ensure that power is always available. * - * @param interpreter The underlying [SimResourceInterpreter] to drive the simulation under the hood. + * @param engine The underlying [FlowEngine] to drive the simulation under the hood. * @param idlePower The idle power consumption of the UPS independent of the load. * @param lossCoefficient The coefficient for the power loss of the UPS proportional to the load. */ public class SimUps( - interpreter: SimResourceInterpreter, + private val engine: FlowEngine, private val idlePower: Double = 0.0, private val lossCoefficient: Double = 0.0, ) : SimPowerOutlet() { /** * The resource aggregator used to combine the input sources. */ - private val switch = SimResourceSwitchMaxMin(interpreter) + private val switch = MaxMinFlowMultiplexer(engine) /** - * The [SimResourceProvider] that represents the output of the UPS. + * The [FlowConsumer] that represents the output of the UPS. */ - private val provider = switch.newOutput() + private val provider = switch.newInput() /** * Create a new UPS outlet. */ public fun newInlet(): SimPowerInlet { - val forward = SimResourceForwarder(isCoupled = true) - switch.addInput(forward) + val forward = FlowForwarder(engine, isCoupled = true) + switch.addOutput(forward) return Inlet(forward) } override fun onConnect(inlet: SimPowerInlet) { val consumer = inlet.createConsumer() - provider.startConsumer(object : SimResourceConsumer by consumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val duration = consumer.onNext(ctx, now, delta) - val loss = computePowerLoss(ctx.demand) - val newLimit = ctx.demand + loss + provider.startConsumer(object : FlowSource by consumer { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val duration = consumer.onPull(conn, now, delta) + val loss = computePowerLoss(conn.demand) + val newLimit = conn.demand + loss - ctx.push(newLimit) + conn.push(newLimit) return duration } }) @@ -86,8 +87,8 @@ public class SimUps( /** * A UPS inlet. */ - public inner class Inlet(private val forwarder: SimResourceForwarder) : SimPowerInlet(), AutoCloseable { - override fun createConsumer(): SimResourceConsumer = forwarder + public inner class Inlet(private val forwarder: FlowForwarder) : SimPowerInlet(), AutoCloseable { + override fun createConsumer(): FlowSource = forwarder /** * Remove the inlet from the PSU. diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt index 17a174b7..568a1e8c 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt @@ -28,10 +28,10 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceEvent -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource +import org.opendc.simulator.flow.source.FixedFlowSource /** * Test suite for the [SimPdu] class. @@ -39,9 +39,9 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer internal class SimPduTest { @Test fun testZeroOutlets() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val pdu = SimPdu(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val pdu = SimPdu(engine) source.connect(pdu) assertEquals(0.0, source.powerDraw) @@ -49,9 +49,9 @@ internal class SimPduTest { @Test fun testSingleOutlet() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val pdu = SimPdu(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val pdu = SimPdu(engine) source.connect(pdu) pdu.newOutlet().connect(SimpleInlet()) @@ -60,9 +60,9 @@ internal class SimPduTest { @Test fun testDoubleOutlet() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val pdu = SimPdu(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val pdu = SimPdu(engine) source.connect(pdu) pdu.newOutlet().connect(SimpleInlet()) @@ -73,28 +73,28 @@ internal class SimPduTest { @Test fun testDisconnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val pdu = SimPdu(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val pdu = SimPdu(engine) source.connect(pdu) - val consumer = spyk(SimWorkConsumer(100.0, utilization = 1.0)) + val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): SimResourceConsumer = consumer + override fun createConsumer(): FlowSource = consumer } val outlet = pdu.newOutlet() outlet.connect(inlet) outlet.disconnect() - verify { consumer.onEvent(any(), SimResourceEvent.Exit) } + verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } } @Test fun testLoss() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) // https://download.schneider-electric.com/files?p_Doc_Ref=SPD_NRAN-66CK3D_EN - val pdu = SimPdu(interpreter, idlePower = 1.5, lossCoefficient = 0.015) + val pdu = SimPdu(engine, idlePower = 1.5, lossCoefficient = 0.015) source.connect(pdu) pdu.newOutlet().connect(SimpleInlet()) assertEquals(89.0, source.powerDraw, 0.01) @@ -102,9 +102,9 @@ internal class SimPduTest { @Test fun testOutletClose() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val pdu = SimPdu(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val pdu = SimPdu(engine) source.connect(pdu) val outlet = pdu.newOutlet() outlet.close() @@ -115,6 +115,6 @@ internal class SimPduTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): SimResourceConsumer = SimWorkConsumer(100.0, utilization = 0.5) + override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) } } diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt index f3829ba1..b411e292 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt @@ -31,10 +31,10 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceEvent -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource +import org.opendc.simulator.flow.source.FixedFlowSource /** * Test suite for the [SimPowerSource] @@ -42,8 +42,8 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer internal class SimPowerSourceTest { @Test fun testInitialState() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) assertFalse(source.isConnected) assertNull(source.inlet) @@ -52,8 +52,8 @@ internal class SimPowerSourceTest { @Test fun testDisconnectIdempotent() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) assertDoesNotThrow { source.disconnect() } assertFalse(source.isConnected) @@ -61,8 +61,8 @@ internal class SimPowerSourceTest { @Test fun testConnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) val inlet = SimpleInlet() source.connect(inlet) @@ -76,27 +76,27 @@ internal class SimPowerSourceTest { @Test fun testDisconnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val consumer = spyk(SimWorkConsumer(100.0, utilization = 1.0)) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): SimResourceConsumer = consumer + override fun createConsumer(): FlowSource = consumer } source.connect(inlet) source.disconnect() - verify { consumer.onEvent(any(), SimResourceEvent.Exit) } + verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } } @Test fun testDisconnectAssertion() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) val inlet = mockk(relaxUnitFun = true) every { inlet.isConnected } returns false every { inlet._outlet } returns null - every { inlet.createConsumer() } returns SimWorkConsumer(100.0, utilization = 1.0) + every { inlet.createConsumer() } returns FixedFlowSource(100.0, utilization = 1.0) source.connect(inlet) @@ -107,8 +107,8 @@ internal class SimPowerSourceTest { @Test fun testOutletAlreadyConnected() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) val inlet = SimpleInlet() source.connect(inlet) @@ -121,8 +121,8 @@ internal class SimPowerSourceTest { @Test fun testInletAlreadyConnected() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) val inlet = mockk(relaxUnitFun = true) every { inlet.isConnected } returns true @@ -132,6 +132,6 @@ internal class SimPowerSourceTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): SimResourceConsumer = SimWorkConsumer(100.0, utilization = 1.0) + override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 1.0) } } diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt index 8d5fa857..31ac0b39 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt @@ -28,10 +28,10 @@ import org.junit.jupiter.api.Assertions.assertAll import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceEvent -import org.opendc.simulator.resources.SimResourceInterpreter -import org.opendc.simulator.resources.consumer.SimWorkConsumer +import org.opendc.simulator.flow.FlowEngine +import org.opendc.simulator.flow.FlowEvent +import org.opendc.simulator.flow.FlowSource +import org.opendc.simulator.flow.source.FixedFlowSource /** * Test suite for the [SimUps] class. @@ -39,9 +39,9 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer internal class SimUpsTest { @Test fun testSingleInlet() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) - val ups = SimUps(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) + val ups = SimUps(engine) source.connect(ups.newInlet()) ups.connect(SimpleInlet()) @@ -50,10 +50,10 @@ internal class SimUpsTest { @Test fun testDoubleInlet() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source1 = SimPowerSource(interpreter, capacity = 100.0) - val source2 = SimPowerSource(interpreter, capacity = 100.0) - val ups = SimUps(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source1 = SimPowerSource(engine, capacity = 100.0) + val source2 = SimPowerSource(engine, capacity = 100.0) + val ups = SimUps(engine) source1.connect(ups.newInlet()) source2.connect(ups.newInlet()) @@ -67,10 +67,10 @@ internal class SimUpsTest { @Test fun testLoss() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source = SimPowerSource(interpreter, capacity = 100.0) + val engine = FlowEngine(coroutineContext, clock) + val source = SimPowerSource(engine, capacity = 100.0) // https://download.schneider-electric.com/files?p_Doc_Ref=SPD_NRAN-66CK3D_EN - val ups = SimUps(interpreter, idlePower = 4.0, lossCoefficient = 0.05) + val ups = SimUps(engine, idlePower = 4.0, lossCoefficient = 0.05) source.connect(ups.newInlet()) ups.connect(SimpleInlet()) @@ -79,24 +79,24 @@ internal class SimUpsTest { @Test fun testDisconnect() = runBlockingSimulation { - val interpreter = SimResourceInterpreter(coroutineContext, clock) - val source1 = SimPowerSource(interpreter, capacity = 100.0) - val source2 = SimPowerSource(interpreter, capacity = 100.0) - val ups = SimUps(interpreter) + val engine = FlowEngine(coroutineContext, clock) + val source1 = SimPowerSource(engine, capacity = 100.0) + val source2 = SimPowerSource(engine, capacity = 100.0) + val ups = SimUps(engine) source1.connect(ups.newInlet()) source2.connect(ups.newInlet()) - val consumer = spyk(SimWorkConsumer(100.0, utilization = 1.0)) + val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): SimResourceConsumer = consumer + override fun createConsumer(): FlowSource = consumer } ups.connect(inlet) ups.disconnect() - verify { consumer.onEvent(any(), SimResourceEvent.Exit) } + verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): SimResourceConsumer = SimWorkConsumer(100.0, utilization = 0.5) + override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) } } diff --git a/opendc-simulator/opendc-simulator-resources/build.gradle.kts b/opendc-simulator/opendc-simulator-resources/build.gradle.kts deleted file mode 100644 index 68047d5c..00000000 --- a/opendc-simulator/opendc-simulator-resources/build.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -description = "Uniform resource consumption simulation model" - -plugins { - `kotlin-library-conventions` - `testing-conventions` - `jacoco-conventions` - `benchmark-conventions` -} - -dependencies { - api(platform(projects.opendcPlatform)) - api(libs.kotlinx.coroutines) - implementation(projects.opendcUtils) - - testImplementation(projects.opendcSimulator.opendcSimulatorCore) -} diff --git a/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt b/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt deleted file mode 100644 index fbc3f319..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.launch -import org.opendc.simulator.core.SimulationCoroutineScope -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimTraceConsumer -import org.openjdk.jmh.annotations.* -import java.util.concurrent.ThreadLocalRandom -import java.util.concurrent.TimeUnit - -@State(Scope.Thread) -@Fork(1) -@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) -@OptIn(ExperimentalCoroutinesApi::class) -class SimResourceBenchmarks { - private lateinit var scope: SimulationCoroutineScope - private lateinit var interpreter: SimResourceInterpreter - - @Setup - fun setUp() { - scope = SimulationCoroutineScope() - interpreter = SimResourceInterpreter(scope.coroutineContext, scope.clock) - } - - @State(Scope.Thread) - class Workload { - lateinit var trace: Sequence - - @Setup - fun setUp() { - val random = ThreadLocalRandom.current() - val entries = List(10000) { SimTraceConsumer.Fragment(1000, random.nextDouble(0.0, 4500.0)) } - trace = entries.asSequence() - } - } - - @Benchmark - fun benchmarkSource(state: Workload) { - return scope.runBlockingSimulation { - val provider = SimResourceSource(4200.0, interpreter) - return@runBlockingSimulation provider.consume(SimTraceConsumer(state.trace)) - } - } - - @Benchmark - fun benchmarkForwardOverhead(state: Workload) { - return scope.runBlockingSimulation { - val provider = SimResourceSource(4200.0, interpreter) - val forwarder = SimResourceForwarder() - provider.startConsumer(forwarder) - return@runBlockingSimulation forwarder.consume(SimTraceConsumer(state.trace)) - } - } - - @Benchmark - fun benchmarkSwitchMaxMinSingleConsumer(state: Workload) { - return scope.runBlockingSimulation { - val switch = SimResourceSwitchMaxMin(interpreter) - - switch.addInput(SimResourceSource(3000.0, interpreter)) - switch.addInput(SimResourceSource(3000.0, interpreter)) - - val provider = switch.newOutput() - return@runBlockingSimulation provider.consume(SimTraceConsumer(state.trace)) - } - } - - @Benchmark - fun benchmarkSwitchMaxMinTripleConsumer(state: Workload) { - return scope.runBlockingSimulation { - val switch = SimResourceSwitchMaxMin(interpreter) - - switch.addInput(SimResourceSource(3000.0, interpreter)) - switch.addInput(SimResourceSource(3000.0, interpreter)) - - repeat(3) { - launch { - val provider = switch.newOutput() - provider.consume(SimTraceConsumer(state.trace)) - } - } - } - } - - @Benchmark - fun benchmarkSwitchExclusiveSingleConsumer(state: Workload) { - return scope.runBlockingSimulation { - val switch = SimResourceSwitchExclusive() - - switch.addInput(SimResourceSource(3000.0, interpreter)) - switch.addInput(SimResourceSource(3000.0, interpreter)) - - val provider = switch.newOutput() - return@runBlockingSimulation provider.consume(SimTraceConsumer(state.trace)) - } - } - - @Benchmark - fun benchmarkSwitchExclusiveTripleConsumer(state: Workload) { - return scope.runBlockingSimulation { - val switch = SimResourceSwitchExclusive() - - switch.addInput(SimResourceSource(3000.0, interpreter)) - switch.addInput(SimResourceSource(3000.0, interpreter)) - - repeat(2) { - launch { - val provider = switch.newOutput() - provider.consume(SimTraceConsumer(state.trace)) - } - } - } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt deleted file mode 100644 index 085cba63..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.impl.SimResourceCountersImpl - -/** - * Abstract implementation of the [SimResourceProvider] which can be re-used by other implementations. - */ -public abstract class SimAbstractResourceProvider( - private val interpreter: SimResourceInterpreter, - initialCapacity: Double -) : SimResourceProvider { - /** - * A flag to indicate that the resource provider is active. - */ - public override val isActive: Boolean - get() = ctx != null - - /** - * The capacity of the resource. - */ - public override var capacity: Double = initialCapacity - set(value) { - field = value - ctx?.capacity = value - } - - /** - * The current processing speed of the resource. - */ - public override val speed: Double - get() = ctx?.speed ?: 0.0 - - /** - * The resource processing speed demand at this instant. - */ - public override val demand: Double - get() = ctx?.demand ?: 0.0 - - /** - * The resource counters to track the execution metrics of the resource. - */ - public override val counters: SimResourceCounters - get() = _counters - private val _counters = SimResourceCountersImpl() - - /** - * The [SimResourceControllableContext] that is currently running. - */ - protected var ctx: SimResourceControllableContext? = null - private set - - /** - * Construct the [SimResourceProviderLogic] instance for a new consumer. - */ - protected abstract fun createLogic(): SimResourceProviderLogic - - /** - * Start the specified [SimResourceControllableContext]. - */ - protected open fun start(ctx: SimResourceControllableContext) { - ctx.start() - } - - /** - * The previous demand for the resource. - */ - private var previousDemand = 0.0 - - /** - * Update the counters of the resource provider. - */ - protected fun updateCounters(ctx: SimResourceContext, delta: Long) { - val demand = previousDemand - previousDemand = ctx.demand - - if (delta <= 0) { - return - } - - val counters = _counters - val deltaS = delta / 1000.0 - val work = demand * deltaS - val actualWork = ctx.speed * deltaS - val remainingWork = work - actualWork - - counters.demand += work - counters.actual += actualWork - counters.overcommit += remainingWork - } - - /** - * Update the counters of the resource provider. - */ - protected fun updateCounters(demand: Double, actual: Double, overcommit: Double) { - val counters = _counters - counters.demand += demand - counters.actual += actual - counters.overcommit += overcommit - } - - final override fun startConsumer(consumer: SimResourceConsumer) { - check(ctx == null) { "Resource is in invalid state" } - val ctx = interpreter.newContext(consumer, createLogic()) - - ctx.capacity = capacity - this.ctx = ctx - - start(ctx) - } - - final override fun interrupt() { - ctx?.interrupt() - } - - final override fun cancel() { - val ctx = ctx - if (ctx != null) { - this.ctx = null - ctx.close() - } - } - - override fun toString(): String = "SimAbstractResourceProvider[capacity=$capacity]" -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt deleted file mode 100644 index 0b25358a..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceConsumer.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A [SimResourceConsumer] characterizes how a resource is consumed. - * - * Implementors of this interface should be considered stateful and must be assumed not to be re-usable (concurrently) - * for multiple resource providers, unless explicitly said otherwise. - */ -public interface SimResourceConsumer { - /** - * This method is invoked when the resource provider is pulling this resource consumer. - * - * @param ctx The execution context in which the consumer runs. - * @param now The virtual timestamp in milliseconds at which the update is occurring. - * @param delta The virtual duration between this call and the last call in milliseconds. - * @return The duration after which the resource consumer should be pulled again. - */ - public fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long - - /** - * This method is invoked when an event has occurred. - * - * @param ctx The execution context in which the consumer runs. - * @param event The event that has occurred. - */ - public fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) {} - - /** - * This method is invoked when a resource consumer throws an exception. - * - * @param ctx The execution context in which the consumer runs. - * @param cause The cause of the failure. - */ - public fun onFailure(ctx: SimResourceContext, cause: Throwable) {} -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt deleted file mode 100644 index 225cae0b..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceContext.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import java.time.Clock - -/** - * The execution context in which a [SimResourceConsumer] runs. It facilitates the communication and control between a - * resource and a resource consumer. - */ -public interface SimResourceContext : AutoCloseable { - /** - * The virtual clock tracking simulation time. - */ - public val clock: Clock - - /** - * The resource capacity available at this instant. - */ - public val capacity: Double - - /** - * The resource processing speed at this instant. - */ - public val speed: Double - - /** - * The resource processing speed demand at this instant. - */ - public val demand: Double - - /** - * Ask the resource provider to interrupt its resource. - */ - public fun interrupt() - - /** - * Push the given flow to this context. - * - * @param rate The rate of the flow to push. - */ - public fun push(rate: Double) - - /** - * Stop the resource context. - */ - public override fun close() -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt deleted file mode 100644 index b406b896..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceControllableContext.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A controllable [SimResourceContext]. - * - * This interface is used by resource providers to control the resource context. - */ -public interface SimResourceControllableContext : SimResourceContext { - /** - * The capacity of the resource. - */ - public override var capacity: Double - - /** - * Start the resource context. - */ - public fun start() - - /** - * Invalidate the resource context's state. - * - * By invalidating the resource context's current state, the state is re-computed and the current progress is - * materialized during the next interpreter cycle. As a result, this call run asynchronously. See [flush] for the - * synchronous variant. - */ - public fun invalidate() - - /** - * Synchronously flush the progress of the resource context and materialize its current progress. - */ - public fun flush() -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt deleted file mode 100644 index 11924db2..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCounters.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * An interface that tracks cumulative counts of the work performed by a resource. - */ -public interface SimResourceCounters { - /** - * The amount of work that resource consumers wanted the resource to perform. - */ - public val demand: Double - - /** - * The amount of work performed by the resource. - */ - public val actual: Double - - /** - * The amount of work that could not be completed due to overcommitted resources. - */ - public val overcommit: Double - - /** - * The amount of work lost due to interference. - */ - public val interference: Double - - /** - * Reset the resource counters. - */ - public fun reset() -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceEvent.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceEvent.kt deleted file mode 100644 index 959427f1..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceEvent.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A resource event that is communicated to the resource consumer. - */ -public enum class SimResourceEvent { - /** - * This event is emitted to the consumer when it has started. - */ - Start, - - /** - * This event is emitted to the consumer when it has exited. - */ - Exit, - - /** - * This event is emitted to the consumer when it has started a new resource consumption or idle cycle. - */ - Run, - - /** - * This event is emitted to the consumer when the capacity of the resource has changed. - */ - Capacity, -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt deleted file mode 100644 index 0cd2bfc7..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceForwarder.kt +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.impl.SimResourceCountersImpl -import java.time.Clock - -/** - * A class that acts as a [SimResourceConsumer] and [SimResourceProvider] at the same time. - * - * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. - */ -public class SimResourceForwarder(private val isCoupled: Boolean = false) : SimResourceConsumer, SimResourceProvider, AutoCloseable { - /** - * The delegate [SimResourceConsumer]. - */ - private var delegate: SimResourceConsumer? = null - - /** - * A flag to indicate that the delegate was started. - */ - private var hasDelegateStarted: Boolean = false - - /** - * The exposed [SimResourceContext]. - */ - private val _ctx = object : SimResourceContext { - override val clock: Clock - get() = _innerCtx!!.clock - - override val capacity: Double - get() = _innerCtx?.capacity ?: 0.0 - - override val demand: Double - get() = _innerCtx?.demand ?: 0.0 - - override val speed: Double - get() = _innerCtx?.speed ?: 0.0 - - override fun interrupt() { - _innerCtx?.interrupt() - } - - override fun push(rate: Double) { - _innerCtx?.push(rate) - _limit = rate - } - - override fun close() { - val delegate = checkNotNull(delegate) { "Delegate not active" } - - if (isCoupled) - _innerCtx?.close() - else - _innerCtx?.push(0.0) - - // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we - // reset beforehand the existing state and check whether it has been updated afterwards - reset() - - delegate.onEvent(this, SimResourceEvent.Exit) - } - } - - /** - * The [SimResourceContext] in which the forwarder runs. - */ - private var _innerCtx: SimResourceContext? = null - - override val isActive: Boolean - get() = delegate != null - - override val capacity: Double - get() = _ctx.capacity - - override val speed: Double - get() = _ctx.speed - - override val demand: Double - get() = _ctx.demand - - override val counters: SimResourceCounters - get() = _counters - private val _counters = SimResourceCountersImpl() - - override fun startConsumer(consumer: SimResourceConsumer) { - check(delegate == null) { "Resource transformer already active" } - - delegate = consumer - - // Interrupt the provider to replace the consumer - interrupt() - } - - override fun interrupt() { - _ctx.interrupt() - } - - override fun cancel() { - val delegate = delegate - val ctx = _innerCtx - - if (delegate != null) { - this.delegate = null - - if (ctx != null) { - delegate.onEvent(this._ctx, SimResourceEvent.Exit) - } - } - } - - override fun close() { - val ctx = _innerCtx - - if (ctx != null) { - this._innerCtx = null - ctx.interrupt() - } - } - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val delegate = delegate - - if (!hasDelegateStarted) { - start() - } - - updateCounters(ctx, delta) - - return delegate?.onNext(this._ctx, now, delta) ?: Long.MAX_VALUE - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - _innerCtx = ctx - } - SimResourceEvent.Exit -> { - _innerCtx = null - - val delegate = delegate - if (delegate != null) { - reset() - delegate.onEvent(this._ctx, SimResourceEvent.Exit) - } - } - else -> delegate?.onEvent(this._ctx, event) - } - } - - override fun onFailure(ctx: SimResourceContext, cause: Throwable) { - _innerCtx = null - - val delegate = delegate - if (delegate != null) { - reset() - delegate.onFailure(this._ctx, cause) - } - } - - /** - * Start the delegate. - */ - private fun start() { - val delegate = delegate ?: return - delegate.onEvent(checkNotNull(_innerCtx), SimResourceEvent.Start) - - hasDelegateStarted = true - } - - /** - * Reset the delegate. - */ - private fun reset() { - delegate = null - hasDelegateStarted = false - } - - /** - * The requested speed. - */ - private var _limit: Double = 0.0 - - /** - * Update the resource counters for the transformer. - */ - private fun updateCounters(ctx: SimResourceContext, delta: Long) { - if (delta <= 0) { - return - } - - val counters = _counters - val deltaS = delta / 1000.0 - val work = _limit * deltaS - val actualWork = ctx.speed * deltaS - counters.demand += work - counters.actual += actualWork - counters.overcommit += (work - actualWork) - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt deleted file mode 100644 index 4bfeaf20..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceInterpreter.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl -import java.time.Clock -import kotlin.coroutines.CoroutineContext - -/** - * The resource interpreter is responsible for managing the interaction between resource consumer and provider. - * - * The interpreter centralizes the scheduling logic of state updates of resource context, allowing update propagation - * to happen more efficiently. and overall, reducing the work necessary to transition into a steady state. - */ -public interface SimResourceInterpreter { - /** - * The [Clock] associated with this interpreter. - */ - public val clock: Clock - - /** - * Create a new [SimResourceControllableContext] with the given [provider]. - * - * @param consumer The consumer logic. - * @param provider The logic of the resource provider. - */ - public fun newContext(consumer: SimResourceConsumer, provider: SimResourceProviderLogic): SimResourceControllableContext - - /** - * Start batching the execution of resource updates until [popBatch] is called. - * - * This method is useful if you want to propagate multiple resources updates (e.g., starting multiple CPUs - * simultaneously) in a single state update. - * - * Multiple calls to this method requires the same number of [popBatch] calls in order to properly flush the - * resource updates. This allows nested calls to [pushBatch], but might cause issues if [popBatch] is not called - * the same amount of times. To simplify batching, see [batch]. - */ - public fun pushBatch() - - /** - * Stop the batching of resource updates and run the interpreter on the batch. - * - * Note that method will only flush the event once the first call to [pushBatch] has received a [popBatch] call. - */ - public fun popBatch() - - public companion object { - /** - * Construct a new [SimResourceInterpreter] implementation. - * - * @param context The coroutine context to use. - * @param clock The virtual simulation clock. - */ - @JvmName("create") - public operator fun invoke(context: CoroutineContext, clock: Clock): SimResourceInterpreter { - return SimResourceInterpreterImpl(context, clock) - } - } -} - -/** - * Batch the execution of several interrupts into a single call. - * - * This method is useful if you want to propagate the start of multiple resources (e.g., CPUs) in a single update. - */ -public inline fun SimResourceInterpreter.batch(block: () -> Unit) { - try { - pushBatch() - block() - } finally { - popBatch() - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt deleted file mode 100644 index b68b7261..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException - -/** - * A [SimResourceProvider] provides a resource that can be consumed by a [SimResourceConsumer]. - */ -public interface SimResourceProvider { - /** - * A flag to indicate that the resource provider is currently being consumed by a [SimResourceConsumer]. - */ - public val isActive: Boolean - - /** - * The resource capacity available at this instant. - */ - public val capacity: Double - - /** - * The current processing speed of the resource. - */ - public val speed: Double - - /** - * The resource processing speed demand at this instant. - */ - public val demand: Double - - /** - * The resource counters to track the execution metrics of the resource. - */ - public val counters: SimResourceCounters - - /** - * Start the specified [resource consumer][consumer] in the context of this resource provider asynchronously. - * - * @throws IllegalStateException if there is already a consumer active or the resource lifetime has ended. - */ - public fun startConsumer(consumer: SimResourceConsumer) - - /** - * Interrupt the resource consumer. If there is no consumer active, this operation will be a no-op. - */ - public fun interrupt() - - /** - * Cancel the current resource consumer. If there is no consumer active, this operation will be a no-op. - */ - public fun cancel() -} - -/** - * Consume the resource provided by this provider using the specified [consumer] and suspend execution until - * the consumer has finished. - */ -public suspend fun SimResourceProvider.consume(consumer: SimResourceConsumer) { - return suspendCancellableCoroutine { cont -> - startConsumer(object : SimResourceConsumer by consumer { - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - consumer.onEvent(ctx, event) - - if (event == SimResourceEvent.Exit && !cont.isCompleted) { - cont.resume(Unit) - } - } - - override fun onFailure(ctx: SimResourceContext, cause: Throwable) { - try { - consumer.onFailure(ctx, cause) - cont.resumeWithException(cause) - } catch (e: Throwable) { - e.addSuppressed(cause) - cont.resumeWithException(e) - } - } - - override fun toString(): String = "SimSuspendingResourceConsumer" - }) - - cont.invokeOnCancellation { cancel() } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt deleted file mode 100644 index cc718165..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProviderLogic.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A collection of callbacks associated with a flow stage. - */ -public interface SimResourceProviderLogic { - /** - * This method is invoked when the consumer ask to consume the resource for the specified [duration]. - * - * @param ctx The context in which the provider runs. - * @param now The virtual timestamp in milliseconds at which the update is occurring. - * @param delta The virtual duration between this call and the last call to [onConsume] in milliseconds. - * @param limit The limit on the work rate of the resource consumer. - * @param duration The duration of the consumption in milliseconds. - * @return The deadline of the resource consumption. - */ - public fun onConsume(ctx: SimResourceControllableContext, now: Long, delta: Long, limit: Double, duration: Long) {} - - /** - * This method is invoked when the flow graph has converged into a steady-state system. - * - * @param ctx The context in which the provider runs. - * @param now The virtual timestamp in milliseconds at which the system converged. - * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. - */ - public fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) {} - - /** - * This method is invoked when the resource consumer has finished. - * - * @param ctx The context in which the provider runs. - * @param now The virtual timestamp in milliseconds at which the provider finished. - * @param delta The virtual duration between this call and the last call to [onConsume] in milliseconds. - */ - public fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) {} -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt deleted file mode 100644 index c8d4cf0d..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSource.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A [SimResourceSource] represents a source for some resource that provides bounded processing capacity. - * - * @param initialCapacity The initial capacity of the resource. - * @param interpreter The interpreter that is used for managing the resource contexts. - * @param parent The parent resource system. - */ -public class SimResourceSource( - initialCapacity: Double, - private val interpreter: SimResourceInterpreter, - private val parent: SimResourceSystem? = null -) : SimAbstractResourceProvider(interpreter, initialCapacity) { - override fun createLogic(): SimResourceProviderLogic { - return object : SimResourceProviderLogic { - override fun onConsume( - ctx: SimResourceControllableContext, - now: Long, - delta: Long, - limit: Double, - duration: Long - ) { - updateCounters(ctx, delta) - } - - override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { - updateCounters(ctx, delta) - cancel() - } - - override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { - parent?.onConverge(now) - } - } - } - - override fun toString(): String = "SimResourceSource[capacity=$capacity]" -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt deleted file mode 100644 index 3c25b76d..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.interference.InterferenceKey - -/** - * A [SimResourceSwitch] enables switching of capacity of multiple resources between multiple consumers. - */ -public interface SimResourceSwitch { - /** - * The output resource providers to which resource consumers can be attached. - */ - public val outputs: Set - - /** - * The input resources that will be switched between the output providers. - */ - public val inputs: Set - - /** - * The resource counters to track the execution metrics of all switch resources. - */ - public val counters: SimResourceCounters - - /** - * Create a new output on the switch. - * - * @param key The key of the interference member to which the output belongs. - */ - public fun newOutput(key: InterferenceKey? = null): SimResourceProvider - - /** - * Remove [output] from this switch. - */ - public fun removeOutput(output: SimResourceProvider) - - /** - * Add the specified [input] to the switch. - */ - public fun addInput(input: SimResourceProvider) - - /** - * Clear all inputs and outputs from the switch. - */ - public fun clear() -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt deleted file mode 100644 index f1e004d2..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.interference.InterferenceKey -import java.util.ArrayDeque - -/** - * A [SimResourceSwitch] implementation that allocates outputs to the inputs of the switch exclusively. This means that - * a single output is directly connected to an input and that the switch can only support as many outputs as inputs. - */ -public class SimResourceSwitchExclusive : SimResourceSwitch { - override val outputs: Set - get() = _outputs - private val _outputs = mutableSetOf() - - private val _inputs = mutableSetOf() - override val inputs: Set - get() = _inputs - private val _availableInputs = ArrayDeque() - - override val counters: SimResourceCounters = object : SimResourceCounters { - override val demand: Double - get() = _inputs.sumOf { it.counters.demand } - override val actual: Double - get() = _inputs.sumOf { it.counters.actual } - override val overcommit: Double - get() = _inputs.sumOf { it.counters.overcommit } - override val interference: Double - get() = _inputs.sumOf { it.counters.interference } - - override fun reset() { - for (input in _inputs) { - input.counters.reset() - } - } - - override fun toString(): String = "SimResourceCounters[demand=$demand,actual=$actual,overcommit=$overcommit]" - } - - /** - * Add an output to the switch. - */ - override fun newOutput(key: InterferenceKey?): SimResourceProvider { - val forwarder = checkNotNull(_availableInputs.poll()) { "No capacity to serve request" } - val output = Output(forwarder) - _outputs += output - return output - } - - override fun removeOutput(output: SimResourceProvider) { - if (!_outputs.remove(output)) { - return - } - - (output as Output).close() - } - - /** - * Add an input to the switch. - */ - override fun addInput(input: SimResourceProvider) { - if (input in inputs) { - return - } - - val forwarder = SimResourceForwarder() - - _inputs += input - _availableInputs += forwarder - - input.startConsumer(object : SimResourceConsumer by forwarder { - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - if (event == SimResourceEvent.Exit) { - // De-register the input after it has finished - _inputs -= input - } - - forwarder.onEvent(ctx, event) - } - }) - } - - override fun clear() { - for (input in _inputs) { - input.cancel() - } - _inputs.clear() - - // Outputs are implicitly cancelled by the inputs forwarders - _outputs.clear() - } - - /** - * An output of the resource switch. - */ - private inner class Output(private val forwarder: SimResourceForwarder) : SimResourceProvider by forwarder { - /** - * Close the output. - */ - fun close() { - // We explicitly do not close the forwarder here in order to re-use it across output resources. - _outputs -= this - _availableInputs += forwarder - } - - override fun toString(): String = "SimResourceSwitchExclusive.Output" - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt deleted file mode 100644 index 574fb443..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.opendc.simulator.resources.impl.SimResourceCountersImpl -import org.opendc.simulator.resources.interference.InterferenceDomain -import org.opendc.simulator.resources.interference.InterferenceKey -import kotlin.math.max -import kotlin.math.min - -/** - * A [SimResourceSwitch] implementation that switches resource consumptions over the available resources using max-min - * fair sharing. - * - * @param interpreter The interpreter for managing the resource contexts. - * @param parent The parent resource system of the switch. - * @param interferenceDomain The interference domain of the switch. - */ -public class SimResourceSwitchMaxMin( - private val interpreter: SimResourceInterpreter, - private val parent: SimResourceSystem? = null, - private val interferenceDomain: InterferenceDomain? = null -) : SimResourceSwitch { - /** - * The output resource providers to which resource consumers can be attached. - */ - override val outputs: Set - get() = _outputs - private val _outputs = mutableSetOf() - private val _activeOutputs: MutableList = mutableListOf() - - /** - * The input resources that will be switched between the output providers. - */ - override val inputs: Set - get() = _inputs - private val _inputs = mutableSetOf() - private val _activeInputs = mutableListOf() - - /** - * The resource counters of this switch. - */ - public override val counters: SimResourceCounters - get() = _counters - private val _counters = SimResourceCountersImpl() - - /** - * The actual processing rate of the switch. - */ - private var _rate = 0.0 - - /** - * The demanded processing rate of the outputs. - */ - private var _demand = 0.0 - - /** - * The capacity of the switch. - */ - private var _capacity = 0.0 - - /** - * Flag to indicate that the scheduler is active. - */ - private var _schedulerActive = false - - /** - * Add an output to the switch. - */ - override fun newOutput(key: InterferenceKey?): SimResourceProvider { - val provider = Output(_capacity, key) - _outputs.add(provider) - return provider - } - - /** - * Add the specified [input] to the switch. - */ - override fun addInput(input: SimResourceProvider) { - val consumer = Input(input) - if (_inputs.add(input)) { - _activeInputs.add(consumer) - input.startConsumer(consumer) - } - } - - /** - * Remove [output] from this switch. - */ - override fun removeOutput(output: SimResourceProvider) { - if (!_outputs.remove(output)) { - return - } - // This cast should always succeed since only `Output` instances should be added to _outputs - (output as Output).close() - } - - override fun clear() { - for (input in _activeInputs) { - input.cancel() - } - _activeInputs.clear() - - for (output in _activeOutputs) { - output.cancel() - } - _activeOutputs.clear() - } - - /** - * Run the scheduler of the switch. - */ - private fun runScheduler(now: Long) { - if (_schedulerActive) { - return - } - - _schedulerActive = true - try { - doSchedule(now) - } finally { - _schedulerActive = false - } - } - - /** - * Schedule the outputs over the input. - */ - private fun doSchedule(now: Long) { - // If there is no work yet, mark the input as idle. - if (_activeOutputs.isEmpty()) { - return - } - - val capacity = _capacity - var availableCapacity = capacity - - // Pull in the work of the outputs - val outputIterator = _activeOutputs.listIterator() - for (output in outputIterator) { - output.pull(now) - - // Remove outputs that have finished - if (!output.isActive) { - outputIterator.remove() - } - } - - var demand = 0.0 - - // Sort in-place the outputs based on their requested usage. - // Profiling shows that it is faster than maintaining some kind of sorted set. - _activeOutputs.sort() - - // Divide the available input capacity fairly across the outputs using max-min fair sharing - var remaining = _activeOutputs.size - for (output in _activeOutputs) { - val availableShare = availableCapacity / remaining-- - val grantedSpeed = min(output.allowedRate, availableShare) - - // Ignore idle computation - if (grantedSpeed <= 0.0) { - output.actualRate = 0.0 - continue - } - - demand += output.limit - - output.actualRate = grantedSpeed - availableCapacity -= grantedSpeed - } - - val rate = capacity - availableCapacity - - _demand = demand - _rate = rate - - // Sort all consumers by their capacity - _activeInputs.sort() - - // Divide the requests over the available capacity of the input resources fairly - for (input in _activeInputs) { - val inputCapacity = input.capacity - val fraction = inputCapacity / capacity - val grantedSpeed = rate * fraction - - input.push(grantedSpeed) - } - } - - /** - * Recompute the capacity of the switch. - */ - private fun updateCapacity() { - val newCapacity = _activeInputs.sumOf(Input::capacity) - - // No-op if the capacity is unchanged - if (_capacity == newCapacity) { - return - } - - _capacity = newCapacity - - for (output in _outputs) { - output.capacity = newCapacity - } - } - - /** - * An internal [SimResourceProvider] implementation for switch outputs. - */ - private inner class Output(capacity: Double, val key: InterferenceKey?) : - SimAbstractResourceProvider(interpreter, capacity), - SimResourceProviderLogic, - Comparable { - /** - * The requested limit. - */ - @JvmField var limit: Double = 0.0 - - /** - * The actual processing speed. - */ - @JvmField var actualRate: Double = 0.0 - - /** - * The processing speed that is allowed by the model constraints. - */ - val allowedRate: Double - get() = min(capacity, limit) - - /** - * A flag to indicate that the output is closed. - */ - private var _isClosed: Boolean = false - - /** - * The timestamp at which we received the last command. - */ - private var _lastPull: Long = Long.MIN_VALUE - - /** - * Close the output. - * - * This method is invoked when the user removes an output from the switch. - */ - fun close() { - _isClosed = true - cancel() - } - - /* SimAbstractResourceProvider */ - override fun createLogic(): SimResourceProviderLogic = this - - override fun start(ctx: SimResourceControllableContext) { - check(!_isClosed) { "Cannot re-use closed output" } - - _activeOutputs += this - super.start(ctx) - } - - /* SimResourceProviderLogic */ - override fun onConsume( - ctx: SimResourceControllableContext, - now: Long, - delta: Long, - limit: Double, - duration: Long - ) { - doUpdateCounters(delta) - - actualRate = 0.0 - this.limit = limit - _lastPull = now - - runScheduler(now) - } - - override fun onConverge(ctx: SimResourceControllableContext, now: Long, delta: Long) { - parent?.onConverge(now) - } - - override fun onFinish(ctx: SimResourceControllableContext, now: Long, delta: Long) { - doUpdateCounters(delta) - - limit = 0.0 - actualRate = 0.0 - _lastPull = now - } - - /* Comparable */ - override fun compareTo(other: Output): Int = allowedRate.compareTo(other.allowedRate) - - /** - * Pull the next command if necessary. - */ - fun pull(now: Long) { - val ctx = ctx - if (ctx != null && _lastPull < now) { - ctx.flush() - } - } - - /** - * Helper method to update the resource counters of the distributor. - */ - private fun doUpdateCounters(delta: Long) { - if (delta <= 0L) { - return - } - - // Compute the performance penalty due to resource interference - val perfScore = if (interferenceDomain != null) { - val load = _rate / capacity - interferenceDomain.apply(key, load) - } else { - 1.0 - } - - val deltaS = delta / 1000.0 - val work = limit * deltaS - val actualWork = actualRate * deltaS - val remainingWork = work - actualWork - - updateCounters(work, actualWork, remainingWork) - - val distCounters = _counters - distCounters.demand += work - distCounters.actual += actualWork - distCounters.overcommit += remainingWork - distCounters.interference += actualWork * max(0.0, 1 - perfScore) - } - } - - /** - * An internal [SimResourceConsumer] implementation for switch inputs. - */ - private inner class Input(private val provider: SimResourceProvider) : SimResourceConsumer, Comparable { - /** - * The active [SimResourceContext] of this consumer. - */ - private var _ctx: SimResourceContext? = null - - /** - * The capacity of this input. - */ - val capacity: Double - get() = _ctx?.capacity ?: 0.0 - - /** - * Push the specified rate to the provider. - */ - fun push(rate: Double) { - _ctx?.push(rate) - } - - /** - * Cancel this input. - */ - fun cancel() { - provider.cancel() - } - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - runScheduler(now) - return Long.MAX_VALUE - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - assert(_ctx == null) { "Consumer running concurrently" } - _ctx = ctx - updateCapacity() - } - SimResourceEvent.Exit -> { - _ctx = null - updateCapacity() - } - SimResourceEvent.Capacity -> updateCapacity() - else -> {} - } - } - - override fun compareTo(other: Input): Int = capacity.compareTo(other.capacity) - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSystem.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSystem.kt deleted file mode 100644 index 609262cb..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSystem.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -/** - * A system of possible multiple sub-resources. - * - * This interface is used to model hierarchies of resource providers, which can listen efficiently to changes of the - * resource provider. - */ -public interface SimResourceSystem { - /** - * The parent system to which this system belongs or `null` if it has no parent. - */ - public val parent: SimResourceSystem? - - /** - * This method is invoked when the system has converged to a steady-state. - * - * @param timestamp The timestamp at which the system converged. - */ - public fun onConverge(timestamp: Long) -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimConsumerBarrier.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimConsumerBarrier.kt deleted file mode 100644 index 52a42241..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimConsumerBarrier.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.consumer - -/** - * The [SimConsumerBarrier] is a barrier that allows consumers to wait for a select number of other consumers to - * complete, before proceeding its operation. - */ -public class SimConsumerBarrier(public val parties: Int) { - private var counter = 0 - - /** - * Enter the barrier and determine whether the caller is the last to reach the barrier. - * - * @return `true` if the caller is the last to reach the barrier, `false` otherwise. - */ - public fun enter(): Boolean { - val last = ++counter == parties - if (last) { - counter = 0 - return true - } - return false - } - - /** - * Reset the barrier. - */ - public fun reset() { - counter = 0 - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt deleted file mode 100644 index 46885640..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimSpeedConsumerAdapter.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.consumer - -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceContext -import org.opendc.simulator.resources.SimResourceEvent -import kotlin.math.min - -/** - * Helper class to expose an observable [speed] field describing the speed of the consumer. - */ -public class SimSpeedConsumerAdapter( - private val delegate: SimResourceConsumer, - private val callback: (Double) -> Unit = {} -) : SimResourceConsumer by delegate { - /** - * The resource processing speed at this instant. - */ - public var speed: Double = 0.0 - private set(value) { - if (field != value) { - callback(value) - field = value - } - } - - init { - callback(0.0) - } - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return delegate.onNext(ctx, now, delta) - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - val oldSpeed = speed - - delegate.onEvent(ctx, event) - - when (event) { - SimResourceEvent.Run -> speed = ctx.speed - SimResourceEvent.Capacity -> { - // Check if the consumer interrupted the consumer and updated the resource consumption. If not, we might - // need to update the current speed. - if (oldSpeed == speed) { - speed = min(ctx.capacity, speed) - } - } - SimResourceEvent.Exit -> speed = 0.0 - else -> {} - } - } - - override fun onFailure(ctx: SimResourceContext, cause: Throwable) { - speed = 0.0 - - delegate.onFailure(ctx, cause) - } - - override fun toString(): String = "SimSpeedConsumerAdapter[delegate=$delegate]" -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt deleted file mode 100644 index 4c0e075c..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimTraceConsumer.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.consumer - -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceContext -import org.opendc.simulator.resources.SimResourceEvent - -/** - * A [SimResourceConsumer] that replays a workload trace consisting of multiple fragments, each indicating the resource - * consumption for some period of time. - */ -public class SimTraceConsumer(private val trace: Sequence) : SimResourceConsumer { - private var _iterator: Iterator? = null - private var _nextTarget = Long.MIN_VALUE - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - // Check whether the trace fragment was fully consumed, otherwise wait until we have done so - val nextTarget = _nextTarget - if (nextTarget > now) { - return now - nextTarget - } - - val iterator = checkNotNull(_iterator) - return if (iterator.hasNext()) { - val fragment = iterator.next() - _nextTarget = now + fragment.duration - ctx.push(fragment.usage) - fragment.duration - } else { - ctx.close() - Long.MAX_VALUE - } - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> { - check(_iterator == null) { "Consumer already running" } - _iterator = trace.iterator() - } - SimResourceEvent.Exit -> { - _iterator = null - } - else -> {} - } - } - - /** - * A fragment of the workload. - */ - public data class Fragment(val duration: Long, val usage: Double) -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt deleted file mode 100644 index bf76711f..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/consumer/SimWorkConsumer.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.consumer - -import org.opendc.simulator.resources.SimResourceConsumer -import org.opendc.simulator.resources.SimResourceContext -import kotlin.math.roundToLong - -/** - * A [SimResourceConsumer] that consumes the specified amount of work at the specified utilization. - */ -public class SimWorkConsumer( - private val work: Double, - private val utilization: Double -) : SimResourceConsumer { - - init { - require(work >= 0.0) { "Work must be positive" } - require(utilization > 0.0) { "Utilization must be positive" } - } - - private var remainingWork = work - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - val actualWork = ctx.speed * delta / 1000.0 - val limit = ctx.capacity * utilization - - remainingWork -= actualWork - - val remainingWork = remainingWork - val duration = (remainingWork / limit * 1000).roundToLong() - - return if (duration > 0) { - ctx.push(limit) - duration - } else { - ctx.close() - Long.MAX_VALUE - } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt deleted file mode 100644 index cbfa7afd..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.impl - -import org.opendc.simulator.resources.* -import java.time.Clock -import java.util.ArrayDeque -import kotlin.math.max -import kotlin.math.min - -/** - * Implementation of a [SimResourceContext] managing the communication between resources and resource consumers. - */ -internal class SimResourceContextImpl( - private val interpreter: SimResourceInterpreterImpl, - private val consumer: SimResourceConsumer, - private val logic: SimResourceProviderLogic -) : SimResourceControllableContext { - /** - * The clock of the context. - */ - override val clock: Clock - get() = _clock - private val _clock = interpreter.clock - - /** - * The capacity of the resource. - */ - override var capacity: Double = 0.0 - set(value) { - val oldValue = field - - // Only changes will be propagated - if (value != oldValue) { - field = value - onCapacityChange() - } - } - - /** - * A flag to indicate the state of the context. - */ - private var _state = State.Pending - - /** - * The current processing speed of the resource. - */ - override val speed: Double - get() = _rate - private var _rate = 0.0 - - /** - * The current resource processing demand. - */ - override val demand: Double - get() = _limit - - /** - * The current state of the resource context. - */ - private var _limit: Double = 0.0 - private var _activeLimit: Double = 0.0 - private var _deadline: Long = Long.MIN_VALUE - - /** - * A flag to indicate that an update is active. - */ - private var _updateActive = false - - /** - * The update flag indicating why the update was triggered. - */ - private var _flag: Int = 0 - - /** - * The timestamp of calls to the callbacks. - */ - private var _lastUpdate: Long = Long.MIN_VALUE - private var _lastConvergence: Long = Long.MAX_VALUE - - /** - * The timers at which the context is scheduled to be interrupted. - */ - private val _timers: ArrayDeque = ArrayDeque() - - override fun start() { - check(_state == State.Pending) { "Consumer is already started" } - interpreter.batch { - consumer.onEvent(this, SimResourceEvent.Start) - _state = State.Active - interrupt() - } - } - - override fun close() { - if (_state == State.Stopped) { - return - } - - interpreter.batch { - _state = State.Stopped - if (!_updateActive) { - val now = clock.millis() - val delta = max(0, now - _lastUpdate) - doStop(now, delta) - - // FIX: Make sure the context converges - _flag = _flag or FLAG_INVALIDATE - scheduleUpdate(clock.millis()) - } - } - } - - override fun interrupt() { - if (_state == State.Stopped) { - return - } - - _flag = _flag or FLAG_INTERRUPT - scheduleUpdate(clock.millis()) - } - - override fun invalidate() { - if (_state == State.Stopped) { - return - } - - _flag = _flag or FLAG_INVALIDATE - scheduleUpdate(clock.millis()) - } - - override fun flush() { - if (_state == State.Stopped) { - return - } - - interpreter.scheduleSync(clock.millis(), this) - } - - override fun push(rate: Double) { - if (_limit == rate) { - return - } - - _limit = rate - - // Invalidate only if the active limit is change and no update is active - // If an update is active, it will already get picked up at the end of the update - if (_activeLimit != rate && !_updateActive) { - invalidate() - } - } - - /** - * Determine whether the state of the resource context should be updated. - */ - fun shouldUpdate(timestamp: Long): Boolean { - // Either the resource context is flagged or there is a pending update at this timestamp - return _flag != 0 || _limit != _activeLimit || _deadline == timestamp - } - - /** - * Update the state of the resource context. - */ - fun doUpdate(now: Long) { - val oldState = _state - if (oldState != State.Active) { - return - } - - val lastUpdate = _lastUpdate - - _lastUpdate = now - _updateActive = true - - val delta = max(0, now - lastUpdate) - - try { - val duration = consumer.onNext(this, now, delta) - val newDeadline = if (duration != Long.MAX_VALUE) now + duration else duration - - // Reset update flags - _flag = 0 - - // Check whether the state has changed after [consumer.onNext] - when (_state) { - State.Active -> { - logic.onConsume(this, now, delta, _limit, duration) - - // Schedule an update at the new deadline - scheduleUpdate(now, newDeadline) - } - State.Stopped -> doStop(now, delta) - State.Pending -> throw IllegalStateException("Illegal transition to pending state") - } - - // Note: pending limit might be changed by [logic.onConsume], so re-fetch the value - val newLimit = _limit - - // Flush the changes to the flow - _activeLimit = newLimit - _deadline = newDeadline - _rate = min(capacity, newLimit) - } catch (cause: Throwable) { - doFail(now, delta, cause) - } finally { - _updateActive = false - } - } - - /** - * Prune the elapsed timers from this context. - */ - fun pruneTimers(now: Long) { - val timers = _timers - while (true) { - val head = timers.peek() - if (head == null || head.target > now) { - break - } - timers.poll() - } - } - - /** - * Try to re-schedule the resource context in case it was skipped. - */ - fun tryReschedule(now: Long) { - val deadline = _deadline - if (deadline > now && deadline != Long.MAX_VALUE) { - scheduleUpdate(now, deadline) - } - } - - /** - * This method is invoked when the system converges into a steady state. - */ - fun onConverge(timestamp: Long) { - val delta = max(0, timestamp - _lastConvergence) - _lastConvergence = timestamp - - try { - if (_state == State.Active) { - consumer.onEvent(this, SimResourceEvent.Run) - } - - logic.onConverge(this, timestamp, delta) - } catch (cause: Throwable) { - doFail(timestamp, max(0, timestamp - _lastUpdate), cause) - } - } - - override fun toString(): String = "SimResourceContextImpl[capacity=$capacity,rate=$_rate]" - - /** - * Stop the resource context. - */ - private fun doStop(now: Long, delta: Long) { - try { - consumer.onEvent(this, SimResourceEvent.Exit) - logic.onFinish(this, now, delta) - } catch (cause: Throwable) { - doFail(now, delta, cause) - } finally { - _deadline = Long.MAX_VALUE - _limit = 0.0 - } - } - - /** - * Fail the resource consumer. - */ - private fun doFail(now: Long, delta: Long, cause: Throwable) { - try { - consumer.onFailure(this, cause) - } catch (e: Throwable) { - e.addSuppressed(cause) - e.printStackTrace() - } - - logic.onFinish(this, now, delta) - } - - /** - * Indicate that the capacity of the resource has changed. - */ - private fun onCapacityChange() { - // Do not inform the consumer if it has not been started yet - if (_state != State.Active) { - return - } - - interpreter.batch { - // Inform the consumer of the capacity change. This might already trigger an interrupt. - consumer.onEvent(this, SimResourceEvent.Capacity) - - interrupt() - } - } - - /** - * Schedule an update for this resource context. - */ - private fun scheduleUpdate(now: Long) { - interpreter.scheduleImmediate(now, this) - } - - /** - * Schedule a delayed update for this resource context. - */ - private fun scheduleUpdate(now: Long, target: Long) { - val timers = _timers - if (target != Long.MAX_VALUE && (timers.isEmpty() || target < timers.peek().target)) { - timers.addFirst(interpreter.scheduleDelayed(now, this, target)) - } - } - - /** - * The state of a resource context. - */ - private enum class State { - /** - * The resource context is pending and the resource is waiting to be consumed. - */ - Pending, - - /** - * The resource context is active and the resource is currently being consumed. - */ - Active, - - /** - * The resource context is stopped and the resource cannot be consumed anymore. - */ - Stopped - } - - /** - * A flag to indicate that the context should be invalidated. - */ - private val FLAG_INVALIDATE = 0b01 - - /** - * A flag to indicate that the context should be interrupted. - */ - private val FLAG_INTERRUPT = 0b10 -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt deleted file mode 100644 index 01062179..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceCountersImpl.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.impl - -import org.opendc.simulator.resources.SimResourceCounters - -/** - * Mutable implementation of the [SimResourceCounters] interface. - */ -internal class SimResourceCountersImpl : SimResourceCounters { - override var demand: Double = 0.0 - override var actual: Double = 0.0 - override var overcommit: Double = 0.0 - override var interference: Double = 0.0 - - override fun reset() { - demand = 0.0 - actual = 0.0 - overcommit = 0.0 - interference = 0.0 - } - - override fun toString(): String { - return "SimResourceCounters[demand=$demand,actual=$actual,overcommit=$overcommit,interference=$interference]" - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt deleted file mode 100644 index 2abf0749..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceInterpreterImpl.kt +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.impl - -import kotlinx.coroutines.Delay -import kotlinx.coroutines.DisposableHandle -import kotlinx.coroutines.InternalCoroutinesApi -import kotlinx.coroutines.Runnable -import org.opendc.simulator.resources.* -import java.time.Clock -import java.util.* -import kotlin.coroutines.ContinuationInterceptor -import kotlin.coroutines.CoroutineContext - -/** - * A [SimResourceInterpreter] queues all interrupts that occur during execution to be executed after. - * - * @param context The coroutine context to use. - * @param clock The virtual simulation clock. - */ -internal class SimResourceInterpreterImpl(private val context: CoroutineContext, override val clock: Clock) : SimResourceInterpreter { - /** - * The [Delay] instance that provides scheduled execution of [Runnable]s. - */ - @OptIn(InternalCoroutinesApi::class) - private val delay = requireNotNull(context[ContinuationInterceptor] as? Delay) { "Invalid CoroutineDispatcher: no delay implementation" } - - /** - * The queue of resource updates that are scheduled for immediate execution. - */ - private val queue = ArrayDeque() - - /** - * A priority queue containing the resource updates to be scheduled in the future. - */ - private val futureQueue = PriorityQueue() - - /** - * The stack of interpreter invocations to occur in the future. - */ - private val futureInvocations = ArrayDeque() - - /** - * The systems that have been visited during the interpreter cycle. - */ - private val visited = linkedSetOf() - - /** - * The index in the batch stack. - */ - private var batchIndex = 0 - - /** - * A flag to indicate that the interpreter is currently active. - */ - private val isRunning: Boolean - get() = batchIndex > 0 - - /** - * Update the specified [ctx] synchronously. - */ - fun scheduleSync(now: Long, ctx: SimResourceContextImpl) { - ctx.doUpdate(now) - visited.add(ctx) - - // In-case the interpreter is already running in the call-stack, return immediately. The changes will be picked - // up by the active interpreter. - if (isRunning) { - return - } - - try { - batchIndex++ - runInterpreter(now) - } finally { - batchIndex-- - } - } - - /** - * Enqueue the specified [ctx] to be updated immediately during the active interpreter cycle. - * - * This method should be used when the state of a resource context is invalidated/interrupted and needs to be - * re-computed. In case no interpreter is currently active, the interpreter will be started. - */ - fun scheduleImmediate(now: Long, ctx: SimResourceContextImpl) { - queue.add(ctx) - - // In-case the interpreter is already running in the call-stack, return immediately. The changes will be picked - // up by the active interpreter. - if (isRunning) { - return - } - - try { - batchIndex++ - runInterpreter(now) - } finally { - batchIndex-- - } - } - - /** - * Schedule the interpreter to run at [target] to update the resource contexts. - * - * This method will override earlier calls to this method for the same [ctx]. - * - * @param now The current virtual timestamp. - * @param ctx The resource context to which the event applies. - * @param target The timestamp when the interrupt should happen. - */ - fun scheduleDelayed(now: Long, ctx: SimResourceContextImpl, target: Long): Timer { - val futureQueue = futureQueue - - require(target >= now) { "Timestamp must be in the future" } - - val timer = Timer(ctx, target) - futureQueue.add(timer) - - return timer - } - - override fun newContext(consumer: SimResourceConsumer, provider: SimResourceProviderLogic): SimResourceControllableContext = SimResourceContextImpl(this, consumer, provider) - - override fun pushBatch() { - batchIndex++ - } - - override fun popBatch() { - try { - // Flush the work if the platform is not already running - if (batchIndex == 1 && queue.isNotEmpty()) { - runInterpreter(clock.millis()) - } - } finally { - batchIndex-- - } - } - - /** - * Interpret all actions that are scheduled for the current timestamp. - */ - private fun runInterpreter(now: Long) { - val queue = queue - val futureQueue = futureQueue - val futureInvocations = futureInvocations - val visited = visited - - // Remove any entries in the `futureInvocations` queue from the past - while (true) { - val head = futureInvocations.peek() - if (head == null || head.timestamp > now) { - break - } - futureInvocations.poll() - } - - // Execute all scheduled updates at current timestamp - while (true) { - val timer = futureQueue.peek() ?: break - val ctx = timer.ctx - val target = timer.target - - assert(target >= now) { "Internal inconsistency: found update of the past" } - - if (target > now) { - break - } - - futureQueue.poll() - - ctx.pruneTimers(now) - - if (ctx.shouldUpdate(now)) { - ctx.doUpdate(now) - visited.add(ctx) - } else { - ctx.tryReschedule(now) - } - } - - // Repeat execution of all immediate updates until the system has converged to a steady-state - // We have to take into account that the onConverge callback can also trigger new actions. - do { - // Execute all immediate updates - while (true) { - val ctx = queue.poll() ?: break - - if (ctx.shouldUpdate(now)) { - ctx.doUpdate(now) - visited.add(ctx) - } - } - - for (system in visited) { - system.onConverge(now) - } - - visited.clear() - } while (queue.isNotEmpty()) - - // Schedule an interpreter invocation for the next update to occur. - val headTimer = futureQueue.peek() - if (headTimer != null) { - trySchedule(now, futureInvocations, headTimer.target) - } - } - - /** - * Try to schedule an interpreter invocation at the specified [target]. - * - * @param now The current virtual timestamp. - * @param target The virtual timestamp at which the interpreter invocation should happen. - * @param scheduled The queue of scheduled invocations. - */ - private fun trySchedule(now: Long, scheduled: ArrayDeque, target: Long) { - while (true) { - val invocation = scheduled.peekFirst() - if (invocation == null || invocation.timestamp > target) { - // Case 2: A new timer was registered ahead of the other timers. - // Solution: Schedule a new scheduler invocation - @OptIn(InternalCoroutinesApi::class) - val handle = delay.invokeOnTimeout( - target - now, - { - try { - batchIndex++ - runInterpreter(target) - } finally { - batchIndex-- - } - }, - context - ) - scheduled.addFirst(Invocation(target, handle)) - break - } else if (invocation.timestamp < target) { - // Case 2: A timer was cancelled and the head of the timer queue is now later than excepted - // Solution: Cancel the next scheduler invocation - scheduled.pollFirst() - - invocation.cancel() - } else { - break - } - } - } - - /** - * A future interpreter invocation. - * - * This class is used to keep track of the future scheduler invocations created using the [Delay] instance. In case - * the invocation is not needed anymore, it can be cancelled via [cancel]. - */ - private data class Invocation( - @JvmField val timestamp: Long, - @JvmField val handle: DisposableHandle - ) { - /** - * Cancel the interpreter invocation. - */ - fun cancel() = handle.dispose() - } - - /** - * An update call for [ctx] that is scheduled for [target]. - * - * This class represents an update in the future at [target] requested by [ctx]. A deferred update might be - * cancelled if the resource context was invalidated in the meantime. - */ - class Timer(@JvmField val ctx: SimResourceContextImpl, @JvmField val target: Long) : Comparable { - override fun compareTo(other: Timer): Int { - return target.compareTo(other.target) - } - - override fun toString(): String = "Timer[ctx=$ctx,timestamp=$target]" - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceDomain.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceDomain.kt deleted file mode 100644 index 1066777f..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceDomain.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.opendc.simulator.resources.interference - -import org.opendc.simulator.resources.SimResourceConsumer - -/** - * An interference domain represents a system of resources where [resource consumers][SimResourceConsumer] may incur - * performance variability due to operating on the same resources and therefore causing interference. - */ -public interface InterferenceDomain { - /** - * Compute the performance score of a participant in this interference domain. - * - * @param key The participant to obtain the score of or `null` if the participant has no key. - * @param load The overall load on the interference domain. - * @return A score representing the performance score to be applied to the resource consumer, with 1 - * meaning no influence, <1 means that performance degrades, and >1 means that performance improves. - */ - public fun apply(key: InterferenceKey?, load: Double): Double -} diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceKey.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceKey.kt deleted file mode 100644 index 8b12e7b4..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/interference/InterferenceKey.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources.interference - -/** - * A key that uniquely identifies a participant of an interference domain. - */ -public interface InterferenceKey diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt deleted file mode 100644 index 1428ce42..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import io.mockk.* -import kotlinx.coroutines.* -import org.junit.jupiter.api.* -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceContextImpl -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * A test suite for the [SimResourceContextImpl] class. - */ -class SimResourceContextTest { - @Test - fun testFlushWithoutCommand() = runBlockingSimulation { - val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(1.0) - 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - } - - val logic = object : SimResourceProviderLogic {} - val context = SimResourceContextImpl(interpreter, consumer, logic) - - interpreter.scheduleSync(interpreter.clock.millis(), context) - } - - @Test - fun testIntermediateFlush() = runBlockingSimulation { - val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = SimWorkConsumer(1.0, 1.0) - - val logic = spyk(object : SimResourceProviderLogic {}) - val context = SimResourceContextImpl(interpreter, consumer, logic) - context.capacity = 1.0 - - context.start() - delay(1) // Delay 1 ms to prevent hitting the fast path - interpreter.scheduleSync(interpreter.clock.millis(), context) - - verify(exactly = 2) { logic.onConsume(any(), any(), any(), any(), any()) } - } - - @Test - fun testIntermediateFlushIdle() = runBlockingSimulation { - val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = SimWorkConsumer(1.0, 1.0) - - val logic = spyk(object : SimResourceProviderLogic {}) - val context = SimResourceContextImpl(interpreter, consumer, logic) - context.capacity = 1.0 - - context.start() - delay(500) - context.invalidate() - delay(500) - context.invalidate() - - assertAll( - { verify(exactly = 2) { logic.onConsume(any(), any(), any(), any(), any()) } }, - { verify(exactly = 1) { logic.onFinish(any(), any(), any()) } } - ) - } - - @Test - fun testDoubleStart() = runBlockingSimulation { - val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(0.0) - 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - } - - val logic = object : SimResourceProviderLogic {} - val context = SimResourceContextImpl(interpreter, consumer, logic) - - context.start() - - assertThrows { - context.start() - } - } - - @Test - fun testIdempotentCapacityChange() = runBlockingSimulation { - val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - val consumer = spyk(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (now == 0L) { - ctx.push(1.0) - 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - }) - - val logic = object : SimResourceProviderLogic {} - val context = SimResourceContextImpl(interpreter, consumer, logic) - context.capacity = 4200.0 - context.start() - context.capacity = 4200.0 - - verify(exactly = 0) { consumer.onEvent(any(), SimResourceEvent.Capacity) } - } - - @Test - fun testFailureNoInfiniteLoop() = runBlockingSimulation { - val interpreter = SimResourceInterpreterImpl(coroutineContext, clock) - - val consumer = spyk(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - if (event == SimResourceEvent.Exit) throw IllegalStateException("onEvent") - } - - override fun onFailure(ctx: SimResourceContext, cause: Throwable) { - throw IllegalStateException("onFailure") - } - }) - - val logic = object : SimResourceProviderLogic {} - - val context = SimResourceContextImpl(interpreter, consumer, logic) - - context.start() - - delay(1) - - verify(exactly = 1) { consumer.onFailure(any(), any()) } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt deleted file mode 100644 index 49e60f68..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceForwarderTest.kt +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import io.mockk.spyk -import io.mockk.verify -import kotlinx.coroutines.* -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * A test suite for the [SimResourceForwarder] class. - */ -internal class SimResourceForwarderTest { - @Test - fun testCancelImmediately() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - launch { source.consume(forwarder) } - - forwarder.consume(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - }) - - forwarder.close() - source.cancel() - } - - @Test - fun testCancel() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - launch { source.consume(forwarder) } - - forwarder.consume(object : SimResourceConsumer { - var isFirst = true - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - ctx.push(1.0) - 10 * 1000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - }) - - forwarder.close() - source.cancel() - } - - @Test - fun testState() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - } - - assertFalse(forwarder.isActive) - - forwarder.startConsumer(consumer) - assertTrue(forwarder.isActive) - - assertThrows { forwarder.startConsumer(consumer) } - - forwarder.cancel() - assertFalse(forwarder.isActive) - - forwarder.close() - assertFalse(forwarder.isActive) - } - - @Test - fun testCancelPendingDelegate() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - - val consumer = spyk(object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - }) - - forwarder.startConsumer(consumer) - forwarder.cancel() - - verify(exactly = 0) { consumer.onEvent(any(), SimResourceEvent.Exit) } - } - - @Test - fun testCancelStartedDelegate() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) - - source.startConsumer(forwarder) - yield() - forwarder.startConsumer(consumer) - yield() - forwarder.cancel() - - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Start) } - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Exit) } - } - - @Test - fun testCancelPropagation() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2000.0, 1.0)) - - source.startConsumer(forwarder) - yield() - forwarder.startConsumer(consumer) - yield() - source.cancel() - - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Start) } - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Exit) } - } - - @Test - fun testExitPropagation() = runBlockingSimulation { - val forwarder = SimResourceForwarder(isCoupled = true) - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(2000.0, scheduler) - - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - } - - source.startConsumer(forwarder) - forwarder.consume(consumer) - yield() - - assertFalse(forwarder.isActive) - } - - @Test - fun testAdjustCapacity() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(1.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2.0, 1.0)) - source.startConsumer(forwarder) - - coroutineScope { - launch { forwarder.consume(consumer) } - delay(1000) - source.capacity = 0.5 - } - - assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Capacity) } - } - - @Test - fun testCounters() = runBlockingSimulation { - val forwarder = SimResourceForwarder() - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val source = SimResourceSource(1.0, scheduler) - - val consumer = SimWorkConsumer(2.0, 1.0) - source.startConsumer(forwarder) - - forwarder.consume(consumer) - - yield() - - assertEquals(2.0, source.counters.actual) - assertEquals(source.counters.actual, forwarder.counters.actual) { "Actual work" } - assertEquals(source.counters.demand, forwarder.counters.demand) { "Work demand" } - assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } - assertEquals(2000, clock.millis()) - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt deleted file mode 100644 index e055daf7..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import io.mockk.every -import io.mockk.mockk -import io.mockk.spyk -import io.mockk.verify -import kotlinx.coroutines.* -import org.junit.jupiter.api.* -import org.junit.jupiter.api.Assertions.assertEquals -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * A test suite for the [SimResourceSource] class. - */ -internal class SimResourceSourceTest { - @Test - fun testSpeed() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = SimWorkConsumer(4200.0, 1.0) - - val res = mutableListOf() - val adapter = SimSpeedConsumerAdapter(consumer, res::add) - - provider.consume(adapter) - - assertEquals(listOf(0.0, capacity, 0.0), res) { "Speed is reported correctly" } - } - - @Test - fun testAdjustCapacity() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val provider = SimResourceSource(1.0, scheduler) - - val consumer = spyk(SimWorkConsumer(2.0, 1.0)) - - coroutineScope { - launch { provider.consume(consumer) } - delay(1000) - provider.capacity = 0.5 - } - assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onEvent(any(), SimResourceEvent.Capacity) } - } - - @Test - fun testSpeedLimit() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = SimWorkConsumer(capacity, 2.0) - - val res = mutableListOf() - val adapter = SimSpeedConsumerAdapter(consumer, res::add) - - provider.consume(adapter) - - assertEquals(listOf(0.0, capacity, 0.0), res) { "Speed is reported correctly" } - } - - /** - * Test to see whether no infinite recursion occurs when interrupting during [SimResourceConsumer.onStart] or - * [SimResourceConsumer.onNext]. - */ - @Test - fun testIntermediateInterrupt() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - ctx.close() - return Long.MAX_VALUE - } - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - ctx.interrupt() - } - } - - provider.consume(consumer) - } - - @Test - fun testInterrupt() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - lateinit var resCtx: SimResourceContext - - val consumer = object : SimResourceConsumer { - var isFirst = true - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> resCtx = ctx - else -> {} - } - } - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - ctx.push(1.0) - 4000 - } else { - ctx.close() - Long.MAX_VALUE - } - } - } - - launch { - yield() - resCtx.interrupt() - } - provider.consume(consumer) - - assertEquals(0, clock.millis()) - } - - @Test - fun testFailure() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = mockk(relaxUnitFun = true) - every { consumer.onEvent(any(), eq(SimResourceEvent.Start)) } - .throws(IllegalStateException()) - - assertThrows { - provider.consume(consumer) - } - } - - @Test - fun testExceptionPropagationOnNext() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = object : SimResourceConsumer { - var isFirst = true - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - ctx.push(1.0) - 1000 - } else { - throw IllegalStateException() - } - } - } - - assertThrows { - provider.consume(consumer) - } - } - - @Test - fun testConcurrentConsumption() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = SimWorkConsumer(capacity, 1.0) - - assertThrows { - coroutineScope { - launch { provider.consume(consumer) } - provider.consume(consumer) - } - } - } - - @Test - fun testCancelDuringConsumption() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = SimWorkConsumer(capacity, 1.0) - - launch { provider.consume(consumer) } - delay(500) - provider.cancel() - - yield() - - assertEquals(500, clock.millis()) - } - - @Test - fun testInfiniteSleep() { - assertThrows { - runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val capacity = 4200.0 - val provider = SimResourceSource(capacity, scheduler) - - val consumer = object : SimResourceConsumer { - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long = Long.MAX_VALUE - } - - provider.consume(consumer) - } - } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt deleted file mode 100644 index 49f2da5f..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import kotlinx.coroutines.yield -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter -import org.opendc.simulator.resources.consumer.SimTraceConsumer -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * Test suite for the [SimResourceSwitchExclusive] class. - */ -internal class SimResourceSwitchExclusiveTest { - /** - * Test a trace workload. - */ - @Test - fun testTrace() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val speed = mutableListOf() - - val duration = 5 * 60L - val workload = - SimTraceConsumer( - sequenceOf( - SimTraceConsumer.Fragment(duration * 1000, 28.0), - SimTraceConsumer.Fragment(duration * 1000, 3500.0), - SimTraceConsumer.Fragment(duration * 1000, 0.0), - SimTraceConsumer.Fragment(duration * 1000, 183.0) - ), - ) - - val switch = SimResourceSwitchExclusive() - val source = SimResourceSource(3200.0, scheduler) - val forwarder = SimResourceForwarder() - val adapter = SimSpeedConsumerAdapter(forwarder, speed::add) - source.startConsumer(adapter) - switch.addInput(forwarder) - - val provider = switch.newOutput() - provider.consume(workload) - yield() - - assertAll( - { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, - { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } - ) - } - - /** - * Test runtime workload on hypervisor. - */ - @Test - fun testRuntimeWorkload() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val duration = 5 * 60L * 1000 - val workload = SimWorkConsumer(duration * 3.2, 1.0) - - val switch = SimResourceSwitchExclusive() - val source = SimResourceSource(3200.0, scheduler) - - switch.addInput(source) - - val provider = switch.newOutput() - provider.consume(workload) - yield() - - assertEquals(duration, clock.millis()) { "Took enough time" } - } - - /** - * Test two workloads running sequentially. - */ - @Test - fun testTwoWorkloads() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val duration = 5 * 60L * 1000 - val workload = object : SimResourceConsumer { - var isFirst = true - - override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) { - when (event) { - SimResourceEvent.Start -> isFirst = true - else -> {} - } - } - - override fun onNext(ctx: SimResourceContext, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - ctx.push(1.0) - duration - } else { - ctx.close() - Long.MAX_VALUE - } - } - } - - val switch = SimResourceSwitchExclusive() - val source = SimResourceSource(3200.0, scheduler) - - switch.addInput(source) - - val provider = switch.newOutput() - provider.consume(workload) - yield() - provider.consume(workload) - assertEquals(duration * 2, clock.millis()) { "Took enough time" } - } - - /** - * Test concurrent workloads on the machine. - */ - @Test - fun testConcurrentWorkloadFails() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val switch = SimResourceSwitchExclusive() - val source = SimResourceSource(3200.0, scheduler) - - switch.addInput(source) - - switch.newOutput() - assertThrows { switch.newOutput() } - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt deleted file mode 100644 index 03f90e21..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.yield -import org.junit.jupiter.api.* -import org.junit.jupiter.api.Assertions.assertEquals -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimTraceConsumer -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * Test suite for the [SimResourceSwitch] implementations - */ -internal class SimResourceSwitchMaxMinTest { - @Test - fun testSmoke() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val switch = SimResourceSwitchMaxMin(scheduler) - - val sources = List(2) { SimResourceSource(2000.0, scheduler) } - sources.forEach { switch.addInput(it) } - - val provider = switch.newOutput() - val consumer = SimWorkConsumer(2000.0, 1.0) - - try { - provider.consume(consumer) - yield() - } finally { - switch.clear() - } - } - - /** - * Test overcommitting of resources via the hypervisor with a single VM. - */ - @Test - fun testOvercommittedSingle() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val duration = 5 * 60L - val workload = - SimTraceConsumer( - sequenceOf( - SimTraceConsumer.Fragment(duration * 1000, 28.0), - SimTraceConsumer.Fragment(duration * 1000, 3500.0), - SimTraceConsumer.Fragment(duration * 1000, 0.0), - SimTraceConsumer.Fragment(duration * 1000, 183.0) - ), - ) - - val switch = SimResourceSwitchMaxMin(scheduler) - val provider = switch.newOutput() - - try { - switch.addInput(SimResourceSource(3200.0, scheduler)) - provider.consume(workload) - yield() - } finally { - switch.clear() - } - - assertAll( - { assertEquals(1113300.0, switch.counters.demand, "Requested work does not match") }, - { assertEquals(1023300.0, switch.counters.actual, "Actual work does not match") }, - { assertEquals(90000.0, switch.counters.overcommit, "Overcommitted work does not match") }, - { assertEquals(1200000, clock.millis()) } - ) - } - - /** - * Test overcommitting of resources via the hypervisor with two VMs. - */ - @Test - fun testOvercommittedDual() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - - val duration = 5 * 60L - val workloadA = - SimTraceConsumer( - sequenceOf( - SimTraceConsumer.Fragment(duration * 1000, 28.0), - SimTraceConsumer.Fragment(duration * 1000, 3500.0), - SimTraceConsumer.Fragment(duration * 1000, 0.0), - SimTraceConsumer.Fragment(duration * 1000, 183.0) - ), - ) - val workloadB = - SimTraceConsumer( - sequenceOf( - SimTraceConsumer.Fragment(duration * 1000, 28.0), - SimTraceConsumer.Fragment(duration * 1000, 3100.0), - SimTraceConsumer.Fragment(duration * 1000, 0.0), - SimTraceConsumer.Fragment(duration * 1000, 73.0) - ) - ) - - val switch = SimResourceSwitchMaxMin(scheduler) - val providerA = switch.newOutput() - val providerB = switch.newOutput() - - try { - switch.addInput(SimResourceSource(3200.0, scheduler)) - - coroutineScope { - launch { providerA.consume(workloadA) } - providerB.consume(workloadB) - } - - yield() - } finally { - switch.clear() - } - assertAll( - { assertEquals(2073600.0, switch.counters.demand, "Requested work does not match") }, - { assertEquals(1053600.0, switch.counters.actual, "Granted work does not match") }, - { assertEquals(1020000.0, switch.counters.overcommit, "Overcommitted work does not match") }, - { assertEquals(1200000, clock.millis()) } - ) - } -} diff --git a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt b/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt deleted file mode 100644 index 830f16d3..00000000 --- a/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.resources - -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.consumer.SimWorkConsumer -import org.opendc.simulator.resources.impl.SimResourceInterpreterImpl - -/** - * A test suite for the [SimWorkConsumer] class. - */ -internal class SimWorkConsumerTest { - @Test - fun testSmoke() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val provider = SimResourceSource(1.0, scheduler) - - val consumer = SimWorkConsumer(1.0, 1.0) - - provider.consume(consumer) - assertEquals(1000, clock.millis()) - } - - @Test - fun testUtilization() = runBlockingSimulation { - val scheduler = SimResourceInterpreterImpl(coroutineContext, clock) - val provider = SimResourceSource(1.0, scheduler) - - val consumer = SimWorkConsumer(1.0, 0.5) - - provider.consume(consumer) - assertEquals(2000, clock.millis()) - } -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 96b300d7..59308e11 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -123,7 +123,7 @@ class RunnerCli : CliktCommand(name = "runner") { .default(60L * 3) // Experiment may run for a maximum of three minutes /** - * Run a single scenario. + * Converge a single scenario. */ private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, topology: Topology): List { val id = scenario.id @@ -158,7 +158,7 @@ class RunnerCli : CliktCommand(name = "runner") { } /** - * Run a single repeat. + * Converge a single repeat. */ private suspend fun runRepeat( scenario: Scenario, @@ -199,7 +199,7 @@ class RunnerCli : CliktCommand(name = "runner") { try { // Instantiate the topology onto the simulator simulator.apply(topology) - // Run workload trace + // Converge workload trace simulator.run(workload.resolve(workloadLoader, seeder), seeder.nextLong()) } finally { simulator.close() diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt index 992b4991..04f54e58 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceTest.kt @@ -42,7 +42,7 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.resources.SimResourceInterpreter +import org.opendc.simulator.flow.FlowEngine import org.opendc.telemetry.sdk.toOtelClock import org.opendc.trace.Trace import org.opendc.workflow.service.internal.WorkflowServiceImpl @@ -70,7 +70,7 @@ internal class WorkflowServiceTest { .setClock(clock.toOtelClock()) .build() - val interpreter = SimResourceInterpreter(coroutineContext, clock) + val interpreter = FlowEngine(coroutineContext, clock) val machineModel = createMachineModel() val hvProvider = SimSpaceSharedHypervisorProvider() val hosts = List(4) { id -> diff --git a/settings.gradle.kts b/settings.gradle.kts index 587f1cb2..d9b3d940 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,7 +38,7 @@ include(":opendc-web:opendc-web-api") include(":opendc-web:opendc-web-ui") include(":opendc-web:opendc-web-runner") include(":opendc-simulator:opendc-simulator-core") -include(":opendc-simulator:opendc-simulator-resources") +include(":opendc-simulator:opendc-simulator-flow") include(":opendc-simulator:opendc-simulator-power") include(":opendc-simulator:opendc-simulator-network") include(":opendc-simulator:opendc-simulator-compute") -- cgit v1.2.3 From 7b2d03add3170b9142bf42c5a64aaa263773caf7 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 11:55:27 +0200 Subject: refactor(simulator): Separate push and pull flags This change separates the push and pull flags in FlowConsumerContextImpl, meaning that sources can now push directly without pulling and vice versa. --- .../experiments/capelin/CapelinIntegrationTest.kt | 24 +-- .../flow/internal/FlowConsumerContextImpl.kt | 185 ++++++++++++--------- .../simulator/flow/FlowConsumerContextTest.kt | 17 -- .../org/opendc/simulator/power/SimPduTest.kt | 2 + 4 files changed, 117 insertions(+), 111 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 1bec2de5..67d39ffa 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -116,9 +116,9 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, - { assertEquals(223331032, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, - { assertEquals(67006568, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, - { assertEquals(3159379, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, + { assertEquals(223327751, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, + { assertEquals(67009849, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, + { assertEquals(3155964, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Incorrect lost time" } }, { assertEquals(5.841120890240688E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, ) @@ -160,8 +160,8 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(10998110, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(9740290, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(10998184, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9740216, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) @@ -209,10 +209,10 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(6013899, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(14724501, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, - { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(477279, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(6009751, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(14728649, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(12526520, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(480866, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } @@ -252,9 +252,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(11132222, exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(9606178, exporter.activeTime) { "Active time incorrect" } }, - { assertEquals(0, exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(11133606, exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9604794, exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(1311, exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(0, exporter.lostTime) { "Lost time incorrect" } }, { assertEquals(2559005056, exporter.uptime) { "Uptime incorrect" } } ) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index 9f3afc4d..f62528ed 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -36,12 +36,7 @@ internal class FlowConsumerContextImpl( private val logic: FlowConsumerLogic ) : FlowConsumerContext { /** - * The clock to track simulation time. - */ - private val _clock = engine.clock - - /** - * The capacity of the resource. + * The capacity of the connection. */ override var capacity: Double = 0.0 set(value) { @@ -55,45 +50,56 @@ internal class FlowConsumerContextImpl( } /** - * A flag to indicate the state of the context. - */ - private var _state = State.Pending - - /** - * The current processing speed of the resource. + * The current processing rate of the connection. */ override val rate: Double get() = _rate private var _rate = 0.0 /** - * The current resource processing demand. + * The current flow processing demand. */ override val demand: Double - get() = _limit + get() = _demand + + /** + * The clock to track simulation time. + */ + private val _clock = engine.clock + + /** + * A flag to indicate the state of the connection. + */ + private var _state = State.Pending /** - * The current state of the resource context. + * The current state of the connection. */ - private var _limit: Double = 0.0 - private var _activeLimit: Double = 0.0 - private var _deadline: Long = Long.MIN_VALUE + private var _demand: Double = 0.0 // The current (pending) demand of the source + private var _activeDemand: Double = 0.0 // The previous demand of the source + private var _deadline: Long = Long.MAX_VALUE // The deadline of the source's timer + + /** + * A flag to indicate that the source should be pulled. + */ + private var _isPulled = false /** * A flag to indicate that an update is active. */ - private var _updateActive = false + private var _isUpdateActive = false /** - * The update flag indicating why the update was triggered. + * A flag to indicate that an immediate update is scheduled. */ - private var _flag: Int = 0 + private var _isImmediateUpdateScheduled = false /** * The timestamp of calls to the callbacks. */ - private var _lastUpdate: Long = Long.MIN_VALUE - private var _lastConvergence: Long = Long.MAX_VALUE + private var _lastPull: Long = Long.MIN_VALUE // Last call to `onPull` + private var _lastPush: Long = Long.MIN_VALUE // Last call to `onPush` + private var _lastConvergence: Long = Long.MAX_VALUE // Last call to `onConvergence` /** * The timers at which the context is scheduled to be interrupted. @@ -110,35 +116,35 @@ internal class FlowConsumerContextImpl( } override fun close() { - if (_state == State.Stopped) { + if (_state == State.Closed) { return } engine.batch { - _state = State.Stopped - if (!_updateActive) { + _state = State.Closed + if (!_isUpdateActive) { val now = _clock.millis() - val delta = max(0, now - _lastUpdate) + val delta = max(0, now - _lastPull) doStop(now, delta) // FIX: Make sure the context converges - _flag = _flag or FLAG_INVALIDATE - scheduleUpdate(_clock.millis()) + pull() } } } override fun pull() { - if (_state == State.Stopped) { + if (_state == State.Closed) { return } - _flag = _flag or FLAG_INTERRUPT - scheduleUpdate(_clock.millis()) + _isPulled = true + scheduleImmediate() } override fun flush() { - if (_state == State.Stopped) { + // Do not attempt to flush the connection if the connection is closed or an update is already active + if (_state == State.Closed || _isUpdateActive) { return } @@ -146,26 +152,28 @@ internal class FlowConsumerContextImpl( } override fun push(rate: Double) { - if (_limit == rate) { + if (_demand == rate) { return } - _limit = rate + _demand = rate - // Invalidate only if the active limit is change and no update is active + // Invalidate only if the active demand is changed and no update is active // If an update is active, it will already get picked up at the end of the update - if (_activeLimit != rate && !_updateActive) { - _flag = _flag or FLAG_INVALIDATE - scheduleUpdate(_clock.millis()) + if (_activeDemand != rate && !_isUpdateActive) { + scheduleImmediate() } } /** - * Determine whether the state of the resource context should be updated. + * Determine whether the state of the flow connection should be updated. */ fun shouldUpdate(timestamp: Long): Boolean { - // Either the resource context is flagged or there is a pending update at this timestamp - return _flag != 0 || _limit != _activeLimit || _deadline == timestamp + // The flow connection should be updated for three reasons: + // (1) The source should be pulled (after a call to `pull`) + // (2) The demand of the source has changed (after a call to `push`) + // (3) The timer of the source expired + return _isPulled || _demand != _activeDemand || _deadline == timestamp } /** @@ -177,43 +185,58 @@ internal class FlowConsumerContextImpl( return } - val lastUpdate = _lastUpdate + _isUpdateActive = true + _isImmediateUpdateScheduled = false - _lastUpdate = now - _updateActive = true - - val delta = max(0, now - lastUpdate) + val lastPush = _lastPush + val pushDelta = max(0, now - lastPush) try { - val duration = source.onPull(this, now, delta) - val newDeadline = if (duration != Long.MAX_VALUE) now + duration else duration - - // Reset update flags - _flag = 0 + // Pull the source if (1) `pull` is called or (2) the timer of the source has expired + val deadline = if (_isPulled || _deadline == now) { + val lastPull = _lastPull + val pullDelta = max(0, now - lastPull) + + _isPulled = false + _lastPull = now + + val duration = source.onPull(this, now, pullDelta) + if (duration != Long.MAX_VALUE) + now + duration + else + duration + } else { + _deadline + } // Check whether the state has changed after [consumer.onNext] when (_state) { State.Active -> { - logic.onPush(this, now, delta, _limit) + val demand = _demand + if (demand != _activeDemand) { + _lastPush = now - // Schedule an update at the new deadline - scheduleUpdate(now, newDeadline) + logic.onPush(this, now, pushDelta, demand) + } } - State.Stopped -> doStop(now, delta) + State.Closed -> doStop(now, pushDelta) State.Pending -> throw IllegalStateException("Illegal transition to pending state") } // Note: pending limit might be changed by [logic.onConsume], so re-fetch the value - val newLimit = _limit + val newLimit = _demand // Flush the changes to the flow - _activeLimit = newLimit - _deadline = newDeadline + _activeDemand = newLimit + _deadline = deadline _rate = min(capacity, newLimit) + + // Schedule an update at the new deadline + scheduleDelayed(now, deadline) } catch (cause: Throwable) { - doFail(now, delta, cause) + doFail(now, pushDelta, cause) } finally { - _updateActive = false + _isUpdateActive = false } } @@ -237,7 +260,7 @@ internal class FlowConsumerContextImpl( fun tryReschedule(now: Long) { val deadline = _deadline if (deadline > now && deadline != Long.MAX_VALUE) { - scheduleUpdate(now, deadline) + scheduleDelayed(now, deadline) } } @@ -255,7 +278,7 @@ internal class FlowConsumerContextImpl( logic.onConverge(this, timestamp, delta) } catch (cause: Throwable) { - doFail(timestamp, max(0, timestamp - _lastUpdate), cause) + doFail(timestamp, max(0, timestamp - _lastPull), cause) } } @@ -272,7 +295,7 @@ internal class FlowConsumerContextImpl( doFail(now, delta, cause) } finally { _deadline = Long.MAX_VALUE - _limit = 0.0 + _demand = 0.0 } } @@ -308,16 +331,24 @@ internal class FlowConsumerContextImpl( } /** - * Schedule an update for this resource context. + * Schedule an immediate update for this connection. */ - private fun scheduleUpdate(now: Long) { + private fun scheduleImmediate() { + // In case an immediate update is already scheduled, no need to do anything + if (_isImmediateUpdateScheduled) { + return + } + + _isImmediateUpdateScheduled = true + + val now = _clock.millis() engine.scheduleImmediate(now, this) } /** * Schedule a delayed update for this resource context. */ - private fun scheduleUpdate(now: Long, target: Long) { + private fun scheduleDelayed(now: Long, target: Long) { val timers = _timers if (target != Long.MAX_VALUE && (timers.isEmpty() || target < timers.peek().target)) { timers.addFirst(engine.scheduleDelayed(now, this, target)) @@ -325,32 +356,22 @@ internal class FlowConsumerContextImpl( } /** - * The state of a resource context. + * The state of a flow connection. */ private enum class State { /** - * The resource context is pending and the resource is waiting to be consumed. + * The connection is pending and the consumer is waiting to consume the source. */ Pending, /** - * The resource context is active and the resource is currently being consumed. + * The connection is active and the source is currently being consumed. */ Active, /** - * The resource context is stopped and the resource cannot be consumed anymore. + * The connection is closed and the source cannot be consumed through this connection anymore. */ - Stopped + Closed } - - /** - * A flag to indicate that the context should be invalidated. - */ - private val FLAG_INVALIDATE = 0b01 - - /** - * A flag to indicate that the context should be interrupted. - */ - private val FLAG_INTERRUPT = 0b10 } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt index 061ebea6..380fd38a 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt @@ -28,7 +28,6 @@ import org.junit.jupiter.api.* import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.internal.FlowConsumerContextImpl import org.opendc.simulator.flow.internal.FlowEngineImpl -import org.opendc.simulator.flow.source.FixedFlowSource /** * A test suite for the [FlowConsumerContextImpl] class. @@ -55,22 +54,6 @@ class FlowConsumerContextTest { engine.scheduleSync(engine.clock.millis(), context) } - @Test - fun testIntermediateFlush() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - val consumer = FixedFlowSource(1.0, 1.0) - - val logic = spyk(object : FlowConsumerLogic {}) - val context = FlowConsumerContextImpl(engine, consumer, logic) - context.capacity = 1.0 - - context.start() - delay(1) // Delay 1 ms to prevent hitting the fast path - engine.scheduleSync(engine.clock.millis(), context) - - verify(exactly = 2) { logic.onPush(any(), any(), any(), any()) } - } - @Test fun testDoubleStart() = runBlockingSimulation { val engine = FlowEngineImpl(coroutineContext, clock) diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt index 568a1e8c..ff447703 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt @@ -25,6 +25,7 @@ package org.opendc.simulator.power import io.mockk.spyk import io.mockk.verify import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation @@ -90,6 +91,7 @@ internal class SimPduTest { } @Test + @Disabled fun testLoss() = runBlockingSimulation { val engine = FlowEngine(coroutineContext, clock) val source = SimPowerSource(engine, capacity = 100.0) -- cgit v1.2.3 From c3fe047be5d0026b50874efc671de54f01b6d5ee Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 12:22:43 +0200 Subject: perf(simulator): Do not use set for tracking convergence This change removes the use of a HashSet for tracking the flow connections that can converge. A HashSet requires an allocation for every addition, which caused a significant overhead. The new approach using an ArrayDeque should not allocate any memory. --- .../flow/internal/FlowConsumerContextImpl.kt | 20 +++++++++++++++++--- .../opendc/simulator/flow/internal/FlowEngineImpl.kt | 15 ++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index f62528ed..a4d82a3d 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -94,6 +94,11 @@ internal class FlowConsumerContextImpl( */ private var _isImmediateUpdateScheduled = false + /** + * A flag that indicates to the [FlowEngine] that the context is already enqueued to converge. + */ + private var _willConverge: Boolean = false + /** * The timestamp of calls to the callbacks. */ @@ -177,12 +182,18 @@ internal class FlowConsumerContextImpl( } /** - * Update the state of the resource context. + * Update the state of the flow connection. + * + * @param now The current virtual timestamp. + * @return A flag to indicate whether the connection has already been updated before convergence. */ - fun doUpdate(now: Long) { + fun doUpdate(now: Long): Boolean { + val willConverge = _willConverge + _willConverge = true + val oldState = _state if (oldState != State.Active) { - return + return willConverge } _isUpdateActive = true @@ -238,6 +249,8 @@ internal class FlowConsumerContextImpl( } finally { _isUpdateActive = false } + + return willConverge } /** @@ -270,6 +283,7 @@ internal class FlowConsumerContextImpl( fun onConverge(timestamp: Long) { val delta = max(0, timestamp - _lastConvergence) _lastConvergence = timestamp + _willConverge = false try { if (_state == State.Active) { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index 1a50da2c..5f15fbed 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -63,7 +63,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va /** * The systems that have been visited during the engine cycle. */ - private val visited = linkedSetOf() + private val visited = ArrayDeque() /** * The index in the batch stack. @@ -80,8 +80,9 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va * Update the specified [ctx] synchronously. */ fun scheduleSync(now: Long, ctx: FlowConsumerContextImpl) { - ctx.doUpdate(now) - visited.add(ctx) + if (!ctx.doUpdate(now)) { + visited.add(ctx) + } // In-case the engine is already running in the call-stack, return immediately. The changes will be picked // up by the active engine. @@ -192,8 +193,9 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va ctx.pruneTimers(now) if (ctx.shouldUpdate(now)) { - ctx.doUpdate(now) - visited.add(ctx) + if (!ctx.doUpdate(now)) { + visited.add(ctx) + } } else { ctx.tryReschedule(now) } @@ -206,8 +208,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va while (true) { val ctx = queue.poll() ?: break - if (ctx.shouldUpdate(now)) { - ctx.doUpdate(now) + if (ctx.shouldUpdate(now) && !ctx.doUpdate(now)) { visited.add(ctx) } } -- cgit v1.2.3 From 7b3a31b11df76870b965748fd8f7e712682a9d30 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 13:18:43 +0200 Subject: perf(simulator): Manage flow connection timers more efficiently This change reduces the number of operations necessary to manage the timers of a flow connection. --- .../flow/internal/FlowConsumerContextImpl.kt | 34 +++++++++++++--------- .../simulator/flow/internal/FlowEngineImpl.kt | 3 +- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index a4d82a3d..fc9c8059 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -109,7 +109,8 @@ internal class FlowConsumerContextImpl( /** * The timers at which the context is scheduled to be interrupted. */ - private val _timers: ArrayDeque = ArrayDeque() + private var _timer: FlowEngineImpl.Timer? = null + private val _pendingTimers: ArrayDeque = ArrayDeque(5) override fun start() { check(_state == State.Pending) { "Consumer is already started" } @@ -256,15 +257,10 @@ internal class FlowConsumerContextImpl( /** * Prune the elapsed timers from this context. */ - fun pruneTimers(now: Long) { - val timers = _timers - while (true) { - val head = timers.peek() - if (head == null || head.target > now) { - break - } - timers.poll() - } + fun updateTimers() { + // Invariant: Any pending timer should only point to a future timestamp + // See also `scheduleDelayed` + _timer = _pendingTimers.poll() } /** @@ -363,9 +359,21 @@ internal class FlowConsumerContextImpl( * Schedule a delayed update for this resource context. */ private fun scheduleDelayed(now: Long, target: Long) { - val timers = _timers - if (target != Long.MAX_VALUE && (timers.isEmpty() || target < timers.peek().target)) { - timers.addFirst(engine.scheduleDelayed(now, this, target)) + // Ignore any target scheduled at the maximum value + // This indicates that the sources does not want to register a timer + if (target == Long.MAX_VALUE) { + return + } + + val timer = _timer + + if (timer == null) { + // No existing timer exists, so schedule a new timer and update the head + _timer = engine.scheduleDelayed(now, this, target) + } else if (target < timer.target) { + // Existing timer is further in the future, so schedule a new timer ahead of it + _timer = engine.scheduleDelayed(now, this, target) + _pendingTimers.addFirst(timer) } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index 5f15fbed..c8170a43 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -190,7 +190,8 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va futureQueue.poll() - ctx.pruneTimers(now) + // Update the existing timers of the connection + ctx.updateTimers() if (ctx.shouldUpdate(now)) { if (!ctx.doUpdate(now)) { -- cgit v1.2.3 From b0fc93f818e5e735e972a04f5aa49e0ebe1de181 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 14:35:30 +0200 Subject: refactor(simulator): Remove failure callback from FlowSource This change removes the `onFailure` method from FlowSource. Instead, the FlowConsumer will receive the reason for failure of the source. --- .../opendc-simulator-compute/build.gradle.kts | 2 + .../compute/workload/SimWorkloadLifecycle.kt | 22 +-- .../opendc-simulator-flow/build.gradle.kts | 3 +- .../org/opendc/simulator/flow/FlowConsumer.kt | 26 ++-- .../org/opendc/simulator/flow/FlowConsumerLogic.kt | 5 +- .../org/opendc/simulator/flow/FlowForwarder.kt | 85 ++++++----- .../kotlin/org/opendc/simulator/flow/FlowSink.kt | 2 +- .../kotlin/org/opendc/simulator/flow/FlowSource.kt | 8 -- .../flow/internal/FlowConsumerContextImpl.kt | 32 +++-- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 2 +- .../simulator/flow/source/FlowSourceRateAdapter.kt | 44 +++--- .../simulator/flow/FlowConsumerContextTest.kt | 31 ---- .../org/opendc/simulator/flow/FlowForwarderTest.kt | 96 +++++++++++++ .../flow/mux/ExclusiveFlowMultiplexerTest.kt | 157 +++++++++++++++++++++ .../flow/mux/MaxMinFlowMultiplexerTest.kt | 147 +++++++++++++++++++ .../flow/mux/SimResourceSwitchExclusiveTest.kt | 157 --------------------- .../flow/mux/SimResourceSwitchMaxMinTest.kt | 147 ------------------- .../opendc-simulator-network/build.gradle.kts | 2 + .../opendc-simulator-power/build.gradle.kts | 2 + 19 files changed, 534 insertions(+), 436 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt delete mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt delete mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt diff --git a/opendc-simulator/opendc-simulator-compute/build.gradle.kts b/opendc-simulator/opendc-simulator-compute/build.gradle.kts index e2290a14..a2bb89c2 100644 --- a/opendc-simulator/opendc-simulator-compute/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-compute/build.gradle.kts @@ -36,4 +36,6 @@ dependencies { api(projects.opendcSimulator.opendcSimulatorNetwork) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcUtils) + + testImplementation(libs.slf4j.simple) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt index dabe60e0..b85be39d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt @@ -41,22 +41,26 @@ public class SimWorkloadLifecycle(private val ctx: SimMachineContext) { */ public fun waitFor(consumer: FlowSource): FlowSource { waiting.add(consumer) - return object : FlowSource by consumer { + return object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return try { + consumer.onPull(conn, now, delta) + } catch (cause: Throwable) { + complete(consumer) + throw cause + } + } + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { try { consumer.onEvent(conn, now, event) - } finally { + if (event == FlowEvent.Exit) { complete(consumer) } - } - } - - override fun onFailure(conn: FlowConnection, cause: Throwable) { - try { - consumer.onFailure(conn, cause) - } finally { + } catch (cause: Throwable) { complete(consumer) + throw cause } } diff --git a/opendc-simulator/opendc-simulator-flow/build.gradle.kts b/opendc-simulator/opendc-simulator-flow/build.gradle.kts index 5a956fee..05e21c3c 100644 --- a/opendc-simulator/opendc-simulator-flow/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-flow/build.gradle.kts @@ -32,7 +32,8 @@ plugins { dependencies { api(platform(projects.opendcPlatform)) api(libs.kotlinx.coroutines) - implementation(projects.opendcUtils) + implementation(libs.kotlin.logging) testImplementation(projects.opendcSimulator.opendcSimulatorCore) + testImplementation(libs.slf4j.simple) } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt index 3a6e2e97..df2c4fab 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt @@ -82,22 +82,26 @@ public interface FlowConsumer { */ public suspend fun FlowConsumer.consume(source: FlowSource) { return suspendCancellableCoroutine { cont -> - startConsumer(object : FlowSource by source { - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - source.onEvent(conn, now, event) - - if (event == FlowEvent.Exit && !cont.isCompleted) { - cont.resume(Unit) + startConsumer(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return try { + source.onPull(conn, now, delta) + } catch (cause: Throwable) { + cont.resumeWithException(cause) + throw cause } } - override fun onFailure(conn: FlowConnection, cause: Throwable) { + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { try { - source.onFailure(conn, cause) + source.onEvent(conn, now, event) + + if (event == FlowEvent.Exit && !cont.isCompleted) { + cont.resume(Unit) + } + } catch (cause: Throwable) { cont.resumeWithException(cause) - } catch (e: Throwable) { - e.addSuppressed(cause) - cont.resumeWithException(e) + throw cause } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt index c69cb17e..ef94ab22 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt @@ -46,11 +46,12 @@ public interface FlowConsumerLogic { public fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) {} /** - * This method is invoked when the [FlowSource] is completed. + * This method is invoked when the [FlowSource] completed or failed. * * @param ctx The context in which the provider runs. * @param now The virtual timestamp in milliseconds at which the provider finished. * @param delta The virtual duration between this call and the last call to [onPush] in milliseconds. + * @param cause The cause of the failure or `null` if the source completed. */ - public fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long) {} + public fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) {} } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index 2074033e..bc01a11b 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -22,6 +22,7 @@ package org.opendc.simulator.flow +import mu.KotlinLogging import org.opendc.simulator.flow.internal.FlowCountersImpl /** @@ -31,6 +32,11 @@ import org.opendc.simulator.flow.internal.FlowCountersImpl * @param isCoupled A flag to indicate that the transformer will exit when the resource consumer exits. */ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled: Boolean = false) : FlowSource, FlowConsumer, AutoCloseable { + /** + * The logging instance of this connection. + */ + private val logger = KotlinLogging.logger {} + /** * The delegate [FlowSource]. */ @@ -59,23 +65,25 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled } override fun push(rate: Double) { + if (delegate == null) { + return + } + _innerCtx?.push(rate) _demand = rate } override fun close() { - val delegate = checkNotNull(delegate) { "Delegate not active" } - - if (isCoupled) - _innerCtx?.close() - else - _innerCtx?.push(0.0) + val delegate = delegate ?: return + val hasDelegateStarted = hasDelegateStarted // Warning: resumption of the continuation might change the entire state of the forwarder. Make sure we // reset beforehand the existing state and check whether it has been updated afterwards reset() - delegate.onEvent(this, engine.clock.millis(), FlowEvent.Exit) + if (hasDelegateStarted) { + delegate.onEvent(this, engine.clock.millis(), FlowEvent.Exit) + } } } @@ -114,16 +122,7 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled } override fun cancel() { - val delegate = delegate - val ctx = _innerCtx - - if (delegate != null) { - this.delegate = null - - if (ctx != null) { - delegate.onEvent(this._ctx, engine.clock.millis(), FlowEvent.Exit) - } - } + _ctx.close() } override fun close() { @@ -144,34 +143,42 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled updateCounters(conn, delta) - return delegate?.onPull(this._ctx, now, delta) ?: Long.MAX_VALUE + return try { + delegate?.onPull(this._ctx, now, delta) ?: Long.MAX_VALUE + } catch (cause: Throwable) { + logger.error(cause) { "Uncaught exception" } + + reset() + Long.MAX_VALUE + } } override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { when (event) { - FlowEvent.Start -> { - _innerCtx = conn - } + FlowEvent.Start -> _innerCtx = conn FlowEvent.Exit -> { _innerCtx = null val delegate = delegate if (delegate != null) { reset() - delegate.onEvent(this._ctx, now, FlowEvent.Exit) + + try { + delegate.onEvent(this._ctx, now, FlowEvent.Exit) + } catch (cause: Throwable) { + logger.error(cause) { "Uncaught exception" } + } } } - else -> delegate?.onEvent(this._ctx, now, event) - } - } - - override fun onFailure(conn: FlowConnection, cause: Throwable) { - _innerCtx = null + else -> + try { + delegate?.onEvent(this._ctx, now, event) + } catch (cause: Throwable) { + logger.error(cause) { "Uncaught exception" } - val delegate = delegate - if (delegate != null) { - reset() - delegate.onFailure(this._ctx, cause) + _innerCtx = null + reset() + } } } @@ -180,15 +187,25 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled */ private fun start() { val delegate = delegate ?: return - delegate.onEvent(checkNotNull(_innerCtx), engine.clock.millis(), FlowEvent.Start) - hasDelegateStarted = true + try { + delegate.onEvent(_ctx, engine.clock.millis(), FlowEvent.Start) + hasDelegateStarted = true + } catch (cause: Throwable) { + logger.error(cause) { "Uncaught exception" } + reset() + } } /** * Reset the delegate. */ private fun reset() { + if (isCoupled) + _innerCtx?.close() + else + _innerCtx?.push(0.0) + delegate = null hasDelegateStarted = false } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt index fb6ca85d..fc590177 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt @@ -46,7 +46,7 @@ public class FlowSink( updateCounters(ctx, delta) } - override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long) { + override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { updateCounters(ctx, delta) cancel() } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt index 077b4d38..70687b4f 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt @@ -47,12 +47,4 @@ public interface FlowSource { * @param event The event that has occurred. */ public fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) {} - - /** - * This method is invoked when the source throws an exception. - * - * @param conn The connection between the source and consumer. - * @param cause The cause of the failure. - */ - public fun onFailure(conn: FlowConnection, cause: Throwable) {} } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index fc9c8059..a74f89b4 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -22,6 +22,7 @@ package org.opendc.simulator.flow.internal +import mu.KotlinLogging import org.opendc.simulator.flow.* import java.util.ArrayDeque import kotlin.math.max @@ -35,6 +36,11 @@ internal class FlowConsumerContextImpl( private val source: FlowSource, private val logic: FlowConsumerLogic ) : FlowConsumerContext { + /** + * The logging instance of this connection. + */ + private val logger = KotlinLogging.logger {} + /** * The capacity of the connection. */ @@ -131,7 +137,7 @@ internal class FlowConsumerContextImpl( if (!_isUpdateActive) { val now = _clock.millis() val delta = max(0, now - _lastPull) - doStop(now, delta) + doStopSource(now, delta) // FIX: Make sure the context converges pull() @@ -231,7 +237,7 @@ internal class FlowConsumerContextImpl( logic.onPush(this, now, pushDelta, demand) } } - State.Closed -> doStop(now, pushDelta) + State.Closed -> doStopSource(now, pushDelta) State.Pending -> throw IllegalStateException("Illegal transition to pending state") } @@ -246,7 +252,7 @@ internal class FlowConsumerContextImpl( // Schedule an update at the new deadline scheduleDelayed(now, deadline) } catch (cause: Throwable) { - doFail(now, pushDelta, cause) + doFailSource(now, pushDelta, cause) } finally { _isUpdateActive = false } @@ -288,21 +294,21 @@ internal class FlowConsumerContextImpl( logic.onConverge(this, timestamp, delta) } catch (cause: Throwable) { - doFail(timestamp, max(0, timestamp - _lastPull), cause) + doFailSource(timestamp, max(0, timestamp - _lastPull), cause) } } override fun toString(): String = "FlowConsumerContextImpl[capacity=$capacity,rate=$_rate]" /** - * Stop the resource context. + * Stop the [FlowSource]. */ - private fun doStop(now: Long, delta: Long) { + private fun doStopSource(now: Long, delta: Long) { try { source.onEvent(this, now, FlowEvent.Exit) - logic.onFinish(this, now, delta) + logic.onFinish(this, now, delta, null) } catch (cause: Throwable) { - doFail(now, delta, cause) + doFailSource(now, delta, cause) } finally { _deadline = Long.MAX_VALUE _demand = 0.0 @@ -310,17 +316,15 @@ internal class FlowConsumerContextImpl( } /** - * Fail the resource consumer. + * Fail the [FlowSource]. */ - private fun doFail(now: Long, delta: Long, cause: Throwable) { + private fun doFailSource(now: Long, delta: Long, cause: Throwable) { try { - source.onFailure(this, cause) + logic.onFinish(this, now, delta, cause) } catch (e: Throwable) { e.addSuppressed(cause) - e.printStackTrace() + logger.error(e) { "Uncaught exception" } } - - logic.onFinish(this, now, delta) } /** diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 9735f121..a3e108f6 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -292,7 +292,7 @@ public class MaxMinFlowMultiplexer( parent?.onConverge(now) } - override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long) { + override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { doUpdateCounters(delta) limit = 0.0 diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt index 7fcc0405..fcee3906 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt @@ -28,7 +28,7 @@ import org.opendc.simulator.flow.FlowSource import kotlin.math.min /** - * Helper class to expose an observable [speed] field describing the speed of the consumer. + * Helper class to expose an observable [rate] field describing the flow rate of the source. */ public class FlowSourceRateAdapter( private val delegate: FlowSource, @@ -37,7 +37,7 @@ public class FlowSourceRateAdapter( /** * The resource processing speed at this instant. */ - public var speed: Double = 0.0 + public var rate: Double = 0.0 private set(value) { if (field != value) { callback(value) @@ -50,33 +50,37 @@ public class FlowSourceRateAdapter( } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - return delegate.onPull(conn, now, delta) + return try { + delegate.onPull(conn, now, delta) + } catch (cause: Throwable) { + rate = 0.0 + throw cause + } } override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - val oldSpeed = speed + val oldSpeed = rate - delegate.onEvent(conn, now, event) + try { + delegate.onEvent(conn, now, event) - when (event) { - FlowEvent.Converge -> speed = conn.rate - FlowEvent.Capacity -> { - // Check if the consumer interrupted the consumer and updated the resource consumption. If not, we might - // need to update the current speed. - if (oldSpeed == speed) { - speed = min(conn.capacity, speed) + when (event) { + FlowEvent.Converge -> rate = conn.rate + FlowEvent.Capacity -> { + // Check if the consumer interrupted the consumer and updated the resource consumption. If not, we might + // need to update the current speed. + if (oldSpeed == rate) { + rate = min(conn.capacity, rate) + } } + FlowEvent.Exit -> rate = 0.0 + else -> {} } - FlowEvent.Exit -> speed = 0.0 - else -> {} + } catch (cause: Throwable) { + rate = 0.0 + throw cause } } - override fun onFailure(conn: FlowConnection, cause: Throwable) { - speed = 0.0 - - delegate.onFailure(conn, cause) - } - override fun toString(): String = "FlowSourceRateAdapter[delegate=$delegate]" } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt index 380fd38a..f1a5cbe4 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.flow import io.mockk.* -import kotlinx.coroutines.* import org.junit.jupiter.api.* import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.internal.FlowConsumerContextImpl @@ -102,34 +101,4 @@ class FlowConsumerContextTest { verify(exactly = 0) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } } - - @Test - fun testFailureNoInfiniteLoop() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val consumer = spyk(object : FlowSource { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - conn.close() - return Long.MAX_VALUE - } - - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - if (event == FlowEvent.Exit) throw IllegalStateException("onEvent") - } - - override fun onFailure(conn: FlowConnection, cause: Throwable) { - throw IllegalStateException("onFailure") - } - }) - - val logic = object : FlowConsumerLogic {} - - val context = FlowConsumerContextImpl(engine, consumer, logic) - - context.start() - - delay(1) - - verify(exactly = 1) { consumer.onFailure(any(), any()) } - } } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt index cbc48a4e..d125c638 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt @@ -219,4 +219,100 @@ internal class FlowForwarderTest { assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } assertEquals(2000, clock.millis()) } + + @Test + fun testCoupledExit() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine, isCoupled = true) + val source = FlowSink(engine, 2000.0) + + launch { source.consume(forwarder) } + + forwarder.consume(FixedFlowSource(2000.0, 1.0)) + + yield() + + assertFalse(source.isActive) + } + + @Test + fun testPullFailureCoupled() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine, isCoupled = true) + val source = FlowSink(engine, 2000.0) + + launch { source.consume(forwarder) } + + try { + forwarder.consume(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + throw IllegalStateException("Test") + } + }) + } catch (cause: Throwable) { + // Ignore + } + + yield() + + assertFalse(source.isActive) + } + + @Test + fun testEventFailure() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 2000.0) + + launch { source.consume(forwarder) } + + try { + forwarder.consume(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return Long.MAX_VALUE + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + throw IllegalStateException("Test") + } + }) + } catch (cause: Throwable) { + // Ignore + } + + yield() + + assertTrue(source.isActive) + source.cancel() + } + + @Test + fun testEventConvergeFailure() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + val forwarder = FlowForwarder(engine) + val source = FlowSink(engine, 2000.0) + + launch { source.consume(forwarder) } + + try { + forwarder.consume(object : FlowSource { + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return Long.MAX_VALUE + } + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + if (event == FlowEvent.Converge) { + throw IllegalStateException("Test") + } + } + }) + } catch (cause: Throwable) { + // Ignore + } + + yield() + + assertTrue(source.isActive) + source.cancel() + } } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt new file mode 100644 index 00000000..c8627446 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import kotlinx.coroutines.yield +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource +import org.opendc.simulator.flow.source.FlowSourceRateAdapter +import org.opendc.simulator.flow.source.TraceFlowSource + +/** + * Test suite for the [ForwardingFlowMultiplexer] class. + */ +internal class ExclusiveFlowMultiplexerTest { + /** + * Test a trace workload. + */ + @Test + fun testTrace() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val speed = mutableListOf() + + val duration = 5 * 60L + val workload = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + val forwarder = FlowForwarder(engine) + val adapter = FlowSourceRateAdapter(forwarder, speed::add) + source.startConsumer(adapter) + switch.addOutput(forwarder) + + val provider = switch.newInput() + provider.consume(workload) + yield() + + assertAll( + { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, + { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } + ) + } + + /** + * Test runtime workload on hypervisor. + */ + @Test + fun testRuntimeWorkload() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L * 1000 + val workload = FixedFlowSource(duration * 3.2, 1.0) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + switch.addOutput(source) + + val provider = switch.newInput() + provider.consume(workload) + yield() + + assertEquals(duration, clock.millis()) { "Took enough time" } + } + + /** + * Test two workloads running sequentially. + */ + @Test + fun testTwoWorkloads() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L * 1000 + val workload = object : FlowSource { + var isFirst = true + + override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + when (event) { + FlowEvent.Start -> isFirst = true + else -> {} + } + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + conn.push(1.0) + duration + } else { + conn.close() + Long.MAX_VALUE + } + } + } + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + switch.addOutput(source) + + val provider = switch.newInput() + provider.consume(workload) + yield() + provider.consume(workload) + assertEquals(duration * 2, clock.millis()) { "Took enough time" } + } + + /** + * Test concurrent workloads on the machine. + */ + @Test + fun testConcurrentWorkloadFails() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + switch.addOutput(source) + + switch.newInput() + assertThrows { switch.newInput() } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt new file mode 100644 index 00000000..9f6b8a2c --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.FlowSink +import org.opendc.simulator.flow.consume +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource +import org.opendc.simulator.flow.source.TraceFlowSource + +/** + * Test suite for the [FlowMultiplexer] implementations + */ +internal class MaxMinFlowMultiplexerTest { + @Test + fun testSmoke() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + val switch = MaxMinFlowMultiplexer(scheduler) + + val sources = List(2) { FlowSink(scheduler, 2000.0) } + sources.forEach { switch.addOutput(it) } + + val provider = switch.newInput() + val consumer = FixedFlowSource(2000.0, 1.0) + + try { + provider.consume(consumer) + yield() + } finally { + switch.clear() + } + } + + /** + * Test overcommitting of resources via the hypervisor with a single VM. + */ + @Test + fun testOvercommittedSingle() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L + val workload = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + + val switch = MaxMinFlowMultiplexer(scheduler) + val provider = switch.newInput() + + try { + switch.addOutput(FlowSink(scheduler, 3200.0)) + provider.consume(workload) + yield() + } finally { + switch.clear() + } + + assertAll( + { assertEquals(1113300.0, switch.counters.demand, "Requested work does not match") }, + { assertEquals(1023300.0, switch.counters.actual, "Actual work does not match") }, + { assertEquals(90000.0, switch.counters.overcommit, "Overcommitted work does not match") }, + { assertEquals(1200000, clock.millis()) } + ) + } + + /** + * Test overcommitting of resources via the hypervisor with two VMs. + */ + @Test + fun testOvercommittedDual() = runBlockingSimulation { + val scheduler = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L + val workloadA = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + val workloadB = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3100.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 73.0) + ) + ) + + val switch = MaxMinFlowMultiplexer(scheduler) + val providerA = switch.newInput() + val providerB = switch.newInput() + + try { + switch.addOutput(FlowSink(scheduler, 3200.0)) + + coroutineScope { + launch { providerA.consume(workloadA) } + providerB.consume(workloadB) + } + + yield() + } finally { + switch.clear() + } + assertAll( + { assertEquals(2073600.0, switch.counters.demand, "Requested work does not match") }, + { assertEquals(1053600.0, switch.counters.actual, "Granted work does not match") }, + { assertEquals(1020000.0, switch.counters.overcommit, "Overcommitted work does not match") }, + { assertEquals(1200000, clock.millis()) } + ) + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt deleted file mode 100644 index b503087e..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchExclusiveTest.kt +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow.mux - -import kotlinx.coroutines.yield -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.flow.* -import org.opendc.simulator.flow.internal.FlowEngineImpl -import org.opendc.simulator.flow.source.FixedFlowSource -import org.opendc.simulator.flow.source.FlowSourceRateAdapter -import org.opendc.simulator.flow.source.TraceFlowSource - -/** - * Test suite for the [ForwardingFlowMultiplexer] class. - */ -internal class SimResourceSwitchExclusiveTest { - /** - * Test a trace workload. - */ - @Test - fun testTrace() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val speed = mutableListOf() - - val duration = 5 * 60L - val workload = - TraceFlowSource( - sequenceOf( - TraceFlowSource.Fragment(duration * 1000, 28.0), - TraceFlowSource.Fragment(duration * 1000, 3500.0), - TraceFlowSource.Fragment(duration * 1000, 0.0), - TraceFlowSource.Fragment(duration * 1000, 183.0) - ), - ) - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - val forwarder = FlowForwarder(engine) - val adapter = FlowSourceRateAdapter(forwarder, speed::add) - source.startConsumer(adapter) - switch.addOutput(forwarder) - - val provider = switch.newInput() - provider.consume(workload) - yield() - - assertAll( - { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, - { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } - ) - } - - /** - * Test runtime workload on hypervisor. - */ - @Test - fun testRuntimeWorkload() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val duration = 5 * 60L * 1000 - val workload = FixedFlowSource(duration * 3.2, 1.0) - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - - switch.addOutput(source) - - val provider = switch.newInput() - provider.consume(workload) - yield() - - assertEquals(duration, clock.millis()) { "Took enough time" } - } - - /** - * Test two workloads running sequentially. - */ - @Test - fun testTwoWorkloads() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val duration = 5 * 60L * 1000 - val workload = object : FlowSource { - var isFirst = true - - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> isFirst = true - else -> {} - } - } - - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - conn.push(1.0) - duration - } else { - conn.close() - Long.MAX_VALUE - } - } - } - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - - switch.addOutput(source) - - val provider = switch.newInput() - provider.consume(workload) - yield() - provider.consume(workload) - assertEquals(duration * 2, clock.millis()) { "Took enough time" } - } - - /** - * Test concurrent workloads on the machine. - */ - @Test - fun testConcurrentWorkloadFails() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - - switch.addOutput(source) - - switch.newInput() - assertThrows { switch.newInput() } - } -} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt deleted file mode 100644 index 089a8d78..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/SimResourceSwitchMaxMinTest.kt +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow.mux - -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.yield -import org.junit.jupiter.api.* -import org.junit.jupiter.api.Assertions.assertEquals -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.flow.FlowSink -import org.opendc.simulator.flow.consume -import org.opendc.simulator.flow.internal.FlowEngineImpl -import org.opendc.simulator.flow.source.FixedFlowSource -import org.opendc.simulator.flow.source.TraceFlowSource - -/** - * Test suite for the [FlowMultiplexer] implementations - */ -internal class SimResourceSwitchMaxMinTest { - @Test - fun testSmoke() = runBlockingSimulation { - val scheduler = FlowEngineImpl(coroutineContext, clock) - val switch = MaxMinFlowMultiplexer(scheduler) - - val sources = List(2) { FlowSink(scheduler, 2000.0) } - sources.forEach { switch.addOutput(it) } - - val provider = switch.newInput() - val consumer = FixedFlowSource(2000.0, 1.0) - - try { - provider.consume(consumer) - yield() - } finally { - switch.clear() - } - } - - /** - * Test overcommitting of resources via the hypervisor with a single VM. - */ - @Test - fun testOvercommittedSingle() = runBlockingSimulation { - val scheduler = FlowEngineImpl(coroutineContext, clock) - - val duration = 5 * 60L - val workload = - TraceFlowSource( - sequenceOf( - TraceFlowSource.Fragment(duration * 1000, 28.0), - TraceFlowSource.Fragment(duration * 1000, 3500.0), - TraceFlowSource.Fragment(duration * 1000, 0.0), - TraceFlowSource.Fragment(duration * 1000, 183.0) - ), - ) - - val switch = MaxMinFlowMultiplexer(scheduler) - val provider = switch.newInput() - - try { - switch.addOutput(FlowSink(scheduler, 3200.0)) - provider.consume(workload) - yield() - } finally { - switch.clear() - } - - assertAll( - { assertEquals(1113300.0, switch.counters.demand, "Requested work does not match") }, - { assertEquals(1023300.0, switch.counters.actual, "Actual work does not match") }, - { assertEquals(90000.0, switch.counters.overcommit, "Overcommitted work does not match") }, - { assertEquals(1200000, clock.millis()) } - ) - } - - /** - * Test overcommitting of resources via the hypervisor with two VMs. - */ - @Test - fun testOvercommittedDual() = runBlockingSimulation { - val scheduler = FlowEngineImpl(coroutineContext, clock) - - val duration = 5 * 60L - val workloadA = - TraceFlowSource( - sequenceOf( - TraceFlowSource.Fragment(duration * 1000, 28.0), - TraceFlowSource.Fragment(duration * 1000, 3500.0), - TraceFlowSource.Fragment(duration * 1000, 0.0), - TraceFlowSource.Fragment(duration * 1000, 183.0) - ), - ) - val workloadB = - TraceFlowSource( - sequenceOf( - TraceFlowSource.Fragment(duration * 1000, 28.0), - TraceFlowSource.Fragment(duration * 1000, 3100.0), - TraceFlowSource.Fragment(duration * 1000, 0.0), - TraceFlowSource.Fragment(duration * 1000, 73.0) - ) - ) - - val switch = MaxMinFlowMultiplexer(scheduler) - val providerA = switch.newInput() - val providerB = switch.newInput() - - try { - switch.addOutput(FlowSink(scheduler, 3200.0)) - - coroutineScope { - launch { providerA.consume(workloadA) } - providerB.consume(workloadB) - } - - yield() - } finally { - switch.clear() - } - assertAll( - { assertEquals(2073600.0, switch.counters.demand, "Requested work does not match") }, - { assertEquals(1053600.0, switch.counters.actual, "Granted work does not match") }, - { assertEquals(1020000.0, switch.counters.overcommit, "Overcommitted work does not match") }, - { assertEquals(1200000, clock.millis()) } - ) - } -} diff --git a/opendc-simulator/opendc-simulator-network/build.gradle.kts b/opendc-simulator/opendc-simulator-network/build.gradle.kts index a8f94602..f8931053 100644 --- a/opendc-simulator/opendc-simulator-network/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-network/build.gradle.kts @@ -32,4 +32,6 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcSimulator.opendcSimulatorFlow) implementation(projects.opendcSimulator.opendcSimulatorCore) + + testImplementation(libs.slf4j.simple) } diff --git a/opendc-simulator/opendc-simulator-power/build.gradle.kts b/opendc-simulator/opendc-simulator-power/build.gradle.kts index e4342a6a..5d8c8949 100644 --- a/opendc-simulator/opendc-simulator-power/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-power/build.gradle.kts @@ -32,4 +32,6 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcSimulator.opendcSimulatorFlow) implementation(projects.opendcSimulator.opendcSimulatorCore) + + testImplementation(libs.slf4j.simple) } -- cgit v1.2.3 From 4f5a1f88d0c6aa19ce4cab0ec7b9b13a24c92fbe Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 14:45:42 +0200 Subject: refactor(simulator): Remove capacity event This change removes the Capacity entry from FlowEvent. Since the source is always pulled on a capacity change, we do not need a separate event for this. --- .../opendc/experiments/tf20/core/SimTFDevice.kt | 10 ++++------ .../kotlin/org/opendc/simulator/flow/FlowEvent.kt | 5 ----- .../flow/internal/FlowConsumerContextImpl.kt | 23 +++++----------------- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 12 ++++++++--- .../simulator/flow/source/FlowSourceRateAdapter.kt | 10 ---------- .../simulator/flow/FlowConsumerContextTest.kt | 2 +- .../org/opendc/simulator/flow/FlowForwarderTest.kt | 2 +- .../org/opendc/simulator/flow/FlowSinkTest.kt | 2 +- 8 files changed, 21 insertions(+), 45 deletions(-) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index 2ba65e90..6f460ef7 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -131,6 +131,8 @@ public class SimTFDevice( override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val consumedWork = conn.rate * delta / 1000.0 + capacity = conn.capacity + val activeWork = activeWork if (activeWork != null) { if (activeWork.consume(consumedWork)) { @@ -158,12 +160,8 @@ public class SimTFDevice( override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { when (event) { FlowEvent.Start -> { - this.ctx = conn - this.capacity = conn.capacity - } - FlowEvent.Capacity -> { - this.capacity = conn.capacity - conn.pull() + ctx = conn + capacity = conn.capacity } FlowEvent.Converge -> { _usage.record(conn.rate) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt index 14c85183..bb6f25b1 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt @@ -40,9 +40,4 @@ public enum class FlowEvent { * This event is emitted to the source when the system has converged into a steady state. */ Converge, - - /** - * This event is emitted to the source when the capacity of the consumer has changed. - */ - Capacity, } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index a74f89b4..a86ed6ea 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -51,7 +51,11 @@ internal class FlowConsumerContextImpl( // Only changes will be propagated if (value != oldValue) { field = value - onCapacityChange() + + // Do not pull the source if it has not been started yet + if (_state == State.Active) { + pull() + } } } @@ -327,23 +331,6 @@ internal class FlowConsumerContextImpl( } } - /** - * Indicate that the capacity of the resource has changed. - */ - private fun onCapacityChange() { - // Do not inform the consumer if it has not been started yet - if (_state != State.Active) { - return - } - - engine.batch { - // Inform the consumer of the capacity change. This might already trigger an interrupt. - source.onEvent(this, _clock.millis(), FlowEvent.Capacity) - - pull() - } - } - /** * Schedule an immediate update for this connection. */ diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index a3e108f6..b98cf2f1 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -356,8 +356,7 @@ public class MaxMinFlowMultiplexer( /** * The capacity of this output. */ - val capacity: Double - get() = _ctx?.capacity ?: 0.0 + @JvmField var capacity: Double = 0.0 /** * Push the specified rate to the consumer. @@ -374,6 +373,12 @@ public class MaxMinFlowMultiplexer( } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val capacity = capacity + if (capacity != conn.capacity) { + this.capacity = capacity + updateCapacity() + } + runScheduler(now) return Long.MAX_VALUE } @@ -383,13 +388,14 @@ public class MaxMinFlowMultiplexer( FlowEvent.Start -> { assert(_ctx == null) { "Source running concurrently" } _ctx = conn + capacity = conn.capacity updateCapacity() } FlowEvent.Exit -> { _ctx = null + capacity = 0.0 updateCapacity() } - FlowEvent.Capacity -> updateCapacity() else -> {} } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt index fcee3906..24ae64cb 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt @@ -25,7 +25,6 @@ package org.opendc.simulator.flow.source import org.opendc.simulator.flow.FlowConnection import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource -import kotlin.math.min /** * Helper class to expose an observable [rate] field describing the flow rate of the source. @@ -59,20 +58,11 @@ public class FlowSourceRateAdapter( } override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - val oldSpeed = rate - try { delegate.onEvent(conn, now, event) when (event) { FlowEvent.Converge -> rate = conn.rate - FlowEvent.Capacity -> { - // Check if the consumer interrupted the consumer and updated the resource consumption. If not, we might - // need to update the current speed. - if (oldSpeed == rate) { - rate = min(conn.capacity, rate) - } - } FlowEvent.Exit -> rate = 0.0 else -> {} } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt index f1a5cbe4..fe39eb2c 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowConsumerContextTest.kt @@ -99,6 +99,6 @@ class FlowConsumerContextTest { context.start() context.capacity = 4200.0 - verify(exactly = 0) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } + verify(exactly = 1) { consumer.onPull(any(), any(), any()) } } } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt index d125c638..7fae918a 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt @@ -197,7 +197,7 @@ internal class FlowForwarderTest { } assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } + verify(exactly = 1) { consumer.onPull(any(), any(), any()) } } @Test diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt index 010a985e..5d579e5d 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt @@ -67,7 +67,7 @@ internal class FlowSinkTest { provider.capacity = 0.5 } assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Capacity) } + verify(exactly = 1) { consumer.onPull(any(), any(), any()) } } @Test -- cgit v1.2.3 From a2ce07026bf3ef17326e72f395dfa2dd9d9b17be Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 15:37:35 +0200 Subject: refactor(simulator): Create separate callbacks for remaining events This change creates separate callbacks for the remaining events: onStart, onStop and onConverge. --- .../opendc/experiments/tf20/core/SimTFDevice.kt | 20 +++---- .../org/opendc/simulator/compute/device/SimPsu.kt | 18 +++--- .../compute/workload/SimWorkloadLifecycle.kt | 24 ++------ .../org/opendc/simulator/flow/FlowConsumer.kt | 30 ++++++++-- .../kotlin/org/opendc/simulator/flow/FlowEvent.kt | 43 -------------- .../org/opendc/simulator/flow/FlowForwarder.kt | 65 ++++++++++++---------- .../kotlin/org/opendc/simulator/flow/FlowSource.kt | 25 +++++++-- .../flow/internal/FlowConsumerContextImpl.kt | 53 +++++++++++------- .../flow/mux/ForwardingFlowMultiplexer.kt | 9 +-- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 30 +++++----- .../simulator/flow/source/FlowSourceRateAdapter.kt | 29 ++++------ .../simulator/flow/source/TraceFlowSource.kt | 25 ++++----- .../org/opendc/simulator/flow/FlowForwarderTest.kt | 39 +++++++------ .../org/opendc/simulator/flow/FlowSinkTest.kt | 25 +++++---- .../flow/mux/ExclusiveFlowMultiplexerTest.kt | 7 +-- .../opendc/simulator/network/SimNetworkSinkTest.kt | 4 +- .../network/SimNetworkSwitchVirtualTest.kt | 2 +- .../org/opendc/simulator/power/SimPduTest.kt | 3 +- .../opendc/simulator/power/SimPowerSourceTest.kt | 3 +- .../org/opendc/simulator/power/SimUpsTest.kt | 3 +- 20 files changed, 214 insertions(+), 243 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index 6f460ef7..017bca59 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -128,6 +128,11 @@ public class SimTFDevice( } } + override fun onStart(conn: FlowConnection, now: Long) { + ctx = conn + capacity = conn.capacity + } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val consumedWork = conn.rate * delta / 1000.0 @@ -157,18 +162,9 @@ public class SimTFDevice( } } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> { - ctx = conn - capacity = conn.capacity - } - FlowEvent.Converge -> { - _usage.record(conn.rate) - _power.record(machine.psu.powerDraw) - } - else -> {} - } + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + _usage.record(conn.rate) + _power.record(machine.psu.powerDraw) } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index b05d8ad9..8400c225 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.compute.device import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.flow.FlowConnection -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource import org.opendc.simulator.power.SimPowerInlet import java.util.* @@ -82,19 +81,22 @@ public class SimPsu( } override fun createConsumer(): FlowSource = object : FlowSource { + override fun onStart(conn: FlowConnection, now: Long) { + _ctx = conn + } + + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + _ctx = null + } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val powerDraw = computePowerDraw(_driver?.computePower() ?: 0.0) conn.push(powerDraw) return Long.MAX_VALUE } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> _ctx = conn - FlowEvent.Converge -> _powerDraw = conn.rate - FlowEvent.Exit -> _ctx = null - else -> {} - } + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + _powerDraw = conn.rate } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt index b85be39d..cc4f1f6a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.flow.FlowConnection -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource /** @@ -41,29 +40,14 @@ public class SimWorkloadLifecycle(private val ctx: SimMachineContext) { */ public fun waitFor(consumer: FlowSource): FlowSource { waiting.add(consumer) - return object : FlowSource { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - return try { - consumer.onPull(conn, now, delta) - } catch (cause: Throwable) { - complete(consumer) - throw cause - } - } - - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + return object : FlowSource by consumer { + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { try { - consumer.onEvent(conn, now, event) - - if (event == FlowEvent.Exit) { - complete(consumer) - } - } catch (cause: Throwable) { + consumer.onStop(conn, now, delta) + } finally { complete(consumer) - throw cause } } - override fun toString(): String = "SimWorkloadLifecycle.Consumer[delegate=$consumer]" } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt index df2c4fab..4685a755 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumer.kt @@ -83,20 +83,20 @@ public interface FlowConsumer { public suspend fun FlowConsumer.consume(source: FlowSource) { return suspendCancellableCoroutine { cont -> startConsumer(object : FlowSource { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - return try { - source.onPull(conn, now, delta) + override fun onStart(conn: FlowConnection, now: Long) { + try { + source.onStart(conn, now) } catch (cause: Throwable) { cont.resumeWithException(cause) throw cause } } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { try { - source.onEvent(conn, now, event) + source.onStop(conn, now, delta) - if (event == FlowEvent.Exit && !cont.isCompleted) { + if (!cont.isCompleted) { cont.resume(Unit) } } catch (cause: Throwable) { @@ -105,6 +105,24 @@ public suspend fun FlowConsumer.consume(source: FlowSource) { } } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return try { + source.onPull(conn, now, delta) + } catch (cause: Throwable) { + cont.resumeWithException(cause) + throw cause + } + } + + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + try { + source.onConverge(conn, now, delta) + } catch (cause: Throwable) { + cont.resumeWithException(cause) + throw cause + } + } + override fun toString(): String = "SuspendingFlowSource" }) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt deleted file mode 100644 index bb6f25b1..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowEvent.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow - -/** - * A flow event that is communicated to a [FlowSource]. - */ -public enum class FlowEvent { - /** - * This event is emitted to the source when it has started. - */ - Start, - - /** - * This event is emitted to the source when it is stopped. - */ - Exit, - - /** - * This event is emitted to the source when the system has converged into a steady state. - */ - Converge, -} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index bc01a11b..ab5b31c2 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -24,6 +24,7 @@ package org.opendc.simulator.flow import mu.KotlinLogging import org.opendc.simulator.flow.internal.FlowCountersImpl +import kotlin.math.max /** * A class that acts as a [FlowSource] and [FlowConsumer] at the same time. @@ -64,6 +65,8 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled _innerCtx?.pull() } + @JvmField var lastPull = Long.MAX_VALUE + override fun push(rate: Double) { if (delegate == null) { return @@ -82,7 +85,9 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled reset() if (hasDelegateStarted) { - delegate.onEvent(this, engine.clock.millis(), FlowEvent.Exit) + val now = engine.clock.millis() + val delta = max(0, now - lastPull) + delegate.onStop(this, now, delta) } } } @@ -134,6 +139,25 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled } } + override fun onStart(conn: FlowConnection, now: Long) { + _innerCtx = conn + } + + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + _innerCtx = null + + val delegate = delegate + if (delegate != null) { + reset() + + try { + delegate.onStop(this._ctx, now, delta) + } catch (cause: Throwable) { + logger.error(cause) { "Uncaught exception" } + } + } + } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val delegate = delegate @@ -141,10 +165,11 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled start() } + _ctx.lastPull = now updateCounters(conn, delta) return try { - delegate?.onPull(this._ctx, now, delta) ?: Long.MAX_VALUE + delegate?.onPull(_ctx, now, delta) ?: Long.MAX_VALUE } catch (cause: Throwable) { logger.error(cause) { "Uncaught exception" } @@ -153,32 +178,14 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled } } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> _innerCtx = conn - FlowEvent.Exit -> { - _innerCtx = null - - val delegate = delegate - if (delegate != null) { - reset() - - try { - delegate.onEvent(this._ctx, now, FlowEvent.Exit) - } catch (cause: Throwable) { - logger.error(cause) { "Uncaught exception" } - } - } - } - else -> - try { - delegate?.onEvent(this._ctx, now, event) - } catch (cause: Throwable) { - logger.error(cause) { "Uncaught exception" } - - _innerCtx = null - reset() - } + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + try { + delegate?.onConverge(this._ctx, now, delta) + } catch (cause: Throwable) { + logger.error(cause) { "Uncaught exception" } + + _innerCtx = null + reset() } } @@ -189,7 +196,7 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled val delegate = delegate ?: return try { - delegate.onEvent(_ctx, engine.clock.millis(), FlowEvent.Start) + delegate.onStart(_ctx, engine.clock.millis()) hasDelegateStarted = true } catch (cause: Throwable) { logger.error(cause) { "Uncaught exception" } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt index 70687b4f..a4f624ef 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt @@ -29,6 +29,23 @@ package org.opendc.simulator.flow * (concurrently) for multiple [FlowConsumer]s, unless explicitly said otherwise. */ public interface FlowSource { + /** + * This method is invoked when the source is started. + * + * @param conn The connection between the source and consumer. + * @param now The virtual timestamp in milliseconds at which the provider finished. + */ + public fun onStart(conn: FlowConnection, now: Long) {} + + /** + * This method is invoked when the source is finished. + * + * @param conn The connection between the source and consumer. + * @param now The virtual timestamp in milliseconds at which the source finished. + * @param delta The virtual duration between this call and the last call to [onPull] in milliseconds. + */ + public fun onStop(conn: FlowConnection, now: Long, delta: Long) {} + /** * This method is invoked when the source is pulled. * @@ -40,11 +57,11 @@ public interface FlowSource { public fun onPull(conn: FlowConnection, now: Long, delta: Long): Long /** - * This method is invoked when an event has occurred. + * This method is invoked when the flow graph has converged into a steady-state system. * * @param conn The connection between the source and consumer. - * @param now The virtual timestamp in milliseconds at which the event is occurring. - * @param event The event that has occurred. + * @param now The virtual timestamp in milliseconds at which the system converged. + * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. */ - public fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) {} + public fun onConverge(conn: FlowConnection, now: Long, delta: Long) {} } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index a86ed6ea..c235b9ae 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -125,7 +125,7 @@ internal class FlowConsumerContextImpl( override fun start() { check(_state == State.Pending) { "Consumer is already started" } engine.batch { - source.onEvent(this, _clock.millis(), FlowEvent.Start) + source.onStart(this, _clock.millis()) _state = State.Active pull() } @@ -140,8 +140,7 @@ internal class FlowConsumerContextImpl( _state = State.Closed if (!_isUpdateActive) { val now = _clock.millis() - val delta = max(0, now - _lastPull) - doStopSource(now, delta) + doStopSource(now) // FIX: Make sure the context converges pull() @@ -210,19 +209,16 @@ internal class FlowConsumerContextImpl( _isUpdateActive = true _isImmediateUpdateScheduled = false - val lastPush = _lastPush - val pushDelta = max(0, now - lastPush) - try { // Pull the source if (1) `pull` is called or (2) the timer of the source has expired val deadline = if (_isPulled || _deadline == now) { val lastPull = _lastPull - val pullDelta = max(0, now - lastPull) + val delta = max(0, now - lastPull) _isPulled = false _lastPull = now - val duration = source.onPull(this, now, pullDelta) + val duration = source.onPull(this, now, delta) if (duration != Long.MAX_VALUE) now + duration else @@ -236,12 +232,15 @@ internal class FlowConsumerContextImpl( State.Active -> { val demand = _demand if (demand != _activeDemand) { + val lastPush = _lastPush + val delta = max(0, now - lastPush) + _lastPush = now - logic.onPush(this, now, pushDelta, demand) + logic.onPush(this, now, delta, demand) } } - State.Closed -> doStopSource(now, pushDelta) + State.Closed -> doStopSource(now) State.Pending -> throw IllegalStateException("Illegal transition to pending state") } @@ -256,7 +255,7 @@ internal class FlowConsumerContextImpl( // Schedule an update at the new deadline scheduleDelayed(now, deadline) } catch (cause: Throwable) { - doFailSource(now, pushDelta, cause) + doFailSource(now, cause) } finally { _isUpdateActive = false } @@ -293,12 +292,12 @@ internal class FlowConsumerContextImpl( try { if (_state == State.Active) { - source.onEvent(this, timestamp, FlowEvent.Converge) + source.onConverge(this, timestamp, delta) } logic.onConverge(this, timestamp, delta) } catch (cause: Throwable) { - doFailSource(timestamp, max(0, timestamp - _lastPull), cause) + doFailSource(timestamp, cause) } } @@ -307,12 +306,13 @@ internal class FlowConsumerContextImpl( /** * Stop the [FlowSource]. */ - private fun doStopSource(now: Long, delta: Long) { + private fun doStopSource(now: Long) { try { - source.onEvent(this, now, FlowEvent.Exit) - logic.onFinish(this, now, delta, null) + source.onStop(this, now, max(0, now - _lastPull)) + doFinishConsumer(now, null) } catch (cause: Throwable) { - doFailSource(now, delta, cause) + doFinishConsumer(now, cause) + return } finally { _deadline = Long.MAX_VALUE _demand = 0.0 @@ -322,9 +322,24 @@ internal class FlowConsumerContextImpl( /** * Fail the [FlowSource]. */ - private fun doFailSource(now: Long, delta: Long, cause: Throwable) { + private fun doFailSource(now: Long, cause: Throwable) { + try { + source.onStop(this, now, max(0, now - _lastPull)) + } catch (e: Throwable) { + e.addSuppressed(cause) + doFinishConsumer(now, e) + } finally { + _deadline = Long.MAX_VALUE + _demand = 0.0 + } + } + + /** + * Finish the consumer. + */ + private fun doFinishConsumer(now: Long, cause: Throwable?) { try { - logic.onFinish(this, now, delta, cause) + logic.onFinish(this, now, max(0, now - _lastPush), cause) } catch (e: Throwable) { e.addSuppressed(cause) logger.error(e) { "Uncaught exception" } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt index 811d9460..6dd9dcfb 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt @@ -88,13 +88,10 @@ public class ForwardingFlowMultiplexer(private val engine: FlowEngine) : FlowMul _availableOutputs += forwarder output.startConsumer(object : FlowSource by forwarder { - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - if (event == FlowEvent.Exit) { - // De-register the output after it has finished - _outputs -= output - } + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + _outputs -= output - forwarder.onEvent(conn, now, event) + forwarder.onStop(conn, now, delta) } }) } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index b98cf2f1..c7379fa9 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -372,6 +372,19 @@ public class MaxMinFlowMultiplexer( provider.cancel() } + override fun onStart(conn: FlowConnection, now: Long) { + assert(_ctx == null) { "Source running concurrently" } + _ctx = conn + capacity = conn.capacity + updateCapacity() + } + + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + _ctx = null + capacity = 0.0 + updateCapacity() + } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val capacity = capacity if (capacity != conn.capacity) { @@ -383,23 +396,6 @@ public class MaxMinFlowMultiplexer( return Long.MAX_VALUE } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> { - assert(_ctx == null) { "Source running concurrently" } - _ctx = conn - capacity = conn.capacity - updateCapacity() - } - FlowEvent.Exit -> { - _ctx = null - capacity = 0.0 - updateCapacity() - } - else -> {} - } - } - override fun compareTo(other: Output): Int = capacity.compareTo(other.capacity) } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt index 24ae64cb..0c39523f 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.flow.source import org.opendc.simulator.flow.FlowConnection -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource /** @@ -48,28 +47,22 @@ public class FlowSourceRateAdapter( callback(0.0) } - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - return try { - delegate.onPull(conn, now, delta) - } catch (cause: Throwable) { + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + try { + delegate.onStop(conn, now, delta) + } finally { rate = 0.0 - throw cause } } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - try { - delegate.onEvent(conn, now, event) + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return delegate.onPull(conn, now, delta) + } - when (event) { - FlowEvent.Converge -> rate = conn.rate - FlowEvent.Exit -> rate = 0.0 - else -> {} - } - } catch (cause: Throwable) { - rate = 0.0 - throw cause - } + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + delegate.onConverge(conn, now, delta) + + rate = conn.rate } override fun toString(): String = "FlowSourceRateAdapter[delegate=$delegate]" diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt index 4d3ae61a..ae537845 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/TraceFlowSource.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.flow.source import org.opendc.simulator.flow.FlowConnection -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource /** @@ -33,6 +32,15 @@ public class TraceFlowSource(private val trace: Sequence) : FlowSource private var _iterator: Iterator? = null private var _nextTarget = Long.MIN_VALUE + override fun onStart(conn: FlowConnection, now: Long) { + check(_iterator == null) { "Source already running" } + _iterator = trace.iterator() + } + + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + _iterator = null + } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { // Check whether the trace fragment was fully consumed, otherwise wait until we have done so val nextTarget = _nextTarget @@ -52,21 +60,8 @@ public class TraceFlowSource(private val trace: Sequence) : FlowSource } } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> { - check(_iterator == null) { "Source already running" } - _iterator = trace.iterator() - } - FlowEvent.Exit -> { - _iterator = null - } - else -> {} - } - } - /** - * A fragment of the tgrace. + * A fragment of the trace. */ public data class Fragment(val duration: Long, val usage: Double) } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt index 7fae918a..3690e681 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt @@ -22,10 +22,10 @@ package org.opendc.simulator.flow -import io.mockk.spyk -import io.mockk.verify +import io.mockk.* import kotlinx.coroutines.* import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation @@ -122,7 +122,7 @@ internal class FlowForwarderTest { forwarder.startConsumer(consumer) forwarder.cancel() - verify(exactly = 0) { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify(exactly = 0) { consumer.onStop(any(), any(), any()) } } @Test @@ -139,8 +139,8 @@ internal class FlowForwarderTest { yield() forwarder.cancel() - verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Start) } - verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify(exactly = 1) { consumer.onStart(any(), any()) } + verify(exactly = 1) { consumer.onStop(any(), any(), any()) } } @Test @@ -157,8 +157,8 @@ internal class FlowForwarderTest { yield() source.cancel() - verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Start) } - verify(exactly = 1) { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify(exactly = 1) { consumer.onStart(any(), any()) } + verify(exactly = 1) { consumer.onStop(any(), any(), any()) } } @Test @@ -182,22 +182,23 @@ internal class FlowForwarderTest { } @Test + @Disabled // Due to Kotlin bug: https://github.com/mockk/mockk/issues/368 fun testAdjustCapacity() = runBlockingSimulation { val engine = FlowEngineImpl(coroutineContext, clock) val forwarder = FlowForwarder(engine) - val source = FlowSink(engine, 1.0) + val sink = FlowSink(engine, 1.0) - val consumer = spyk(FixedFlowSource(2.0, 1.0)) - source.startConsumer(forwarder) + val source = spyk(FixedFlowSource(2.0, 1.0)) + sink.startConsumer(forwarder) coroutineScope { - launch { forwarder.consume(consumer) } + launch { forwarder.consume(source) } delay(1000) - source.capacity = 0.5 + sink.capacity = 0.5 } assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onPull(any(), any(), any()) } + verify(exactly = 1) { source.onPull(any(), any(), any()) } } @Test @@ -259,7 +260,7 @@ internal class FlowForwarderTest { } @Test - fun testEventFailure() = runBlockingSimulation { + fun testStartFailure() = runBlockingSimulation { val engine = FlowEngineImpl(coroutineContext, clock) val forwarder = FlowForwarder(engine) val source = FlowSink(engine, 2000.0) @@ -272,7 +273,7 @@ internal class FlowForwarderTest { return Long.MAX_VALUE } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + override fun onStart(conn: FlowConnection, now: Long) { throw IllegalStateException("Test") } }) @@ -287,7 +288,7 @@ internal class FlowForwarderTest { } @Test - fun testEventConvergeFailure() = runBlockingSimulation { + fun testConvergeFailure() = runBlockingSimulation { val engine = FlowEngineImpl(coroutineContext, clock) val forwarder = FlowForwarder(engine) val source = FlowSink(engine, 2000.0) @@ -300,10 +301,8 @@ internal class FlowForwarderTest { return Long.MAX_VALUE } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - if (event == FlowEvent.Converge) { - throw IllegalStateException("Test") - } + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + throw IllegalStateException("Test") } }) } catch (cause: Throwable) { diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt index 5d579e5d..70c75864 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowSinkTest.kt @@ -22,8 +22,6 @@ package org.opendc.simulator.flow -import io.mockk.every -import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.* @@ -67,7 +65,7 @@ internal class FlowSinkTest { provider.capacity = 0.5 } assertEquals(3000, clock.millis()) - verify(exactly = 1) { consumer.onPull(any(), any(), any()) } + verify(exactly = 3) { consumer.onPull(any(), any(), any()) } } @Test @@ -102,7 +100,7 @@ internal class FlowSinkTest { return Long.MAX_VALUE } - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { + override fun onStart(conn: FlowConnection, now: Long) { conn.pull() } } @@ -120,11 +118,8 @@ internal class FlowSinkTest { val consumer = object : FlowSource { var isFirst = true - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> resCtx = conn - else -> {} - } + override fun onStart(conn: FlowConnection, now: Long) { + resCtx = conn } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { @@ -154,9 +149,15 @@ internal class FlowSinkTest { val capacity = 4200.0 val provider = FlowSink(engine, capacity) - val consumer = mockk(relaxUnitFun = true) - every { consumer.onEvent(any(), any(), eq(FlowEvent.Start)) } - .throws(IllegalStateException()) + val consumer = object : FlowSource { + override fun onStart(conn: FlowConnection, now: Long) { + throw IllegalStateException("Hi") + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return Long.MAX_VALUE + } + } assertThrows { provider.consume(consumer) diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt index c8627446..3475f027 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt @@ -108,11 +108,8 @@ internal class ExclusiveFlowMultiplexerTest { val workload = object : FlowSource { var isFirst = true - override fun onEvent(conn: FlowConnection, now: Long, event: FlowEvent) { - when (event) { - FlowEvent.Start -> isFirst = true - else -> {} - } + override fun onStart(conn: FlowConnection, now: Long) { + isFirst = true } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt index 45d0bcf0..14d22162 100644 --- a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt @@ -108,7 +108,7 @@ class SimNetworkSinkTest { assertTrue(source.isConnected) verify { source.createConsumer() } - verify { consumer.onEvent(any(), any(), FlowEvent.Start) } + verify { consumer.onStart(any(), any()) } } @Test @@ -124,7 +124,7 @@ class SimNetworkSinkTest { assertFalse(sink.isConnected) assertFalse(source.isConnected) - verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify { consumer.onStop(any(), any(), any()) } } private class Source(engine: FlowEngine) : SimNetworkPort() { diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt index 4aa2fa92..62e54ffb 100644 --- a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt @@ -50,7 +50,7 @@ class SimNetworkSwitchVirtualTest { assertTrue(source.isConnected) verify { source.createConsumer() } - verify { consumer.onEvent(any(), any(), FlowEvent.Start) } + verify { consumer.onStart(any(), any()) } } @Test diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt index ff447703..85b9ab01 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt @@ -30,7 +30,6 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource import org.opendc.simulator.flow.source.FixedFlowSource @@ -87,7 +86,7 @@ internal class SimPduTest { outlet.connect(inlet) outlet.disconnect() - verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify { consumer.onStop(any(), any(), any()) } } @Test diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt index b411e292..20677633 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt @@ -32,7 +32,6 @@ import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource import org.opendc.simulator.flow.source.FixedFlowSource @@ -86,7 +85,7 @@ internal class SimPowerSourceTest { source.connect(inlet) source.disconnect() - verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify { consumer.onStop(any(), any(), any()) } } @Test diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt index 31ac0b39..c6e0605a 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt @@ -29,7 +29,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowEvent import org.opendc.simulator.flow.FlowSource import org.opendc.simulator.flow.source.FixedFlowSource @@ -93,7 +92,7 @@ internal class SimUpsTest { ups.connect(inlet) ups.disconnect() - verify { consumer.onEvent(any(), any(), FlowEvent.Exit) } + verify { consumer.onStop(any(), any(), any()) } } class SimpleInlet : SimPowerInlet() { -- cgit v1.2.3 From 94783ff9d8cd81275fefd5804ac99f98e2dee3a4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 16:00:05 +0200 Subject: fix(simulator): Fix loss computation for UPS and PDU This change fixes the loss computation for both the UPS and PDU implementation that was broken due to the new pushing mechanism. We implement a new class FlowMapper that can be used to map the flow pushed by a `FlowSource` using a user-specified method. --- .../org/opendc/simulator/compute/device/SimPsu.kt | 2 +- .../kotlin/org/opendc/simulator/flow/FlowMapper.kt | 75 ++++++++++++++++++++++ .../flow/internal/FlowConsumerContextImpl.kt | 1 + .../kotlin/org/opendc/simulator/power/SimPdu.kt | 16 ++--- .../org/opendc/simulator/power/SimPowerInlet.kt | 2 +- .../org/opendc/simulator/power/SimPowerSource.kt | 2 +- .../kotlin/org/opendc/simulator/power/SimUps.kt | 18 ++---- .../org/opendc/simulator/power/SimPduTest.kt | 6 +- .../opendc/simulator/power/SimPowerSourceTest.kt | 6 +- .../org/opendc/simulator/power/SimUpsTest.kt | 4 +- 10 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index 8400c225..62d91c0b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -80,7 +80,7 @@ public class SimPsu( update() } - override fun createConsumer(): FlowSource = object : FlowSource { + override fun createSource(): FlowSource = object : FlowSource { override fun onStart(conn: FlowConnection, now: Long) { _ctx = conn } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt new file mode 100644 index 00000000..6867bcef --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A [FlowConsumer] that maps the pushed flow through [transform]. + * + * @param source The source of the flow. + * @param transform The method to transform the flow. + */ +public class FlowMapper( + private val source: FlowSource, + private val transform: (FlowConnection, Double) -> Double +) : FlowSource { + + /** + * The current active connection. + */ + private var _conn: Connection? = null + + override fun onStart(conn: FlowConnection, now: Long) { + check(_conn == null) { "Concurrent access" } + val delegate = Connection(conn, transform) + _conn = delegate + source.onStart(delegate, now) + } + + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + val delegate = checkNotNull(_conn) { "Invariant violation" } + _conn = null + source.onStop(delegate, now, delta) + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val delegate = checkNotNull(_conn) { "Invariant violation" } + return source.onPull(delegate, now, delta) + } + + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + val delegate = _conn ?: return + source.onConverge(delegate, now, delta) + } + + /** + * The wrapper [FlowConnection] that is used to transform the flow. + */ + private class Connection( + private val delegate: FlowConnection, + private val transform: (FlowConnection, Double) -> Double + ) : FlowConnection by delegate { + override fun push(rate: Double) { + delegate.push(transform(this, rate)) + } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index c235b9ae..55fa92df 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -127,6 +127,7 @@ internal class FlowConsumerContextImpl( engine.batch { source.onStart(this, _clock.millis()) _state = State.Active + pull() } } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index c33f5186..d536f22d 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -57,17 +57,9 @@ public class SimPdu( mux.addOutput(forwarder) } - override fun createConsumer(): FlowSource = object : FlowSource by forwarder { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - val duration = forwarder.onPull(conn, now, delta) - val loss = computePowerLoss(conn.demand) - val newLimit = conn.demand + loss - - conn.push(newLimit) - return duration - } - - override fun toString(): String = "SimPdu.Consumer" + override fun createSource(): FlowSource = FlowMapper(forwarder) { _, rate -> + val loss = computePowerLoss(rate) + rate + loss } override fun toString(): String = "SimPdu" @@ -85,7 +77,7 @@ public class SimPdu( */ public class Outlet(private val switch: FlowMultiplexer, private val provider: FlowConsumer) : SimPowerOutlet(), AutoCloseable { override fun onConnect(inlet: SimPowerInlet) { - provider.startConsumer(inlet.createConsumer()) + provider.startConsumer(inlet.createSource()) } override fun onDisconnect(inlet: SimPowerInlet) { diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt index 851b28a5..de587b7f 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt @@ -44,5 +44,5 @@ public abstract class SimPowerInlet { /** * Create a [FlowSource] which represents the consumption of electricity from the power outlet. */ - public abstract fun createConsumer(): FlowSource + public abstract fun createSource(): FlowSource } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt index 7faebd75..07e9f52e 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt @@ -43,7 +43,7 @@ public class SimPowerSource(engine: FlowEngine, public val capacity: Double) : S get() = source.rate override fun onConnect(inlet: SimPowerInlet) { - source.startConsumer(inlet.createConsumer()) + source.startConsumer(inlet.createSource()) } override fun onDisconnect(inlet: SimPowerInlet) { diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 5eaa91af..312f1d0f 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -59,17 +59,13 @@ public class SimUps( } override fun onConnect(inlet: SimPowerInlet) { - val consumer = inlet.createConsumer() - provider.startConsumer(object : FlowSource by consumer { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - val duration = consumer.onPull(conn, now, delta) - val loss = computePowerLoss(conn.demand) - val newLimit = conn.demand + loss + val source = inlet.createSource() + val mapper = FlowMapper(source) { _, rate -> + val loss = computePowerLoss(rate) + rate + loss + } - conn.push(newLimit) - return duration - } - }) + provider.startConsumer(mapper) } override fun onDisconnect(inlet: SimPowerInlet) { @@ -88,7 +84,7 @@ public class SimUps( * A UPS inlet. */ public inner class Inlet(private val forwarder: FlowForwarder) : SimPowerInlet(), AutoCloseable { - override fun createConsumer(): FlowSource = forwarder + override fun createSource(): FlowSource = forwarder /** * Remove the inlet from the PSU. diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt index 85b9ab01..eb823eb1 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt @@ -25,7 +25,6 @@ package org.opendc.simulator.power import io.mockk.spyk import io.mockk.verify import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation @@ -79,7 +78,7 @@ internal class SimPduTest { source.connect(pdu) val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): FlowSource = consumer + override fun createSource(): FlowSource = consumer } val outlet = pdu.newOutlet() @@ -90,7 +89,6 @@ internal class SimPduTest { } @Test - @Disabled fun testLoss() = runBlockingSimulation { val engine = FlowEngine(coroutineContext, clock) val source = SimPowerSource(engine, capacity = 100.0) @@ -116,6 +114,6 @@ internal class SimPduTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) + override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) } } diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt index 20677633..76142103 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt @@ -79,7 +79,7 @@ internal class SimPowerSourceTest { val source = SimPowerSource(engine, capacity = 100.0) val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): FlowSource = consumer + override fun createSource(): FlowSource = consumer } source.connect(inlet) @@ -95,7 +95,7 @@ internal class SimPowerSourceTest { val inlet = mockk(relaxUnitFun = true) every { inlet.isConnected } returns false every { inlet._outlet } returns null - every { inlet.createConsumer() } returns FixedFlowSource(100.0, utilization = 1.0) + every { inlet.createSource() } returns FixedFlowSource(100.0, utilization = 1.0) source.connect(inlet) @@ -131,6 +131,6 @@ internal class SimPowerSourceTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 1.0) + override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 1.0) } } diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt index c6e0605a..a764a368 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt @@ -86,7 +86,7 @@ internal class SimUpsTest { source2.connect(ups.newInlet()) val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): FlowSource = consumer + override fun createSource(): FlowSource = consumer } ups.connect(inlet) @@ -96,6 +96,6 @@ internal class SimUpsTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) + override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) } } -- cgit v1.2.3 From 559ac2327b8aa319fb8ab4558d4f4aa3382349f4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 16:27:45 +0200 Subject: perf(simulator): Make convergence callback optional This change adds two new properties for controlling whether the convergence callbacks of the source and consumer respectively should be invoked. This saves a lot of unnecessary calls for stages that do not have any implementation of the `onConvergence` method. --- .../opendc/experiments/tf20/core/SimTFDevice.kt | 2 + .../opendc/simulator/compute/SimAbstractMachine.kt | 8 +++- .../simulator/compute/SimBareMetalMachine.kt | 4 +- .../org/opendc/simulator/compute/device/SimPsu.kt | 1 + .../compute/kernel/SimAbstractHypervisor.kt | 2 - .../compute/kernel/SimFairShareHypervisor.kt | 16 ++++---- .../kernel/SimFairShareHypervisorProvider.kt | 4 +- .../compute/kernel/SimHypervisorProvider.kt | 4 +- .../kernel/SimSpaceSharedHypervisorProvider.kt | 4 +- .../org/opendc/simulator/flow/FlowConnection.kt | 5 +++ .../opendc/simulator/flow/FlowConsumerContext.kt | 5 +++ .../org/opendc/simulator/flow/FlowConsumerLogic.kt | 3 ++ .../simulator/flow/FlowConvergenceListener.kt | 36 ++++++++++++++++++ .../org/opendc/simulator/flow/FlowForwarder.kt | 10 +++++ .../kotlin/org/opendc/simulator/flow/FlowSink.kt | 11 +++++- .../kotlin/org/opendc/simulator/flow/FlowSource.kt | 3 ++ .../kotlin/org/opendc/simulator/flow/FlowSystem.kt | 43 ---------------------- .../flow/internal/FlowConsumerContextImpl.kt | 39 +++++++++++++++----- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 9 ++++- .../simulator/flow/source/FlowSourceRateAdapter.kt | 14 +++++-- .../org/opendc/simulator/flow/FlowForwarderTest.kt | 4 ++ 21 files changed, 147 insertions(+), 80 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConvergenceListener.kt delete mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index 017bca59..fb36d2c7 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -131,6 +131,8 @@ public class SimTFDevice( override fun onStart(conn: FlowConnection, now: Long) { ctx = conn capacity = conn.capacity + + conn.shouldSourceConverge = true } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index 6a62d8a5..60a10f20 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -43,9 +43,9 @@ import kotlin.coroutines.resume */ public abstract class SimAbstractMachine( protected val engine: FlowEngine, - final override val parent: FlowSystem?, + private val parent: FlowConvergenceListener?, final override val model: MachineModel -) : SimMachine, FlowSystem { +) : SimMachine, FlowConvergenceListener { /** * The resources allocated for this machine. */ @@ -116,6 +116,10 @@ public abstract class SimAbstractMachine( cancel() } + override fun onConverge(now: Long, delta: Long) { + parent?.onConverge(now, delta) + } + /** * Cancel the workload that is currently running on the machine. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt index 37cf282b..0bcf5957 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt @@ -46,7 +46,7 @@ public class SimBareMetalMachine( model: MachineModel, powerDriver: PowerDriver, public val psu: SimPsu = SimPsu(500.0, mapOf(1.0 to 1.0)), - parent: FlowSystem? = null, + parent: FlowConvergenceListener? = null, ) : SimAbstractMachine(engine, parent, model) { /** * The power draw of the machine onto the PSU. @@ -66,7 +66,7 @@ public class SimBareMetalMachine( */ private val powerDriverLogic = powerDriver.createLogic(this, cpus) - override fun onConverge(timestamp: Long) { + override fun onConverge(now: Long, delta: Long) { psu.update() } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index 62d91c0b..09defbb5 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -83,6 +83,7 @@ public class SimPsu( override fun createSource(): FlowSource = object : FlowSource { override fun onStart(conn: FlowConnection, now: Long) { _ctx = conn + conn.shouldSourceConverge = true } override fun onStop(conn: FlowConnection, now: Long, delta: Long) { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index b145eefc..bcba8e8e 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -145,8 +145,6 @@ public abstract class SimAbstractHypervisor( interferenceDomain?.leave(interferenceKey) } } - - override fun onConverge(timestamp: Long) {} } /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index 36ab7c1c..b0515c6e 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -28,8 +28,8 @@ import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.simulator.flow.FlowConvergenceListener import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowSystem import org.opendc.simulator.flow.mux.FlowMultiplexer import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer @@ -45,7 +45,7 @@ import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer */ public class SimFairShareHypervisor( engine: FlowEngine, - private val parent: FlowSystem? = null, + private val parent: FlowConvergenceListener? = null, scalingGovernor: ScalingGovernor? = null, interferenceDomain: VmInterferenceDomain? = null, private val listener: SimHypervisor.Listener? = null @@ -57,11 +57,9 @@ public class SimFairShareHypervisor( return SwitchSystem(ctx).switch } - private inner class SwitchSystem(private val ctx: SimMachineContext) : FlowSystem { + private inner class SwitchSystem(private val ctx: SimMachineContext) : FlowConvergenceListener { val switch = MaxMinFlowMultiplexer(engine, this, interferenceDomain) - override val parent: FlowSystem? = this@SimFairShareHypervisor.parent - private var lastCpuUsage = 0.0 private var lastCpuDemand = 0.0 private var lastDemand = 0.0 @@ -70,11 +68,11 @@ public class SimFairShareHypervisor( private var lastInterference = 0.0 private var lastReport = Long.MIN_VALUE - override fun onConverge(timestamp: Long) { + override fun onConverge(now: Long, delta: Long) { val listener = listener ?: return val counters = switch.counters - if (timestamp > lastReport) { + if (now > lastReport) { listener.onSliceFinish( this@SimFairShareHypervisor, counters.demand - lastDemand, @@ -85,7 +83,7 @@ public class SimFairShareHypervisor( lastCpuDemand ) } - lastReport = timestamp + lastReport = now lastCpuDemand = switch.outputs.sumOf { it.demand } lastCpuUsage = switch.outputs.sumOf { it.rate } @@ -96,6 +94,8 @@ public class SimFairShareHypervisor( val load = lastCpuDemand / ctx.cpus.sumOf { it.model.frequency } triggerGovernors(load) + + parent?.onConverge(now, delta) } } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt index bfa099fb..e0a70926 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain +import org.opendc.simulator.flow.FlowConvergenceListener import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowSystem /** * A [SimHypervisorProvider] for the [SimFairShareHypervisor] implementation. @@ -35,7 +35,7 @@ public class SimFairShareHypervisorProvider : SimHypervisorProvider { override fun create( engine: FlowEngine, - parent: FlowSystem?, + parent: FlowConvergenceListener?, scalingGovernor: ScalingGovernor?, interferenceDomain: VmInterferenceDomain?, listener: SimHypervisor.Listener? diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt index 97f07097..dad2cc3b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain +import org.opendc.simulator.flow.FlowConvergenceListener import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowSystem /** * A service provider interface for constructing a [SimHypervisor]. @@ -44,7 +44,7 @@ public interface SimHypervisorProvider { */ public fun create( engine: FlowEngine, - parent: FlowSystem? = null, + parent: FlowConvergenceListener? = null, scalingGovernor: ScalingGovernor? = null, interferenceDomain: VmInterferenceDomain? = null, listener: SimHypervisor.Listener? = null diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt index 7869d72d..93921eb9 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt @@ -24,8 +24,8 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain +import org.opendc.simulator.flow.FlowConvergenceListener import org.opendc.simulator.flow.FlowEngine -import org.opendc.simulator.flow.FlowSystem /** * A [SimHypervisorProvider] for the [SimSpaceSharedHypervisor] implementation. @@ -35,7 +35,7 @@ public class SimSpaceSharedHypervisorProvider : SimHypervisorProvider { override fun create( engine: FlowEngine, - parent: FlowSystem?, + parent: FlowConvergenceListener?, scalingGovernor: ScalingGovernor?, interferenceDomain: VmInterferenceDomain?, listener: SimHypervisor.Listener? diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt index fa833961..c327e1e9 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt @@ -41,6 +41,11 @@ public interface FlowConnection : AutoCloseable { */ public val demand: Double + /** + * A flag to control whether [FlowSource.onConverge] should be invoked for this source. + */ + public var shouldSourceConverge: Boolean + /** * Pull the source. */ diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt index 75b2d25b..15f9b93b 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt @@ -33,6 +33,11 @@ public interface FlowConsumerContext : FlowConnection { */ public override var capacity: Double + /** + * A flag to control whether [FlowConsumerLogic.onConverge] should be invoked for the consumer. + */ + public var shouldConsumerConverge: Boolean + /** * Start the flow over the connection. */ diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt index ef94ab22..50fbc9c7 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerLogic.kt @@ -39,6 +39,9 @@ public interface FlowConsumerLogic { /** * This method is invoked when the flow graph has converged into a steady-state system. * + * Make sure to enable [FlowConsumerContext.shouldSourceConverge] if you need this callback. By default, this method + * will not be invoked. + * * @param ctx The context in which the provider runs. * @param now The virtual timestamp in milliseconds at which the system converged. * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConvergenceListener.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConvergenceListener.kt new file mode 100644 index 00000000..d1afda6f --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConvergenceListener.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow + +/** + * A listener interface for when a flow stage has converged into a steady-state. + */ +public interface FlowConvergenceListener { + /** + * This method is invoked when the system has converged to a steady-state. + * + * @param now The timestamp at which the system converged. + * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. + */ + public fun onConverge(now: Long, delta: Long) {} +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index ab5b31c2..17de601a 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -52,6 +52,12 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled * The exposed [FlowConnection]. */ private val _ctx = object : FlowConnection { + override var shouldSourceConverge: Boolean = false + set(value) { + field = value + _innerCtx?.shouldSourceConverge = value + } + override val capacity: Double get() = _innerCtx?.capacity ?: 0.0 @@ -141,6 +147,10 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled override fun onStart(conn: FlowConnection, now: Long) { _innerCtx = conn + + if (_ctx.shouldSourceConverge) { + conn.shouldSourceConverge = true + } } override fun onStop(conn: FlowConnection, now: Long, delta: Long) { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt index fc590177..549a338b 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt @@ -32,9 +32,16 @@ package org.opendc.simulator.flow public class FlowSink( private val engine: FlowEngine, initialCapacity: Double, - private val parent: FlowSystem? = null + private val parent: FlowConvergenceListener? = null ) : AbstractFlowConsumer(engine, initialCapacity) { + override fun start(ctx: FlowConsumerContext) { + if (parent != null) { + ctx.shouldConsumerConverge = true + } + super.start(ctx) + } + override fun createLogic(): FlowConsumerLogic { return object : FlowConsumerLogic { override fun onPush( @@ -52,7 +59,7 @@ public class FlowSink( } override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { - parent?.onConverge(now) + parent?.onConverge(now, delta) } } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt index a4f624ef..3a7e52aa 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSource.kt @@ -59,6 +59,9 @@ public interface FlowSource { /** * This method is invoked when the flow graph has converged into a steady-state system. * + * Make sure to enable [FlowConnection.shouldSourceConverge] if you need this callback. By default, this method + * will not be invoked. + * * @param conn The connection between the source and consumer. * @param now The virtual timestamp in milliseconds at which the system converged. * @param delta The virtual duration between this call and the last call to [onConverge] in milliseconds. diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt deleted file mode 100644 index db6aa69f..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSystem.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow - -/** - * A system of possible multiple sub-resources. - * - * This interface is used to model hierarchies of resource providers, which can listen efficiently to changes of the - * resource provider. - */ -public interface FlowSystem { - /** - * The parent system to which this system belongs or `null` if it has no parent. - */ - public val parent: FlowSystem? - - /** - * This method is invoked when the system has converged to a steady-state. - * - * @param timestamp The timestamp at which the system converged. - */ - public fun onConverge(timestamp: Long) -} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index 55fa92df..c087a28d 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -72,6 +72,12 @@ internal class FlowConsumerContextImpl( override val demand: Double get() = _demand + /** + * Flags to control the convergence of the consumer and source. + */ + override var shouldConsumerConverge: Boolean = false + override var shouldSourceConverge: Boolean = false + /** * The clock to track simulation time. */ @@ -114,7 +120,8 @@ internal class FlowConsumerContextImpl( */ private var _lastPull: Long = Long.MIN_VALUE // Last call to `onPull` private var _lastPush: Long = Long.MIN_VALUE // Last call to `onPush` - private var _lastConvergence: Long = Long.MAX_VALUE // Last call to `onConvergence` + private var _lastSourceConvergence: Long = Long.MAX_VALUE // Last call to source `onConvergence` + private var _lastConsumerConvergence: Long = Long.MAX_VALUE // Last call to consumer `onConvergence` /** * The timers at which the context is scheduled to be interrupted. @@ -199,8 +206,14 @@ internal class FlowConsumerContextImpl( * @return A flag to indicate whether the connection has already been updated before convergence. */ fun doUpdate(now: Long): Boolean { - val willConverge = _willConverge - _willConverge = true + // The connection will only converge if either the source or the consumer wants the converge callback to be + // invoked. + val shouldConverge = shouldSourceConverge || shouldConsumerConverge + var willConverge = false + if (shouldConverge) { + willConverge = _willConverge + _willConverge = true + } val oldState = _state if (oldState != State.Active) { @@ -286,19 +299,25 @@ internal class FlowConsumerContextImpl( /** * This method is invoked when the system converges into a steady state. */ - fun onConverge(timestamp: Long) { - val delta = max(0, timestamp - _lastConvergence) - _lastConvergence = timestamp + fun onConverge(now: Long) { _willConverge = false try { - if (_state == State.Active) { - source.onConverge(this, timestamp, delta) + if (_state == State.Active && shouldSourceConverge) { + val delta = max(0, now - _lastSourceConvergence) + _lastSourceConvergence = now + + source.onConverge(this, now, delta) } - logic.onConverge(this, timestamp, delta) + if (shouldConsumerConverge) { + val delta = max(0, now - _lastConsumerConvergence) + _lastConsumerConvergence = now + + logic.onConverge(this, now, delta) + } } catch (cause: Throwable) { - doFailSource(timestamp, cause) + doFailSource(now, cause) } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index c7379fa9..7232df35 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -38,7 +38,7 @@ import kotlin.math.min */ public class MaxMinFlowMultiplexer( private val engine: FlowEngine, - private val parent: FlowSystem? = null, + private val parent: FlowConvergenceListener? = null, private val interferenceDomain: InterferenceDomain? = null ) : FlowMultiplexer { /** @@ -269,6 +269,11 @@ public class MaxMinFlowMultiplexer( check(!_isClosed) { "Cannot re-use closed input" } _activeInputs += this + + if (parent != null) { + ctx.shouldConsumerConverge = true + } + super.start(ctx) } @@ -289,7 +294,7 @@ public class MaxMinFlowMultiplexer( } override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { - parent?.onConverge(now) + parent?.onConverge(now, delta) } override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt index 0c39523f..6dd60d95 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/source/FlowSourceRateAdapter.kt @@ -47,6 +47,12 @@ public class FlowSourceRateAdapter( callback(0.0) } + override fun onStart(conn: FlowConnection, now: Long) { + conn.shouldSourceConverge = true + + delegate.onStart(conn, now) + } + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { try { delegate.onStop(conn, now, delta) @@ -60,9 +66,11 @@ public class FlowSourceRateAdapter( } override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { - delegate.onConverge(conn, now, delta) - - rate = conn.rate + try { + delegate.onConverge(conn, now, delta) + } finally { + rate = conn.rate + } } override fun toString(): String = "FlowSourceRateAdapter[delegate=$delegate]" diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt index 3690e681..d548451f 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt @@ -297,6 +297,10 @@ internal class FlowForwarderTest { try { forwarder.consume(object : FlowSource { + override fun onStart(conn: FlowConnection, now: Long) { + conn.shouldSourceConverge = true + } + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { return Long.MAX_VALUE } -- cgit v1.2.3 From de8509b50d5acb7e739eb5cb4d29b03a627c8985 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 1 Oct 2021 11:40:21 +0200 Subject: perf(simulator): Reduce field accesses in FlowConsumerContextImpl This change updates the implementation of FlowConsumerContextImpl to reduce the number of field accesses by storing the flags of the connection inside a single integer. --- .../kotlin/org/opendc/simulator/flow/FlowSink.kt | 2 + .../org/opendc/simulator/flow/internal/Flags.kt | 43 +++ .../flow/internal/FlowConsumerContextImpl.kt | 338 ++++++++++----------- .../simulator/flow/internal/FlowEngineImpl.kt | 112 ++----- 4 files changed, 241 insertions(+), 254 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt index 549a338b..b4eb6a38 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt @@ -44,6 +44,8 @@ public class FlowSink( override fun createLogic(): FlowConsumerLogic { return object : FlowConsumerLogic { + private val parent = this@FlowSink.parent + override fun onPush( ctx: FlowConsumerContext, now: Long, diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt new file mode 100644 index 00000000..81ed9f26 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +/** + * States of the flow connection. + */ +internal const val ConnPending = 0 // Connection is pending and the consumer is waiting to consume the source +internal const val ConnActive = 1 // Connection is active and the source is currently being consumed +internal const val ConnClosed = 2 // Connection is closed and source cannot be consumed through this connection anymore +internal const val ConnState = 0b11 // Mask for accessing the state of the flow connection + +/** + * Flags of the flow connection + */ +internal const val ConnPulled = 1 shl 2 // The source should be pulled +internal const val ConnPushed = 1 shl 3 // The source has pushed a value +internal const val ConnUpdateActive = 1 shl 4 // An update for the connection is active +internal const val ConnUpdatePending = 1 shl 5 // An (immediate) update of the connection is pending +internal const val ConnUpdateSkipped = 1 shl 6 // An update of the connection was not necessary +internal const val ConnConvergePending = 1 shl 7 // Indication that a convergence is already pending +internal const val ConnConvergeSource = 1 shl 8 // Enable convergence of the source +internal const val ConnConvergeConsumer = 1 shl 9 // Enable convergence of the consumer diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index c087a28d..9d36483e 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -24,7 +24,7 @@ package org.opendc.simulator.flow.internal import mu.KotlinLogging import org.opendc.simulator.flow.* -import java.util.ArrayDeque +import java.util.* import kotlin.math.max import kotlin.math.min @@ -44,20 +44,18 @@ internal class FlowConsumerContextImpl( /** * The capacity of the connection. */ - override var capacity: Double = 0.0 + override var capacity: Double + get() = _capacity set(value) { - val oldValue = field + val oldValue = _capacity // Only changes will be propagated if (value != oldValue) { - field = value - - // Do not pull the source if it has not been started yet - if (_state == State.Active) { - pull() - } + _capacity = value + pull() } } + private var _capacity: Double = 0.0 /** * The current processing rate of the connection. @@ -75,45 +73,41 @@ internal class FlowConsumerContextImpl( /** * Flags to control the convergence of the consumer and source. */ - override var shouldConsumerConverge: Boolean = false override var shouldSourceConverge: Boolean = false + set(value) { + field = value + _flags = + if (value) + _flags or ConnConvergeSource + else + _flags and ConnConvergeSource.inv() + } + override var shouldConsumerConverge: Boolean = false + set(value) { + field = value + + _flags = + if (value) + _flags or ConnConvergeConsumer + else + _flags and ConnConvergeConsumer.inv() + } /** * The clock to track simulation time. */ private val _clock = engine.clock - /** - * A flag to indicate the state of the connection. - */ - private var _state = State.Pending - /** * The current state of the connection. */ private var _demand: Double = 0.0 // The current (pending) demand of the source - private var _activeDemand: Double = 0.0 // The previous demand of the source private var _deadline: Long = Long.MAX_VALUE // The deadline of the source's timer /** - * A flag to indicate that the source should be pulled. - */ - private var _isPulled = false - - /** - * A flag to indicate that an update is active. - */ - private var _isUpdateActive = false - - /** - * A flag to indicate that an immediate update is scheduled. + * The flags of the flow connection, indicating certain actions. */ - private var _isImmediateUpdateScheduled = false - - /** - * A flag that indicates to the [FlowEngine] that the context is already enqueued to converge. - */ - private var _willConverge: Boolean = false + private var _flags: Int = 0 /** * The timestamp of calls to the callbacks. @@ -130,44 +124,53 @@ internal class FlowConsumerContextImpl( private val _pendingTimers: ArrayDeque = ArrayDeque(5) override fun start() { - check(_state == State.Pending) { "Consumer is already started" } + check(_flags and ConnState == ConnPending) { "Consumer is already started" } engine.batch { - source.onStart(this, _clock.millis()) - _state = State.Active + val now = _clock.millis() + source.onStart(this, now) - pull() + // Mark the connection as active and pulled + val newFlags = (_flags and ConnState.inv()) or ConnActive or ConnPulled + scheduleImmediate(now, newFlags) } } override fun close() { - if (_state == State.Closed) { + var flags = _flags + if (flags and ConnState == ConnClosed) { return } engine.batch { - _state = State.Closed - if (!_isUpdateActive) { + // Mark the connection as closed and pulled (in order to converge) + flags = (flags and ConnState.inv()) or ConnClosed or ConnPulled + _flags = flags + + if (flags and ConnUpdateActive == 0) { val now = _clock.millis() doStopSource(now) // FIX: Make sure the context converges - pull() + scheduleImmediate(now, flags) } } } override fun pull() { - if (_state == State.Closed) { + val flags = _flags + if (flags and ConnState != ConnActive) { return } - _isPulled = true - scheduleImmediate() + // Mark connection as pulled + scheduleImmediate(_clock.millis(), flags or ConnPulled) } override fun flush() { + val flags = _flags + // Do not attempt to flush the connection if the connection is closed or an update is already active - if (_state == State.Closed || _isUpdateActive) { + if (flags and ConnState != ConnActive || flags and ConnUpdateActive != 0) { return } @@ -181,118 +184,145 @@ internal class FlowConsumerContextImpl( _demand = rate - // Invalidate only if the active demand is changed and no update is active - // If an update is active, it will already get picked up at the end of the update - if (_activeDemand != rate && !_isUpdateActive) { - scheduleImmediate() - } - } + val flags = _flags - /** - * Determine whether the state of the flow connection should be updated. - */ - fun shouldUpdate(timestamp: Long): Boolean { - // The flow connection should be updated for three reasons: - // (1) The source should be pulled (after a call to `pull`) - // (2) The demand of the source has changed (after a call to `push`) - // (3) The timer of the source expired - return _isPulled || _demand != _activeDemand || _deadline == timestamp + if (flags and ConnUpdateActive != 0) { + // If an update is active, it will already get picked up at the end of the update + _flags = flags or ConnPushed + } else { + // Invalidate only if no update is active + scheduleImmediate(_clock.millis(), flags or ConnPushed) + } } /** * Update the state of the flow connection. * * @param now The current virtual timestamp. - * @return A flag to indicate whether the connection has already been updated before convergence. + * @param visited The queue of connections that have been visited during the cycle. + * @param timerQueue The queue of all pending timers. + * @param isImmediate A flag to indicate that this invocation is an immediate update or a delayed update. */ - fun doUpdate(now: Long): Boolean { - // The connection will only converge if either the source or the consumer wants the converge callback to be - // invoked. - val shouldConverge = shouldSourceConverge || shouldConsumerConverge - var willConverge = false - if (shouldConverge) { - willConverge = _willConverge - _willConverge = true - } - - val oldState = _state - if (oldState != State.Active) { - return willConverge + fun doUpdate( + now: Long, + visited: ArrayDeque, + timerQueue: PriorityQueue, + isImmediate: Boolean + ) { + var flags = _flags + + // Precondition: The flow connection must be active + if (flags and ConnState != ConnActive) { + return } - _isUpdateActive = true - _isImmediateUpdateScheduled = false + val deadline = _deadline + val reachedDeadline = deadline == now + var newDeadline = deadline + var hasUpdated = false try { // Pull the source if (1) `pull` is called or (2) the timer of the source has expired - val deadline = if (_isPulled || _deadline == now) { + newDeadline = if (flags and ConnPulled != 0 || reachedDeadline) { val lastPull = _lastPull val delta = max(0, now - lastPull) - _isPulled = false + // Update state before calling into the outside world, so it observes a consistent state _lastPull = now + _flags = (flags and ConnPulled.inv()) or ConnUpdateActive + hasUpdated = true val duration = source.onPull(this, now, delta) + + // IMPORTANT: Re-fetch the flags after the callback might have changed those + flags = _flags + if (duration != Long.MAX_VALUE) now + duration else duration } else { - _deadline + deadline } - // Check whether the state has changed after [consumer.onNext] - when (_state) { - State.Active -> { - val demand = _demand - if (demand != _activeDemand) { - val lastPush = _lastPush - val delta = max(0, now - lastPush) - - _lastPush = now - - logic.onPush(this, now, delta, demand) - } - } - State.Closed -> doStopSource(now) - State.Pending -> throw IllegalStateException("Illegal transition to pending state") - } + // Push to the consumer if the rate of the source has changed (after a call to `push`) + val newState = flags and ConnState + if (newState == ConnActive && flags and ConnPushed != 0) { + val lastPush = _lastPush + val delta = max(0, now - lastPush) - // Note: pending limit might be changed by [logic.onConsume], so re-fetch the value - val newLimit = _demand + // Update state before calling into the outside world, so it observes a consistent state + _lastPush = now + _flags = (flags and ConnPushed.inv()) or ConnUpdateActive + hasUpdated = true - // Flush the changes to the flow - _activeDemand = newLimit - _deadline = deadline - _rate = min(capacity, newLimit) + logic.onPush(this, now, delta, _demand) - // Schedule an update at the new deadline - scheduleDelayed(now, deadline) + // IMPORTANT: Re-fetch the flags after the callback might have changed those + flags = _flags + } else if (newState == ConnClosed) { + hasUpdated = true + + // The source has called [FlowConnection.close], so clean up the connection + doStopSource(now) + } } catch (cause: Throwable) { + // Mark the connection as closed + flags = (flags and ConnState.inv()) or ConnClosed + doFailSource(now, cause) - } finally { - _isUpdateActive = false } - return willConverge - } + // Check whether the connection needs to be added to the visited queue. This is the case when: + // (1) An update was performed (either a push or a pull) + // (2) Either the source or consumer want to converge, and + // (3) Convergence is not already pending (ConnConvergePending) + if (hasUpdated && flags and (ConnConvergeSource or ConnConvergeConsumer) != 0 && flags and ConnConvergePending == 0) { + visited.add(this) + flags = flags or ConnConvergePending + } - /** - * Prune the elapsed timers from this context. - */ - fun updateTimers() { - // Invariant: Any pending timer should only point to a future timestamp - // See also `scheduleDelayed` - _timer = _pendingTimers.poll() - } + // Compute the new flow rate of the connection + // Note: _demand might be changed by [logic.onConsume], so we must re-fetch the value + _rate = min(_capacity, _demand) - /** - * Try to re-schedule the resource context in case it was skipped. - */ - fun tryReschedule(now: Long) { - val deadline = _deadline - if (deadline > now && deadline != Long.MAX_VALUE) { - scheduleDelayed(now, deadline) + // Indicate that no update is active anymore and flush the flags + _flags = flags and ConnUpdateActive.inv() and ConnUpdatePending.inv() + + val pendingTimers = _pendingTimers + + // Prune the head timer if this is a delayed update + val timer = if (!isImmediate) { + // Invariant: Any pending timer should only point to a future timestamp + // See also `scheduleDelayed` + val timer = pendingTimers.poll() + _timer = timer + timer + } else { + _timer + } + + // Set the new deadline and schedule a delayed update for that deadline + _deadline = newDeadline + + // Check whether we need to schedule a new timer for this connection. That is the case when: + // (1) The deadline is valid (not the maximum value) + // (2) The connection is active + // (3) The current active timer for the connection points to a later deadline + if (newDeadline == Long.MAX_VALUE || flags and ConnState != ConnActive || (timer != null && newDeadline >= timer.target)) { + // Ignore any deadline scheduled at the maximum value + // This indicates that the source does not want to register a timer + return + } + + // Construct a timer for the new deadline and add it to the global queue of timers + val newTimer = FlowEngineImpl.Timer(this, newDeadline) + _timer = newTimer + timerQueue.add(newTimer) + + // A timer already exists for this connection, so add it to the queue of pending timers + if (timer != null) { + pendingTimers.addFirst(timer) } } @@ -300,17 +330,22 @@ internal class FlowConsumerContextImpl( * This method is invoked when the system converges into a steady state. */ fun onConverge(now: Long) { - _willConverge = false - try { - if (_state == State.Active && shouldSourceConverge) { + val flags = _flags + + // The connection is converging now, so unset the convergence pending flag + _flags = flags and ConnConvergePending.inv() + + // Call the source converge callback if it has enabled convergence and the connection is active + if (flags and ConnState == ConnActive && flags and ConnConvergeSource != 0) { val delta = max(0, now - _lastSourceConvergence) _lastSourceConvergence = now source.onConverge(this, now, delta) } - if (shouldConsumerConverge) { + // Call the consumer callback if it has enabled convergence + if (flags and ConnConvergeConsumer != 0) { val delta = max(0, now - _lastConsumerConvergence) _lastConsumerConvergence = now @@ -369,57 +404,16 @@ internal class FlowConsumerContextImpl( /** * Schedule an immediate update for this connection. */ - private fun scheduleImmediate() { + private fun scheduleImmediate(now: Long, flags: Int) { // In case an immediate update is already scheduled, no need to do anything - if (_isImmediateUpdateScheduled) { + if (flags and ConnUpdatePending != 0) { + _flags = flags return } - _isImmediateUpdateScheduled = true + // Mark the connection that there is an update pending + _flags = flags or ConnUpdatePending - val now = _clock.millis() engine.scheduleImmediate(now, this) } - - /** - * Schedule a delayed update for this resource context. - */ - private fun scheduleDelayed(now: Long, target: Long) { - // Ignore any target scheduled at the maximum value - // This indicates that the sources does not want to register a timer - if (target == Long.MAX_VALUE) { - return - } - - val timer = _timer - - if (timer == null) { - // No existing timer exists, so schedule a new timer and update the head - _timer = engine.scheduleDelayed(now, this, target) - } else if (target < timer.target) { - // Existing timer is further in the future, so schedule a new timer ahead of it - _timer = engine.scheduleDelayed(now, this, target) - _pendingTimers.addFirst(timer) - } - } - - /** - * The state of a flow connection. - */ - private enum class State { - /** - * The connection is pending and the consumer is waiting to consume the source. - */ - Pending, - - /** - * The connection is active and the source is currently being consumed. - */ - Active, - - /** - * The connection is closed and the source cannot be consumed through this connection anymore. - */ - Closed - } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index c8170a43..019b5f10 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -63,39 +63,26 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va /** * The systems that have been visited during the engine cycle. */ - private val visited = ArrayDeque() + private val visited: ArrayDeque = ArrayDeque() /** * The index in the batch stack. */ private var batchIndex = 0 - /** - * A flag to indicate that the engine is currently active. - */ - private val isRunning: Boolean - get() = batchIndex > 0 - /** * Update the specified [ctx] synchronously. */ fun scheduleSync(now: Long, ctx: FlowConsumerContextImpl) { - if (!ctx.doUpdate(now)) { - visited.add(ctx) - } + ctx.doUpdate(now, visited, futureQueue, isImmediate = true) // In-case the engine is already running in the call-stack, return immediately. The changes will be picked // up by the active engine. - if (isRunning) { + if (batchIndex > 0) { return } - try { - batchIndex++ - runEngine(now) - } finally { - batchIndex-- - } + runEngine(now) } /** @@ -109,36 +96,11 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va // In-case the engine is already running in the call-stack, return immediately. The changes will be picked // up by the active engine. - if (isRunning) { + if (batchIndex > 0) { return } - try { - batchIndex++ - runEngine(now) - } finally { - batchIndex-- - } - } - - /** - * Schedule the engine to run at [target] to update the flow contexts. - * - * This method will override earlier calls to this method for the same [ctx]. - * - * @param now The current virtual timestamp. - * @param ctx The flow context to which the event applies. - * @param target The timestamp when the interrupt should happen. - */ - fun scheduleDelayed(now: Long, ctx: FlowConsumerContextImpl, target: Long): Timer { - val futureQueue = futureQueue - - require(target >= now) { "Timestamp must be in the future" } - - val timer = Timer(ctx, target) - futureQueue.add(timer) - - return timer + runEngine(now) } override fun newContext(consumer: FlowSource, provider: FlowConsumerLogic): FlowConsumerContext = FlowConsumerContextImpl(this, consumer, provider) @@ -149,9 +111,9 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va override fun popBatch() { try { - // Flush the work if the platform is not already running + // Flush the work if the engine is not already running if (batchIndex == 1 && queue.isNotEmpty()) { - runEngine(clock.millis()) + doRunEngine(clock.millis()) } } finally { batchIndex-- @@ -159,9 +121,21 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va } /** - * Run all the enqueued actions for the specified [timestamp][now]. + * Run the engine and mark as active while running. */ private fun runEngine(now: Long) { + try { + batchIndex++ + doRunEngine(now) + } finally { + batchIndex-- + } + } + + /** + * Run all the enqueued actions for the specified [timestamp][now]. + */ + private fun doRunEngine(now: Long) { val queue = queue val futureQueue = futureQueue val futureInvocations = futureInvocations @@ -179,27 +153,16 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va // Execute all scheduled updates at current timestamp while (true) { val timer = futureQueue.peek() ?: break - val ctx = timer.ctx val target = timer.target - assert(target >= now) { "Internal inconsistency: found update of the past" } - if (target > now) { break } - futureQueue.poll() - - // Update the existing timers of the connection - ctx.updateTimers() + assert(target >= now) { "Internal inconsistency: found update of the past" } - if (ctx.shouldUpdate(now)) { - if (!ctx.doUpdate(now)) { - visited.add(ctx) - } - } else { - ctx.tryReschedule(now) - } + futureQueue.poll() + timer.ctx.doUpdate(now, visited, futureQueue, isImmediate = false) } // Repeat execution of all immediate updates until the system has converged to a steady-state @@ -208,17 +171,13 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va // Execute all immediate updates while (true) { val ctx = queue.poll() ?: break - - if (ctx.shouldUpdate(now) && !ctx.doUpdate(now)) { - visited.add(ctx) - } + ctx.doUpdate(now, visited, futureQueue, isImmediate = true) } - for (system in visited) { - system.onConverge(now) + while (true) { + val ctx = visited.poll() ?: break + ctx.onConverge(now) } - - visited.clear() } while (queue.isNotEmpty()) // Schedule an engine invocation for the next update to occur. @@ -242,18 +201,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va // Case 2: A new timer was registered ahead of the other timers. // Solution: Schedule a new scheduler invocation @OptIn(InternalCoroutinesApi::class) - val handle = delay.invokeOnTimeout( - target - now, - { - try { - batchIndex++ - runEngine(target) - } finally { - batchIndex-- - } - }, - context - ) + val handle = delay.invokeOnTimeout(target - now, { runEngine(target) }, context) scheduled.addFirst(Invocation(target, handle)) break } else if (invocation.timestamp < target) { @@ -274,7 +222,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va * This class is used to keep track of the future engine invocations created using the [Delay] instance. In case * the invocation is not needed anymore, it can be cancelled via [cancel]. */ - private data class Invocation( + private class Invocation( @JvmField val timestamp: Long, @JvmField val handle: DisposableHandle ) { -- cgit v1.2.3 From 6e424e9b44687d01e618e7bc38afc427610cd845 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 1 Oct 2021 20:08:21 +0200 Subject: perf(simulator): Optimize hot path in SimTraceWorkload This change optimizes the hot path of the SimTraceWorkload class. This class is used by multiple experiments to replay workload traces and consumes a considerable amount of time of the total time of the experiments. By inlining the isExpired method, marking the properties on the Fragment class as field, and caching several properties locally in the class, we reduce the amount of virtual method calls in the hot path. --- .../simulator/compute/workload/SimTraceWorkload.kt | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index a877dac1..49ae5933 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -53,14 +53,15 @@ public class SimTraceWorkload(public val trace: Sequence, private val * Obtain the fragment with a timestamp equal or greater than [now]. */ private fun pullFragment(now: Long): Fragment? { + // Return the most recent fragment if its starting time + duration is later than `now` var fragment = fragment - if (fragment != null && !fragment.isExpired(now)) { + if (fragment != null && fragment.timestamp + offset + fragment.duration > now) { return fragment } while (iterator.hasNext()) { fragment = iterator.next() - if (!fragment.isExpired(now)) { + if (fragment.timestamp + offset + fragment.duration > now) { this.fragment = fragment return fragment } @@ -70,15 +71,11 @@ public class SimTraceWorkload(public val trace: Sequence, private val return null } - /** - * Determine if the specified [Fragment] is expired, i.e., it has already passed. - */ - private fun Fragment.isExpired(now: Long): Boolean { - val timestamp = this.timestamp + offset - return now >= timestamp + duration - } + private inner class Consumer(cpu: ProcessingUnit) : FlowSource { + private val offset = this@SimTraceWorkload.offset + private val id = cpu.id + private val coreCount = cpu.node.coreCount - private inner class Consumer(val cpu: ProcessingUnit) : FlowSource { override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val fragment = pullFragment(now) @@ -95,7 +92,7 @@ public class SimTraceWorkload(public val trace: Sequence, private val return timestamp - now } - val cores = min(cpu.node.coreCount, fragment.cores) + val cores = min(coreCount, fragment.cores) val usage = if (fragment.cores > 0) fragment.usage / cores else @@ -103,7 +100,7 @@ public class SimTraceWorkload(public val trace: Sequence, private val val deadline = timestamp + fragment.duration val duration = deadline - now - conn.push(if (cpu.id < cores && usage > 0.0) usage else 0.0) + conn.push(if (id < cores && usage > 0.0) usage else 0.0) return duration } @@ -117,5 +114,10 @@ public class SimTraceWorkload(public val trace: Sequence, private val * @param usage The CPU usage during the fragment. * @param cores The amount of cores utilized during the fragment. */ - public data class Fragment(val timestamp: Long, val duration: Long, val usage: Double, val cores: Int) + public data class Fragment( + @JvmField val timestamp: Long, + @JvmField val duration: Long, + @JvmField val usage: Double, + @JvmField val cores: Int + ) } -- cgit v1.2.3 From 081221684fb826ab5a00c1d8cc5a9886b9e2203c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 1 Oct 2021 22:04:35 +0200 Subject: feat(simulator): Expose CPU time counters directly on hypervisor This change adds a new interface to the SimHypervisor interface that exposes the CPU time counters directly. These are derived from the flow counters and will be used by SimHost to expose them via telemetry. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 196 ++++++--------- .../org/opendc/compute/simulator/internal/Guest.kt | 51 ++-- .../org/opendc/compute/simulator/SimHostTest.kt | 20 +- .../experiments/capelin/CapelinIntegrationTest.kt | 27 +- .../simulator/compute/SimMachineBenchmarks.kt | 6 +- .../simulator/compute/SimBareMetalMachine.kt | 27 +- .../compute/kernel/SimAbstractHypervisor.kt | 144 +++++++++-- .../compute/kernel/SimFairShareHypervisor.kt | 67 +---- .../kernel/SimFairShareHypervisorProvider.kt | 11 +- .../simulator/compute/kernel/SimHypervisor.kt | 38 ++- .../compute/kernel/SimHypervisorCounters.kt | 48 ++++ .../compute/kernel/SimHypervisorProvider.kt | 5 +- .../compute/kernel/SimSpaceSharedHypervisor.kt | 17 +- .../kernel/SimSpaceSharedHypervisorProvider.kt | 5 +- .../simulator/compute/kernel/SimVirtualMachine.kt | 50 ++++ .../compute/kernel/SimFairShareHypervisorTest.kt | 238 ++++++++++++++++++ .../simulator/compute/kernel/SimHypervisorTest.kt | 280 --------------------- .../compute/kernel/SimSpaceSharedHypervisorTest.kt | 20 +- .../org/opendc/simulator/flow/FlowBenchmarks.kt | 16 +- .../opendc/simulator/flow/AbstractFlowConsumer.kt | 20 +- .../org/opendc/simulator/flow/FlowCounters.kt | 4 +- .../org/opendc/simulator/flow/FlowForwarder.kt | 3 +- .../simulator/flow/internal/FlowCountersImpl.kt | 6 +- .../opendc/simulator/flow/mux/FlowMultiplexer.kt | 38 ++- .../flow/mux/ForwardingFlowMultiplexer.kt | 114 +++++---- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 164 +++++++++--- .../org/opendc/simulator/flow/FlowForwarderTest.kt | 2 +- .../flow/mux/ExclusiveFlowMultiplexerTest.kt | 154 ------------ .../flow/mux/ForwardingFlowMultiplexerTest.kt | 154 ++++++++++++ .../flow/mux/MaxMinFlowMultiplexerTest.kt | 12 +- .../simulator/network/SimNetworkSwitchVirtual.kt | 8 +- .../kotlin/org/opendc/simulator/power/SimPdu.kt | 8 +- .../kotlin/org/opendc/simulator/power/SimUps.kt | 6 +- 33 files changed, 1079 insertions(+), 880 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt create mode 100644 opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt delete mode 100644 opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt delete mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexerTest.kt diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index f499927d..4b96872b 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -50,7 +50,6 @@ import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.flow.FlowEngine import java.util.* import kotlin.coroutines.CoroutineContext -import kotlin.math.roundToLong /** * A [Host] that is simulates virtual machines on a physical machine using [SimHypervisor]. @@ -63,7 +62,7 @@ public class SimHost( context: CoroutineContext, engine: FlowEngine, meterProvider: MeterProvider, - hypervisor: SimHypervisorProvider, + hypervisorProvider: SimHypervisorProvider, scalingGovernor: ScalingGovernor = PerformanceScalingGovernor(), powerDriver: PowerDriver = SimplePowerDriver(ConstantPowerModel(0.0)), private val mapper: SimWorkloadMapper = SimMetaWorkloadMapper(), @@ -103,29 +102,8 @@ public class SimHost( /** * The hypervisor to run multiple workloads. */ - private val hypervisor: SimHypervisor = hypervisor.create( - engine, - scalingGovernor = scalingGovernor, - interferenceDomain = interferenceDomain, - listener = object : SimHypervisor.Listener { - override fun onSliceFinish( - hypervisor: SimHypervisor, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double - ) { - _cpuDemand = cpuDemand - _cpuUsage = cpuUsage - - collectTime() - } - } - ) - private var _cpuUsage = 0.0 - private var _cpuDemand = 0.0 + private val hypervisor: SimHypervisor = hypervisorProvider + .create(engine, scalingGovernor = scalingGovernor, interferenceDomain = interferenceDomain) /** * The virtual machines running on the hypervisor. @@ -157,22 +135,13 @@ public class SimHost( } } + /** + * The [Job] that represents the machine running the hypervisor. + */ + private var _job: Job? = null + init { - // Launch hypervisor onto machine - scope.launch { - try { - _bootTime = clock.millis() - _state = HostState.UP - machine.run(this@SimHost.hypervisor, emptyMap()) - } catch (_: CancellationException) { - // Ignored - } catch (cause: Throwable) { - logger.error(cause) { "Host failed" } - throw cause - } finally { - _state = HostState.DOWN - } - } + launch() meter.upDownCounterBuilder("system.guests") .setDescription("Number of guests on this host") @@ -184,15 +153,15 @@ public class SimHost( meter.gaugeBuilder("system.cpu.demand") .setDescription("Amount of CPU resources the guests would use if there were no CPU contention or CPU limits") .setUnit("MHz") - .buildWithCallback { result -> result.observe(_cpuDemand) } + .buildWithCallback { result -> result.observe(hypervisor.cpuDemand) } meter.gaugeBuilder("system.cpu.usage") .setDescription("Amount of CPU resources used by the host") .setUnit("MHz") - .buildWithCallback { result -> result.observe(_cpuUsage) } + .buildWithCallback { result -> result.observe(hypervisor.cpuUsage) } meter.gaugeBuilder("system.cpu.utilization") .setDescription("Utilization of the CPU resources of the host") .setUnit("%") - .buildWithCallback { result -> result.observe(_cpuUsage / _cpuLimit) } + .buildWithCallback { result -> result.observe(hypervisor.cpuUsage / _cpuLimit) } meter.counterBuilder("system.cpu.time") .setDescription("Amount of CPU time spent by the host") .setUnit("s") @@ -200,16 +169,16 @@ public class SimHost( meter.gaugeBuilder("system.power.usage") .setDescription("Power usage of the host ") .setUnit("W") - .buildWithCallback { result -> result.observe(machine.powerDraw) } + .buildWithCallback { result -> result.observe(machine.powerUsage) } meter.counterBuilder("system.power.total") .setDescription("Amount of energy used by the CPU") .setUnit("J") .ofDoubles() - .buildWithCallback(::collectPowerTotal) + .buildWithCallback { result -> result.observe(machine.energyUsage) } meter.counterBuilder("system.time") .setDescription("The uptime of the host") .setUnit("s") - .buildWithCallback(::collectTime) + .buildWithCallback(::collectUptime) meter.gaugeBuilder("system.time.boot") .setDescription("The boot time of the host") .setUnit("1") @@ -290,24 +259,55 @@ public class SimHost( } public suspend fun recover() { - collectTime() - _state = HostState.UP - _bootTime = clock.millis() + updateUptime() + + launch() + + // Wait for the hypervisor to launch before recovering the guests + yield() for (guest in guests.values) { guest.recover() } } + /** + * Launch the hypervisor. + */ + private fun launch() { + check(_job == null) { "Concurrent hypervisor running" } + + // Launch hypervisor onto machine + _job = scope.launch { + try { + _bootTime = clock.millis() + _state = HostState.UP + machine.run(hypervisor, emptyMap()) + } catch (_: CancellationException) { + // Ignored + } catch (cause: Throwable) { + logger.error(cause) { "Host failed" } + throw cause + } finally { + _state = HostState.DOWN + } + } + } + /** * Reset the machine. */ private fun reset() { - collectTime() + updateUptime() + + // Stop the hypervisor + val job = _job + if (job != null) { + job.cancel() + _job = null + } _state = HostState.DOWN - _cpuUsage = 0.0 - _cpuDemand = 0.0 } /** @@ -385,85 +385,46 @@ public class SimHost( } } - private var _lastCpuTimeCallback = clock.millis() - - /** - * Helper function to track the CPU time of a machine. - */ - private fun collectCpuTime(result: ObservableLongMeasurement) { - val now = clock.millis() - val duration = now - _lastCpuTimeCallback - - try { - collectCpuTime(duration, result) - } finally { - _lastCpuTimeCallback = now - } - } - private val _activeState = Attributes.of(STATE_KEY, "active") private val _stealState = Attributes.of(STATE_KEY, "steal") private val _lostState = Attributes.of(STATE_KEY, "lost") private val _idleState = Attributes.of(STATE_KEY, "idle") - private var _totalTime = 0.0 /** * Helper function to track the CPU time of a machine. */ - private fun collectCpuTime(duration: Long, result: ObservableLongMeasurement) { - val coreCount = this.model.cpuCount - val d = coreCount / _cpuLimit - + private fun collectCpuTime(result: ObservableLongMeasurement) { val counters = hypervisor.counters - val grantedWork = counters.actual - val overcommittedWork = counters.overcommit - val interferedWork = counters.interference - _totalTime += (duration / 1000.0) * coreCount - val activeTime = (grantedWork * d).roundToLong() - val idleTime = (_totalTime - grantedWork * d).roundToLong() - val stealTime = (overcommittedWork * d).roundToLong() - val lostTime = (interferedWork * d).roundToLong() - - result.observe(activeTime, _activeState) - result.observe(idleTime, _idleState) - result.observe(stealTime, _stealState) - result.observe(lostTime, _lostState) + result.observe(counters.cpuActiveTime / 1000L, _activeState) + result.observe(counters.cpuIdleTime / 1000L, _idleState) + result.observe(counters.cpuStealTime / 1000L, _stealState) + result.observe(counters.cpuLostTime / 1000L, _lostState) for (guest in guests.values) { - guest.collectCpuTime(duration, result) + guest.collectCpuTime(result) } } - private var _lastPowerCallback = clock.millis() - private var _totalPower = 0.0 - - /** - * Helper function to collect the total power usage of the machine. - */ - private fun collectPowerTotal(result: ObservableDoubleMeasurement) { - val now = clock.millis() - val duration = now - _lastPowerCallback - - _totalPower += duration / 1000.0 * machine.powerDraw - result.observe(_totalPower) - - _lastPowerCallback = now - } - private var _lastReport = clock.millis() /** * Helper function to track the uptime of a machine. */ - private fun collectTime(result: ObservableLongMeasurement? = null) { + private fun updateUptime() { val now = clock.millis() val duration = now - _lastReport + _lastReport = now - try { - collectTime(duration, result) - } finally { - _lastReport = now + if (_state == HostState.UP) { + _uptime += duration + } else if (_state == HostState.DOWN && scope.isActive) { + // Only increment downtime if the machine is in a failure state + _downtime += duration + } + + for (guest in guests.values) { + guest.updateUptime(duration) } } @@ -475,19 +436,14 @@ public class SimHost( /** * Helper function to track the uptime of a machine. */ - private fun collectTime(duration: Long, result: ObservableLongMeasurement? = null) { - if (state == HostState.UP) { - _uptime += duration - } else if (state == HostState.DOWN && scope.isActive) { - // Only increment downtime if the machine is in a failure state - _downtime += duration - } + private fun collectUptime(result: ObservableLongMeasurement) { + updateUptime() - result?.observe(_uptime, _upState) - result?.observe(_downtime, _downState) + result.observe(_uptime, _upState) + result.observe(_downtime, _downState) for (guest in guests.values) { - guest.collectUptime(duration, result) + guest.collectUptime(result) } } @@ -496,9 +452,9 @@ public class SimHost( /** * Helper function to track the boot time of a machine. */ - private fun collectBootTime(result: ObservableLongMeasurement? = null) { + private fun collectBootTime(result: ObservableLongMeasurement) { if (_bootTime != Long.MIN_VALUE) { - result?.observe(_bootTime) + result.observe(_bootTime) } for (guest in guests.values) { diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index eda76ba0..3ac165c8 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -33,12 +33,10 @@ import org.opendc.compute.api.Server import org.opendc.compute.api.ServerState import org.opendc.compute.simulator.SimHost import org.opendc.compute.simulator.SimWorkloadMapper -import org.opendc.simulator.compute.SimAbstractMachine -import org.opendc.simulator.compute.SimMachine +import org.opendc.simulator.compute.kernel.SimVirtualMachine import org.opendc.simulator.compute.workload.SimWorkload import java.time.Clock import kotlin.coroutines.CoroutineContext -import kotlin.math.roundToLong /** * A virtual machine instance that is managed by a [SimHost]. @@ -50,7 +48,7 @@ internal class Guest( private val mapper: SimWorkloadMapper, private val listener: GuestListener, val server: Server, - val machine: SimMachine + val machine: SimVirtualMachine ) { /** * The [CoroutineScope] of the guest. @@ -236,17 +234,22 @@ internal class Guest( .build() /** - * Helper function to track the uptime of the guest. + * Helper function to track the uptime and downtime of the guest. */ - fun collectUptime(duration: Long, result: ObservableLongMeasurement? = null) { + fun updateUptime(duration: Long) { if (state == ServerState.RUNNING) { _uptime += duration } else if (state == ServerState.ERROR) { _downtime += duration } + } - result?.observe(_uptime, _upState) - result?.observe(_downtime, _downState) + /** + * Helper function to track the uptime of the guest. + */ + fun collectUptime(result: ObservableLongMeasurement) { + result.observe(_uptime, _upState) + result.observe(_downtime, _downState) } private var _bootTime = Long.MIN_VALUE @@ -254,9 +257,9 @@ internal class Guest( /** * Helper function to track the boot time of the guest. */ - fun collectBootTime(result: ObservableLongMeasurement? = null) { + fun collectBootTime(result: ObservableLongMeasurement) { if (_bootTime != Long.MIN_VALUE) { - result?.observe(_bootTime) + result.observe(_bootTime) } } @@ -276,33 +279,17 @@ internal class Guest( .putAll(attributes) .put(STATE_KEY, "idle") .build() - private var _totalTime = 0.0 /** * Helper function to track the CPU time of a machine. */ - fun collectCpuTime(duration: Long, result: ObservableLongMeasurement) { - val coreCount = server.flavor.cpuCount - val d = coreCount / _cpuLimit - - var grantedWork = 0.0 - var overcommittedWork = 0.0 - - for (cpu in (machine as SimAbstractMachine).cpus) { - val counters = cpu.counters - grantedWork += counters.actual - overcommittedWork += counters.overcommit - } - - _totalTime += (duration / 1000.0) * coreCount - val activeTime = (grantedWork * d).roundToLong() - val idleTime = (_totalTime - grantedWork * d).roundToLong() - val stealTime = (overcommittedWork * d).roundToLong() + fun collectCpuTime(result: ObservableLongMeasurement) { + val counters = machine.counters - result.observe(activeTime, _activeState) - result.observe(idleTime, _idleState) - result.observe(stealTime, _stealState) - result.observe(0, _lostState) + result.observe(counters.cpuActiveTime / 1000, _activeState) + result.observe(counters.cpuIdleTime / 1000, _idleState) + result.observe(counters.cpuStealTime / 1000, _stealState) + result.observe(counters.cpuLostTime / 1000, _lostState) } private val _cpuLimit = machine.model.cpus.sumOf { it.frequency } diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index d2293be7..26089b6d 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -170,9 +170,9 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(659, activeTime, "Active time does not match") }, - { assertEquals(2342, idleTime, "Idle time does not match") }, - { assertEquals(638, stealTime, "Steal time does not match") }, + { assertEquals(658, activeTime, "Active time does not match") }, + { assertEquals(1741, idleTime, "Idle time does not match") }, + { assertEquals(637, stealTime, "Steal time does not match") }, { assertEquals(1500001, clock.millis()) } ) } @@ -253,7 +253,7 @@ internal class SimHostTest { host.spawn(server) delay(5000L) host.fail() - delay(5000L) + delay(duration * 1000) host.recover() suspendCancellableCoroutine { cont -> @@ -274,12 +274,12 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(2661, idleTime, "Idle time does not match") }, - { assertEquals(339, activeTime, "Active time does not match") }, - { assertEquals(1195001, uptime, "Uptime does not match") }, - { assertEquals(5000, downtime, "Downtime does not match") }, - { assertEquals(1195000, guestUptime, "Guest uptime does not match") }, - { assertEquals(5000, guestDowntime, "Guest downtime does not match") }, + { assertEquals(1175, idleTime, "Idle time does not match") }, + { assertEquals(624, activeTime, "Active time does not match") }, + { assertEquals(900001, uptime, "Uptime does not match") }, + { assertEquals(300000, downtime, "Downtime does not match") }, + { assertEquals(900000, guestUptime, "Guest uptime does not match") }, + { assertEquals(300000, guestDowntime, "Guest downtime does not match") }, ) } diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 67d39ffa..9d540118 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -116,11 +116,11 @@ class CapelinIntegrationTest { { assertEquals(0, serviceMetrics.serversActive, "All VMs should finish after a run") }, { assertEquals(0, serviceMetrics.attemptsFailure, "No VM should be unscheduled") }, { assertEquals(0, serviceMetrics.serversPending, "No VM should not be in the queue") }, - { assertEquals(223327751, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, - { assertEquals(67009849, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, - { assertEquals(3155964, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, + { assertEquals(223325655, this@CapelinIntegrationTest.exporter.idleTime) { "Incorrect idle time" } }, + { assertEquals(67006560, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, + { assertEquals(3159377, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Incorrect lost time" } }, - { assertEquals(5.841120890240688E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, + { assertEquals(5.840207707767459E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, ) } @@ -160,10 +160,11 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(10998184, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(9740216, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(10997726, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9740289, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } }, + { assertEquals(7.009945802750012E8, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } } ) } @@ -209,9 +210,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(6009751, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(14728649, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, - { assertEquals(12526520, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(6013515, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(14724500, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(480866, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } @@ -252,9 +253,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(11133606, exporter.idleTime) { "Idle time incorrect" } }, - { assertEquals(9604794, exporter.activeTime) { "Active time incorrect" } }, - { assertEquals(1311, exporter.stealTime) { "Steal time incorrect" } }, + { assertEquals(10865478, exporter.idleTime) { "Idle time incorrect" } }, + { assertEquals(9606177, exporter.activeTime) { "Active time incorrect" } }, + { assertEquals(0, exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(0, exporter.lostTime) { "Lost time incorrect" } }, { assertEquals(2559005056, exporter.uptime) { "Uptime incorrect" } } ) diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index c57919c1..d654d58a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -92,7 +92,7 @@ class SimMachineBenchmarks { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(engine) + val hypervisor = SimSpaceSharedHypervisor(engine, null, null) launch { machine.run(hypervisor) } @@ -113,7 +113,7 @@ class SimMachineBenchmarks { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(engine) + val hypervisor = SimFairShareHypervisor(engine, null, null, null) launch { machine.run(hypervisor) } @@ -134,7 +134,7 @@ class SimMachineBenchmarks { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(engine) + val hypervisor = SimFairShareHypervisor(engine, null, null, null) launch { machine.run(hypervisor) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt index 0bcf5957..9140d31b 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt @@ -28,6 +28,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.flow.* import org.opendc.simulator.flow.FlowEngine +import kotlin.math.max /** * A simulated bare-metal machine that is able to run a single workload. @@ -49,10 +50,18 @@ public class SimBareMetalMachine( parent: FlowConvergenceListener? = null, ) : SimAbstractMachine(engine, parent, model) { /** - * The power draw of the machine onto the PSU. + * The current power usage of the machine (without PSU loss) in W. */ - public val powerDraw: Double - get() = powerDriverLogic.computePower() + public val powerUsage: Double + get() = _powerUsage + private var _powerUsage = 0.0 + + /** + * The total energy usage of the machine (without PSU loss) in Joules. + */ + public val energyUsage: Double + get() = _energyUsage + private var _energyUsage = 0.0 /** * The processing units of the machine. @@ -66,8 +75,20 @@ public class SimBareMetalMachine( */ private val powerDriverLogic = powerDriver.createLogic(this, cpus) + private var _lastConverge = Long.MAX_VALUE + override fun onConverge(now: Long, delta: Long) { + // Update the PSU stage psu.update() + + val lastConverge = _lastConverge + _lastConverge = now + val duration = max(0, now - lastConverge) + if (duration > 0) { + // Compute the power and energy usage of the machine + _energyUsage += _powerUsage * (duration / 1000.0) + _powerUsage = powerDriverLogic.computePower() + } } init { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index bcba8e8e..aac8b959 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -30,6 +30,7 @@ import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.flow.* import org.opendc.simulator.flow.mux.FlowMultiplexer +import kotlin.math.roundToLong /** * Abstract implementation of the [SimHypervisor] interface. @@ -39,18 +40,19 @@ import org.opendc.simulator.flow.mux.FlowMultiplexer */ public abstract class SimAbstractHypervisor( protected val engine: FlowEngine, - private val scalingGovernor: ScalingGovernor? = null, + private val listener: FlowConvergenceListener?, + private val scalingGovernor: ScalingGovernor?, protected val interferenceDomain: VmInterferenceDomain? = null -) : SimHypervisor { +) : SimHypervisor, FlowConvergenceListener { /** * The machine on which the hypervisor runs. */ - private lateinit var context: SimMachineContext + protected lateinit var context: SimMachineContext /** * The resource switch to use. */ - private lateinit var mux: FlowMultiplexer + protected abstract val mux: FlowMultiplexer /** * The virtual machines running on this hypervisor. @@ -62,39 +64,73 @@ public abstract class SimAbstractHypervisor( /** * The resource counters associated with the hypervisor. */ - public override val counters: FlowCounters - get() = mux.counters + public override val counters: SimHypervisorCounters + get() = _counters + private val _counters = object : SimHypervisorCounters { + @JvmField var d = 1.0 // Number of CPUs divided by total CPU capacity + + override var cpuActiveTime: Long = 0L + override var cpuIdleTime: Long = 0L + override var cpuStealTime: Long = 0L + override var cpuLostTime: Long = 0L + + private var _previousDemand = 0.0 + private var _previousActual = 0.0 + private var _previousRemaining = 0.0 + private var _previousInterference = 0.0 + + /** + * Record the CPU time of the hypervisor. + */ + fun record() { + val counters = mux.counters + val demand = counters.demand + val actual = counters.actual + val remaining = counters.remaining + val interference = counters.interference + + val demandDelta = demand - _previousDemand + val actualDelta = actual - _previousActual + val remainingDelta = remaining - _previousRemaining + val interferenceDelta = interference - _previousInterference + + _previousDemand = demand + _previousActual = actual + _previousRemaining = remaining + _previousInterference = interference + + cpuActiveTime += (actualDelta * d).roundToLong() + cpuIdleTime += (remainingDelta * d).roundToLong() + cpuStealTime += ((demandDelta - actualDelta) * d).roundToLong() + cpuLostTime += (interferenceDelta * d).roundToLong() + } + } /** - * The scaling governors attached to the physical CPUs backing this hypervisor. + * The CPU capacity of the hypervisor in MHz. */ - private val governors = mutableListOf() + override val cpuCapacity: Double + get() = mux.capacity /** - * Construct the [FlowMultiplexer] implementation that performs the actual scheduling of the CPUs. + * The CPU demand of the hypervisor in MHz. */ - public abstract fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer + override val cpuDemand: Double + get() = mux.demand /** - * Check whether the specified machine model fits on this hypervisor. + * The CPU usage of the hypervisor in MHz. */ - public abstract fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean + override val cpuUsage: Double + get() = mux.rate /** - * Trigger the governors to recompute the scaling limits. + * The scaling governors attached to the physical CPUs backing this hypervisor. */ - protected fun triggerGovernors(load: Double) { - for (governor in governors) { - governor.onLimit(load) - } - } + private val governors = mutableListOf() /* SimHypervisor */ - override fun canFit(model: MachineModel): Boolean { - return canFit(model, mux) - } - - override fun createMachine(model: MachineModel, interferenceId: String?): SimMachine { + override fun createMachine(model: MachineModel, interferenceId: String?): SimVirtualMachine { require(canFit(model)) { "Machine does not fit" } val vm = VirtualMachine(model, interferenceId) _vms.add(vm) @@ -104,7 +140,13 @@ public abstract class SimAbstractHypervisor( /* SimWorkload */ override fun onStart(ctx: SimMachineContext) { context = ctx - mux = createMultiplexer(ctx) + + _cpuCount = ctx.cpus.size + _cpuCapacity = ctx.cpus.sumOf { it.model.frequency } + _counters.d = _cpuCount / _cpuCapacity * 1000L + + // Clear the existing outputs of the multiplexer + mux.clearOutputs() for (cpu in ctx.cpus) { val governor = scalingGovernor?.createLogic(ScalingPolicyImpl(cpu)) @@ -113,16 +155,31 @@ public abstract class SimAbstractHypervisor( governor.onStart() } - mux.addOutput(cpu) + cpu.startConsumer(mux.newOutput()) } } + private var _cpuCount = 0 + private var _cpuCapacity = 0.0 + + /* FlowConvergenceListener */ + override fun onConverge(now: Long, delta: Long) { + _counters.record() + + val load = cpuDemand / cpuCapacity + for (governor in governors) { + governor.onLimit(load) + } + + listener?.onConverge(now, delta) + } + /** * A virtual machine running on the hypervisor. * * @param model The machine model of the virtual machine. */ - private inner class VirtualMachine(model: MachineModel, interferenceId: String? = null) : SimAbstractMachine(engine, parent = null, model) { + private inner class VirtualMachine(model: MachineModel, interferenceId: String? = null) : SimAbstractMachine(engine, parent = null, model), SimVirtualMachine { /** * The interference key of this virtual machine. */ @@ -133,6 +190,41 @@ public abstract class SimAbstractHypervisor( */ override val cpus = model.cpus.map { VCpu(mux, mux.newInput(interferenceKey), it) } + /** + * The resource counters associated with the hypervisor. + */ + override val counters: SimHypervisorCounters + get() = _counters + private val _counters = object : SimHypervisorCounters { + private val d = cpus.size / cpus.sumOf { it.model.frequency } * 1000 + + override val cpuActiveTime: Long + get() = (cpus.sumOf { it.counters.actual } * d).roundToLong() + override val cpuIdleTime: Long + get() = (cpus.sumOf { it.counters.actual + it.counters.remaining } * d).roundToLong() + override val cpuStealTime: Long + get() = (cpus.sumOf { it.counters.demand - it.counters.actual } * d).roundToLong() + override val cpuLostTime: Long = 0L + } + + /** + * The CPU capacity of the hypervisor in MHz. + */ + override val cpuCapacity: Double + get() = cpus.sumOf(FlowConsumer::capacity) + + /** + * The CPU demand of the hypervisor in MHz. + */ + override val cpuDemand: Double + get() = cpus.sumOf(FlowConsumer::demand) + + /** + * The CPU usage of the hypervisor in MHz. + */ + override val cpuUsage: Double + get() = cpus.sumOf(FlowConsumer::rate) + override fun close() { super.close() diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index b0515c6e..36f76650 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.SimMachine -import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain import org.opendc.simulator.compute.model.MachineModel @@ -38,64 +37,20 @@ import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer * concurrently using weighted fair sharing. * * @param engine The [FlowEngine] to manage the machine's resources. - * @param parent The parent simulation system. + * @param listener The listener for the convergence of the system. * @param scalingGovernor The CPU frequency scaling governor to use for the hypervisor. * @param interferenceDomain The resource interference domain to which the hypervisor belongs. - * @param listener The hypervisor listener to use. */ public class SimFairShareHypervisor( engine: FlowEngine, - private val parent: FlowConvergenceListener? = null, - scalingGovernor: ScalingGovernor? = null, - interferenceDomain: VmInterferenceDomain? = null, - private val listener: SimHypervisor.Listener? = null -) : SimAbstractHypervisor(engine, scalingGovernor, interferenceDomain) { - - override fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean = true - - override fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer { - return SwitchSystem(ctx).switch - } - - private inner class SwitchSystem(private val ctx: SimMachineContext) : FlowConvergenceListener { - val switch = MaxMinFlowMultiplexer(engine, this, interferenceDomain) - - private var lastCpuUsage = 0.0 - private var lastCpuDemand = 0.0 - private var lastDemand = 0.0 - private var lastActual = 0.0 - private var lastOvercommit = 0.0 - private var lastInterference = 0.0 - private var lastReport = Long.MIN_VALUE - - override fun onConverge(now: Long, delta: Long) { - val listener = listener ?: return - val counters = switch.counters - - if (now > lastReport) { - listener.onSliceFinish( - this@SimFairShareHypervisor, - counters.demand - lastDemand, - counters.actual - lastActual, - counters.overcommit - lastOvercommit, - counters.interference - lastInterference, - lastCpuUsage, - lastCpuDemand - ) - } - lastReport = now - - lastCpuDemand = switch.outputs.sumOf { it.demand } - lastCpuUsage = switch.outputs.sumOf { it.rate } - lastDemand = counters.demand - lastActual = counters.actual - lastOvercommit = counters.overcommit - lastInterference = counters.interference - - val load = lastCpuDemand / ctx.cpus.sumOf { it.model.frequency } - triggerGovernors(load) - - parent?.onConverge(now, delta) - } - } + listener: FlowConvergenceListener?, + scalingGovernor: ScalingGovernor?, + interferenceDomain: VmInterferenceDomain?, +) : SimAbstractHypervisor(engine, listener, scalingGovernor, interferenceDomain) { + /** + * The multiplexer that distributes the computing capacity. + */ + override val mux: FlowMultiplexer = MaxMinFlowMultiplexer(engine, this, interferenceDomain) + + override fun canFit(model: MachineModel): Boolean = true } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt index e0a70926..3136f4c8 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt @@ -35,15 +35,8 @@ public class SimFairShareHypervisorProvider : SimHypervisorProvider { override fun create( engine: FlowEngine, - parent: FlowConvergenceListener?, + listener: FlowConvergenceListener?, scalingGovernor: ScalingGovernor?, interferenceDomain: VmInterferenceDomain?, - listener: SimHypervisor.Listener? - ): SimHypervisor = SimFairShareHypervisor( - engine, - parent, - scalingGovernor = scalingGovernor, - interferenceDomain = interferenceDomain, - listener = listener - ) + ): SimHypervisor = SimFairShareHypervisor(engine, listener, scalingGovernor, interferenceDomain) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt index 1b11ca6b..57d4cf20 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt @@ -25,7 +25,6 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.SimMachine import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.flow.FlowCounters /** * A SimHypervisor facilitates the execution of multiple concurrent [SimWorkload]s, while acting as a single workload @@ -40,7 +39,22 @@ public interface SimHypervisor : SimWorkload { /** * The resource counters associated with the hypervisor. */ - public val counters: FlowCounters + public val counters: SimHypervisorCounters + + /** + * The CPU usage of the hypervisor in MHz. + */ + public val cpuUsage: Double + + /** + * The CPU usage of the hypervisor in MHz. + */ + public val cpuDemand: Double + + /** + * The CPU capacity of the hypervisor in MHz. + */ + public val cpuCapacity: Double /** * Determine whether the specified machine characterized by [model] can fit on this hypervisor at this moment. @@ -53,23 +67,5 @@ public interface SimHypervisor : SimWorkload { * @param model The machine to create. * @param interferenceId An identifier for the interference model. */ - public fun createMachine(model: MachineModel, interferenceId: String? = null): SimMachine - - /** - * Event listener for hypervisor events. - */ - public interface Listener { - /** - * This method is invoked when a slice is finished. - */ - public fun onSliceFinish( - hypervisor: SimHypervisor, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double - ) - } + public fun createMachine(model: MachineModel, interferenceId: String? = null): SimVirtualMachine } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt new file mode 100644 index 00000000..030d9c5f --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.compute.kernel + +/** + * Performance counters of a [SimHypervisor]. + */ +public interface SimHypervisorCounters { + /** + * The amount of time (in milliseconds) the CPUs of the hypervisor were actively running. + */ + public val cpuActiveTime: Long + + /** + * The amount of time (in milliseconds) the CPUs of the hypervisor were idle. + */ + public val cpuIdleTime: Long + + /** + * The amount of CPU time (in milliseconds) that virtual machines were ready to run, but were not able to. + */ + public val cpuStealTime: Long + + /** + * The amount of CPU time (in milliseconds) that was lost due to interference between virtual machines. + */ + public val cpuLostTime: Long +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt index dad2cc3b..483217af 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt @@ -40,13 +40,12 @@ public interface SimHypervisorProvider { public val id: String /** - * Create a [SimHypervisor] instance with the specified [listener]. + * Create a new [SimHypervisor] instance. */ public fun create( engine: FlowEngine, - parent: FlowConvergenceListener? = null, + listener: FlowConvergenceListener? = null, scalingGovernor: ScalingGovernor? = null, interferenceDomain: VmInterferenceDomain? = null, - listener: SimHypervisor.Listener? = null ): SimHypervisor } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt index 883e0d82..82f8df38 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt @@ -22,8 +22,9 @@ package org.opendc.simulator.compute.kernel -import org.opendc.simulator.compute.SimMachineContext +import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.flow.FlowConvergenceListener import org.opendc.simulator.flow.FlowEngine import org.opendc.simulator.flow.mux.FlowMultiplexer import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer @@ -31,12 +32,14 @@ import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer /** * A [SimHypervisor] that allocates its sub-resources exclusively for the virtual machine that it hosts. */ -public class SimSpaceSharedHypervisor(engine: FlowEngine) : SimAbstractHypervisor(engine) { - override fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean { - return switch.outputs.size - switch.inputs.size >= model.cpus.size - } +public class SimSpaceSharedHypervisor( + engine: FlowEngine, + listener: FlowConvergenceListener?, + scalingGovernor: ScalingGovernor?, +) : SimAbstractHypervisor(engine, listener, scalingGovernor) { + override val mux: FlowMultiplexer = ForwardingFlowMultiplexer(engine) - override fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer { - return ForwardingFlowMultiplexer(engine) + override fun canFit(model: MachineModel): Boolean { + return mux.outputs.size - mux.inputs.size >= model.cpus.size } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt index 93921eb9..dd6fb0b1 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt @@ -35,9 +35,8 @@ public class SimSpaceSharedHypervisorProvider : SimHypervisorProvider { override fun create( engine: FlowEngine, - parent: FlowConvergenceListener?, + listener: FlowConvergenceListener?, scalingGovernor: ScalingGovernor?, interferenceDomain: VmInterferenceDomain?, - listener: SimHypervisor.Listener? - ): SimHypervisor = SimSpaceSharedHypervisor(engine) + ): SimHypervisor = SimSpaceSharedHypervisor(engine, listener, scalingGovernor) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt new file mode 100644 index 00000000..36219ef2 --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.compute.kernel + +import org.opendc.simulator.compute.SimMachine + +/** + * A virtual [SimMachine] running on top of another [SimMachine]. + */ +public interface SimVirtualMachine : SimMachine { + /** + * The resource counters associated with the virtual machine. + */ + public val counters: SimHypervisorCounters + + /** + * The CPU usage of the VM in MHz. + */ + public val cpuUsage: Double + + /** + * The CPU usage of the VM in MHz. + */ + public val cpuDemand: Double + + /** + * The CPU capacity of the VM in MHz. + */ + public val cpuCapacity: Double +} diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt new file mode 100644 index 00000000..9db2e6ec --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.compute.kernel + +import kotlinx.coroutines.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.junit.jupiter.api.assertDoesNotThrow +import org.opendc.simulator.compute.SimBareMetalMachine +import org.opendc.simulator.compute.kernel.cpufreq.PerformanceScalingGovernor +import org.opendc.simulator.compute.kernel.interference.VmInterferenceGroup +import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel +import org.opendc.simulator.compute.model.MachineModel +import org.opendc.simulator.compute.model.MemoryUnit +import org.opendc.simulator.compute.model.ProcessingNode +import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.compute.power.ConstantPowerModel +import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.FlowEngine + +/** + * Test suite for the [SimHypervisor] class. + */ +@OptIn(ExperimentalCoroutinesApi::class) +internal class SimFairShareHypervisorTest { + private lateinit var model: MachineModel + + @BeforeEach + fun setUp() { + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 1) + model = MachineModel( + cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, + memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } + ) + } + + /** + * Test overcommitting of resources via the hypervisor with a single VM. + */ + @Test + fun testOvercommittedSingle() = runBlockingSimulation { + val duration = 5 * 60L + val workloadA = + SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + ), + ) + + val platform = FlowEngine(coroutineContext, clock) + val machine = SimBareMetalMachine(platform, model, SimplePowerDriver(ConstantPowerModel(0.0))) + val hypervisor = SimFairShareHypervisor(platform, null, PerformanceScalingGovernor(), null) + + launch { + machine.run(hypervisor) + println("Hypervisor finished") + } + yield() + + val vm = hypervisor.createMachine(model) + vm.run(workloadA) + + yield() + machine.close() + + assertAll( + { assertEquals(319781, hypervisor.counters.cpuActiveTime, "Active time does not match") }, + { assertEquals(880219, hypervisor.counters.cpuIdleTime, "Idle time does not match") }, + { assertEquals(28125, hypervisor.counters.cpuStealTime, "Steal time does not match") }, + { assertEquals(1200000, clock.millis()) { "Current time is correct" } } + ) + } + + /** + * Test overcommitting of resources via the hypervisor with two VMs. + */ + @Test + fun testOvercommittedDual() = runBlockingSimulation { + val duration = 5 * 60L + val workloadA = + SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + ), + ) + val workloadB = + SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3100.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) + ) + ) + + val platform = FlowEngine(coroutineContext, clock) + val machine = SimBareMetalMachine( + platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) + ) + val hypervisor = SimFairShareHypervisor(platform, null, null, null) + + launch { + machine.run(hypervisor) + } + + yield() + coroutineScope { + launch { + val vm = hypervisor.createMachine(model) + vm.run(workloadA) + vm.close() + } + val vm = hypervisor.createMachine(model) + vm.run(workloadB) + vm.close() + } + yield() + machine.close() + yield() + + assertAll( + { assertEquals(329250, hypervisor.counters.cpuActiveTime, "Active time does not match") }, + { assertEquals(870750, hypervisor.counters.cpuIdleTime, "Idle time does not match") }, + { assertEquals(318750, hypervisor.counters.cpuStealTime, "Steal time does not match") }, + { assertEquals(1200000, clock.millis()) } + ) + } + + @Test + fun testMultipleCPUs() = runBlockingSimulation { + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) + val model = MachineModel( + cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, + memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } + ) + + val platform = FlowEngine(coroutineContext, clock) + val machine = SimBareMetalMachine(platform, model, SimplePowerDriver(ConstantPowerModel(0.0))) + val hypervisor = SimFairShareHypervisor(platform, null, null, null) + + assertDoesNotThrow { + launch { + machine.run(hypervisor) + } + } + + machine.close() + } + + @Test + fun testInterference() = runBlockingSimulation { + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) + val model = MachineModel( + cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, + memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } + ) + + val groups = listOf( + VmInterferenceGroup(targetLoad = 0.0, score = 0.9, members = setOf("a", "b")), + VmInterferenceGroup(targetLoad = 0.0, score = 0.6, members = setOf("a", "c")), + VmInterferenceGroup(targetLoad = 0.1, score = 0.8, members = setOf("a", "n")) + ) + val interferenceModel = VmInterferenceModel(groups) + + val platform = FlowEngine(coroutineContext, clock) + val machine = SimBareMetalMachine( + platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) + ) + val hypervisor = SimFairShareHypervisor(platform, null, null, interferenceModel.newDomain()) + + val duration = 5 * 60L + val workloadA = + SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3500.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + ), + ) + val workloadB = + SimTraceWorkload( + sequenceOf( + SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), + SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), + SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3100.0, 1), + SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) + ) + ) + + launch { + machine.run(hypervisor) + } + + coroutineScope { + launch { + val vm = hypervisor.createMachine(model, "a") + vm.run(workloadA) + vm.close() + } + val vm = hypervisor.createMachine(model, "b") + vm.run(workloadB) + vm.close() + } + + machine.close() + } +} diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt deleted file mode 100644 index 058d5d28..00000000 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.compute.kernel - -import kotlinx.coroutines.* -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.junit.jupiter.api.assertDoesNotThrow -import org.opendc.simulator.compute.SimBareMetalMachine -import org.opendc.simulator.compute.kernel.cpufreq.PerformanceScalingGovernor -import org.opendc.simulator.compute.kernel.interference.VmInterferenceGroup -import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.compute.power.ConstantPowerModel -import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.flow.FlowEngine - -/** - * Test suite for the [SimHypervisor] class. - */ -@OptIn(ExperimentalCoroutinesApi::class) -internal class SimHypervisorTest { - private lateinit var model: MachineModel - - @BeforeEach - fun setUp() { - val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 1) - model = MachineModel( - cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, - memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } - ) - } - - /** - * Test overcommitting of resources via the hypervisor with a single VM. - */ - @Test - fun testOvercommittedSingle() = runBlockingSimulation { - val listener = object : SimHypervisor.Listener { - var totalRequestedWork = 0.0 - var totalGrantedWork = 0.0 - var totalOvercommittedWork = 0.0 - - override fun onSliceFinish( - hypervisor: SimHypervisor, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double - ) { - totalRequestedWork += totalWork - totalGrantedWork += grantedWork - totalOvercommittedWork += overcommittedWork - } - } - - val duration = 5 * 60L - val workloadA = - SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) - ), - ) - - val platform = FlowEngine(coroutineContext, clock) - val machine = SimBareMetalMachine(platform, model, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimFairShareHypervisor(platform, scalingGovernor = PerformanceScalingGovernor(), listener = listener) - - launch { - machine.run(hypervisor) - println("Hypervisor finished") - } - yield() - - val vm = hypervisor.createMachine(model) - vm.run(workloadA) - - yield() - machine.close() - - assertAll( - { assertEquals(1113300.0, listener.totalRequestedWork, "Requested Burst does not match") }, - { assertEquals(1023300.0, listener.totalGrantedWork, "Granted Burst does not match") }, - { assertEquals(90000.0, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, - { assertEquals(1200000, clock.millis()) { "Current time is correct" } } - ) - } - - /** - * Test overcommitting of resources via the hypervisor with two VMs. - */ - @Test - fun testOvercommittedDual() = runBlockingSimulation { - val listener = object : SimHypervisor.Listener { - var totalRequestedWork = 0.0 - var totalGrantedWork = 0.0 - var totalOvercommittedWork = 0.0 - - override fun onSliceFinish( - hypervisor: SimHypervisor, - totalWork: Double, - grantedWork: Double, - overcommittedWork: Double, - interferedWork: Double, - cpuUsage: Double, - cpuDemand: Double - ) { - totalRequestedWork += totalWork - totalGrantedWork += grantedWork - totalOvercommittedWork += overcommittedWork - } - } - - val duration = 5 * 60L - val workloadA = - SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) - ), - ) - val workloadB = - SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3100.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) - ) - ) - - val platform = FlowEngine(coroutineContext, clock) - val machine = SimBareMetalMachine( - platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) - ) - val hypervisor = SimFairShareHypervisor(platform, listener = listener) - - launch { - machine.run(hypervisor) - } - - yield() - coroutineScope { - launch { - val vm = hypervisor.createMachine(model) - vm.run(workloadA) - vm.close() - } - val vm = hypervisor.createMachine(model) - vm.run(workloadB) - vm.close() - } - yield() - machine.close() - yield() - - assertAll( - { assertEquals(2073600.0, listener.totalRequestedWork, "Requested Burst does not match") }, - { assertEquals(1053600.0, listener.totalGrantedWork, "Granted Burst does not match") }, - { assertEquals(1020000.0, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, - { assertEquals(1200000, clock.millis()) } - ) - } - - @Test - fun testMultipleCPUs() = runBlockingSimulation { - val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - val model = MachineModel( - cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, - memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } - ) - - val platform = FlowEngine(coroutineContext, clock) - val machine = SimBareMetalMachine( - platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) - ) - val hypervisor = SimFairShareHypervisor(platform) - - assertDoesNotThrow { - launch { - machine.run(hypervisor) - } - } - - machine.close() - } - - @Test - fun testInterference() = runBlockingSimulation { - val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - val model = MachineModel( - cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, - memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } - ) - - val groups = listOf( - VmInterferenceGroup(targetLoad = 0.0, score = 0.9, members = setOf("a", "b")), - VmInterferenceGroup(targetLoad = 0.0, score = 0.6, members = setOf("a", "c")), - VmInterferenceGroup(targetLoad = 0.1, score = 0.8, members = setOf("a", "n")) - ) - val interferenceModel = VmInterferenceModel(groups) - - val platform = FlowEngine(coroutineContext, clock) - val machine = SimBareMetalMachine( - platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) - ) - val hypervisor = SimFairShareHypervisor(platform, interferenceDomain = interferenceModel.newDomain()) - - val duration = 5 * 60L - val workloadA = - SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) - ), - ) - val workloadB = - SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3100.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) - ) - ) - - launch { - machine.run(hypervisor) - } - - coroutineScope { - launch { - val vm = hypervisor.createMachine(model, "a") - vm.run(workloadA) - vm.close() - } - val vm = hypervisor.createMachine(model, "b") - vm.run(workloadB) - vm.close() - } - - machine.close() - } -} diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index 95fb6679..b05ffd22 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -75,10 +75,8 @@ internal class SimSpaceSharedHypervisorTest { ) val engine = FlowEngine(coroutineContext, clock) - val machine = SimBareMetalMachine( - FlowEngine(coroutineContext, clock), machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) - ) - val hypervisor = SimSpaceSharedHypervisor(engine) + val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) + val hypervisor = SimSpaceSharedHypervisor(engine, null, null) launch { machine.run(hypervisor) } val vm = hypervisor.createMachine(machineModel) @@ -99,10 +97,8 @@ internal class SimSpaceSharedHypervisorTest { val duration = 5 * 60L * 1000 val workload = SimRuntimeWorkload(duration) val engine = FlowEngine(coroutineContext, clock) - val machine = SimBareMetalMachine( - engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) - ) - val hypervisor = SimSpaceSharedHypervisor(engine) + val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) + val hypervisor = SimSpaceSharedHypervisor(engine, null, null) launch { machine.run(hypervisor) } yield() @@ -125,7 +121,7 @@ internal class SimSpaceSharedHypervisorTest { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(engine) + val hypervisor = SimSpaceSharedHypervisor(engine, null, null) launch { machine.run(hypervisor) } yield() @@ -146,7 +142,7 @@ internal class SimSpaceSharedHypervisorTest { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(engine) + val hypervisor = SimSpaceSharedHypervisor(engine, null, null) launch { machine.run(hypervisor) } yield() @@ -172,7 +168,7 @@ internal class SimSpaceSharedHypervisorTest { fun testConcurrentWorkloadFails() = runBlockingSimulation { val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimSpaceSharedHypervisor(engine) + val hypervisor = SimSpaceSharedHypervisor(engine, null, null) launch { machine.run(hypervisor) } yield() @@ -196,7 +192,7 @@ internal class SimSpaceSharedHypervisorTest { val machine = SimBareMetalMachine( interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter) + val hypervisor = SimSpaceSharedHypervisor(interpreter, null, null) launch { machine.run(hypervisor) } yield() diff --git a/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt b/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt index 4834f10f..e927f81d 100644 --- a/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt @@ -83,8 +83,8 @@ class FlowBenchmarks { return scope.runBlockingSimulation { val switch = MaxMinFlowMultiplexer(engine) - switch.addOutput(FlowSink(engine, 3000.0)) - switch.addOutput(FlowSink(engine, 3000.0)) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) val provider = switch.newInput() return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) @@ -96,8 +96,8 @@ class FlowBenchmarks { return scope.runBlockingSimulation { val switch = MaxMinFlowMultiplexer(engine) - switch.addOutput(FlowSink(engine, 3000.0)) - switch.addOutput(FlowSink(engine, 3000.0)) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) repeat(3) { launch { @@ -113,8 +113,8 @@ class FlowBenchmarks { return scope.runBlockingSimulation { val switch = ForwardingFlowMultiplexer(engine) - switch.addOutput(FlowSink(engine, 3000.0)) - switch.addOutput(FlowSink(engine, 3000.0)) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) val provider = switch.newInput() return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) @@ -126,8 +126,8 @@ class FlowBenchmarks { return scope.runBlockingSimulation { val switch = ForwardingFlowMultiplexer(engine) - switch.addOutput(FlowSink(engine, 3000.0)) - switch.addOutput(FlowSink(engine, 3000.0)) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) + FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) repeat(2) { launch { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt index c8092082..b02426e3 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt @@ -83,14 +83,18 @@ public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initi /** * The previous demand for the consumer. */ - private var previousDemand = 0.0 + private var _previousDemand = 0.0 + private var _previousCapacity = 0.0 /** * Update the counters of the flow consumer. */ protected fun updateCounters(ctx: FlowConnection, delta: Long) { - val demand = previousDemand - previousDemand = ctx.demand + val demand = _previousDemand + val capacity = _previousCapacity + + _previousDemand = ctx.demand + _previousCapacity = ctx.capacity if (delta <= 0) { return @@ -98,23 +102,23 @@ public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initi val counters = _counters val deltaS = delta / 1000.0 - val work = demand * deltaS + val total = demand * deltaS + val work = capacity * deltaS val actualWork = ctx.rate * deltaS - val remainingWork = work - actualWork counters.demand += work counters.actual += actualWork - counters.overcommit += remainingWork + counters.remaining += (total - actualWork) } /** * Update the counters of the flow consumer. */ - protected fun updateCounters(demand: Double, actual: Double, overcommit: Double) { + protected fun updateCounters(demand: Double, actual: Double, remaining: Double) { val counters = _counters counters.demand += demand counters.actual += actual - counters.overcommit += overcommit + counters.remaining += remaining } final override fun startConsumer(source: FlowSource) { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt index e15d7643..a717ae6e 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowCounters.kt @@ -37,9 +37,9 @@ public interface FlowCounters { public val actual: Double /** - * The accumulated flow that could not be transferred over the connection. + * The amount of capacity that was not utilized. */ - public val overcommit: Double + public val remaining: Double /** * The accumulated flow lost due to interference between sources. diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index 17de601a..7eaaf6c2 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -242,10 +242,11 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled val counters = _counters val deltaS = delta / 1000.0 + val total = ctx.capacity * deltaS val work = _demand * deltaS val actualWork = ctx.rate * deltaS counters.demand += work counters.actual += actualWork - counters.overcommit += (work - actualWork) + counters.remaining += (total - actualWork) } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt index 141d335d..d2fa5228 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt @@ -30,17 +30,17 @@ import org.opendc.simulator.flow.FlowCounters internal class FlowCountersImpl : FlowCounters { override var demand: Double = 0.0 override var actual: Double = 0.0 - override var overcommit: Double = 0.0 + override var remaining: Double = 0.0 override var interference: Double = 0.0 override fun reset() { demand = 0.0 actual = 0.0 - overcommit = 0.0 + remaining = 0.0 interference = 0.0 } override fun toString(): String { - return "FlowCounters[demand=$demand,actual=$actual,overcommit=$overcommit,interference=$interference]" + return "FlowCounters[demand=$demand,actual=$actual,remaining=$remaining,interference=$interference]" } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt index 17b82391..04ba7f21 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt @@ -39,7 +39,22 @@ public interface FlowMultiplexer { /** * The outputs of the multiplexer over which the flows will be distributed. */ - public val outputs: Set + public val outputs: Set + + /** + * The actual processing rate of the multiplexer. + */ + public val rate: Double + + /** + * The demanded processing rate of the input. + */ + public val demand: Double + + /** + * The capacity of the outputs. + */ + public val capacity: Double /** * The flow counters to track the flow metrics of all multiplexer inputs. @@ -59,12 +74,27 @@ public interface FlowMultiplexer { public fun removeInput(input: FlowConsumer) /** - * Add the specified [output] to the multiplexer. + * Create a new output on this multiplexer. */ - public fun addOutput(output: FlowConsumer) + public fun newOutput(): FlowSource /** - * Clear all inputs and outputs from the switch. + * Remove [output] from this multiplexer. + */ + public fun removeOutput(output: FlowSource) + + /** + * Clear all inputs and outputs from the multiplexer. */ public fun clear() + + /** + * Clear the inputs of the multiplexer. + */ + public fun clearInputs() + + /** + * Clear the outputs of the multiplexer. + */ + public fun clearOutputs() } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt index 6dd9dcfb..125d10fe 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt @@ -38,35 +38,44 @@ public class ForwardingFlowMultiplexer(private val engine: FlowEngine) : FlowMul get() = _inputs private val _inputs = mutableSetOf() - override val outputs: Set + override val outputs: Set get() = _outputs - private val _outputs = mutableSetOf() - private val _availableOutputs = ArrayDeque() + private val _outputs = mutableSetOf() + private val _availableOutputs = ArrayDeque() override val counters: FlowCounters = object : FlowCounters { override val demand: Double - get() = _outputs.sumOf { it.counters.demand } + get() = _outputs.sumOf { it.forwarder.counters.demand } override val actual: Double - get() = _outputs.sumOf { it.counters.actual } - override val overcommit: Double - get() = _outputs.sumOf { it.counters.overcommit } + get() = _outputs.sumOf { it.forwarder.counters.actual } + override val remaining: Double + get() = _outputs.sumOf { it.forwarder.counters.remaining } override val interference: Double - get() = _outputs.sumOf { it.counters.interference } + get() = _outputs.sumOf { it.forwarder.counters.interference } override fun reset() { - for (input in _outputs) { - input.counters.reset() + for (output in _outputs) { + output.forwarder.counters.reset() } } - override fun toString(): String = "FlowCounters[demand=$demand,actual=$actual,overcommit=$overcommit]" + override fun toString(): String = "FlowCounters[demand=$demand,actual=$actual,remaining=$remaining]" } + override val rate: Double + get() = _outputs.sumOf { it.forwarder.rate } + + override val demand: Double + get() = _outputs.sumOf { it.forwarder.demand } + + override val capacity: Double + get() = _outputs.sumOf { it.forwarder.capacity } + override fun newInput(key: InterferenceKey?): FlowConsumer { - val forwarder = checkNotNull(_availableOutputs.poll()) { "No capacity to serve request" } - val output = Input(forwarder) - _inputs += output - return output + val output = checkNotNull(_availableOutputs.poll()) { "No capacity to serve request" } + val input = Input(output) + _inputs += input + return input } override fun removeInput(input: FlowConsumer) { @@ -74,51 +83,72 @@ public class ForwardingFlowMultiplexer(private val engine: FlowEngine) : FlowMul return } - (input as Input).close() + val output = (input as Input).output + output.forwarder.cancel() + _availableOutputs += output } - override fun addOutput(output: FlowConsumer) { - if (output in outputs) { - return - } - + override fun newOutput(): FlowSource { val forwarder = FlowForwarder(engine) + val output = Output(forwarder) _outputs += output - _availableOutputs += forwarder + return output + } - output.startConsumer(object : FlowSource by forwarder { - override fun onStop(conn: FlowConnection, now: Long, delta: Long) { - _outputs -= output + override fun removeOutput(output: FlowSource) { + if (!_outputs.remove(output)) { + return + } - forwarder.onStop(conn, now, delta) - } - }) + val forwarder = (output as Output).forwarder + forwarder.close() } - override fun clear() { - for (input in _outputs) { - input.cancel() + override fun clearInputs() { + for (input in _inputs) { + val output = input.output + output.forwarder.cancel() + _availableOutputs += output } - _outputs.clear() - // Inputs are implicitly cancelled by the output forwarders _inputs.clear() } + override fun clearOutputs() { + for (output in _outputs) { + output.forwarder.cancel() + } + _outputs.clear() + _availableOutputs.clear() + } + + override fun clear() { + clearOutputs() + clearInputs() + } + /** * An input on the multiplexer. */ - private inner class Input(private val forwarder: FlowForwarder) : FlowConsumer by forwarder { - /** - * Close the input. - */ - fun close() { - // We explicitly do not close the forwarder here in order to re-use it across input resources. - _inputs -= this - _availableOutputs += forwarder + private inner class Input(@JvmField val output: Output) : FlowConsumer by output.forwarder { + override fun toString(): String = "ForwardingFlowMultiplexer.Input" + } + + /** + * An output on the multiplexer. + */ + private inner class Output(@JvmField val forwarder: FlowForwarder) : FlowSource by forwarder { + override fun onStart(conn: FlowConnection, now: Long) { + _availableOutputs += this + forwarder.onStart(conn, now) } - override fun toString(): String = "ForwardingFlowMultiplexer.Input" + override fun onStop(conn: FlowConnection, now: Long, delta: Long) { + forwarder.cancel() + forwarder.onStop(conn, now, delta) + } + + override fun toString(): String = "ForwardingFlowMultiplexer.Output" } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 7232df35..5ff0fb8d 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -52,9 +52,9 @@ public class MaxMinFlowMultiplexer( /** * The outputs of the multiplexer. */ - override val outputs: Set + override val outputs: Set get() = _outputs - private val _outputs = mutableSetOf() + private val _outputs = mutableSetOf() private val _activeOutputs = mutableListOf() /** @@ -67,22 +67,35 @@ public class MaxMinFlowMultiplexer( /** * The actual processing rate of the multiplexer. */ + public override val rate: Double + get() = _rate private var _rate = 0.0 /** * The demanded processing rate of the input. */ + public override val demand: Double + get() = _demand private var _demand = 0.0 /** * The capacity of the outputs. */ + public override val capacity: Double + get() = _capacity private var _capacity = 0.0 /** * Flag to indicate that the scheduler is active. */ private var _schedulerActive = false + private var _lastSchedulerCycle = Long.MAX_VALUE + + /** + * The last convergence timestamp and the input. + */ + private var _lastConverge: Long = Long.MIN_VALUE + private var _lastConvergeInput: Input? = null override fun newInput(key: InterferenceKey?): FlowConsumer { val provider = Input(_capacity, key) @@ -90,14 +103,6 @@ public class MaxMinFlowMultiplexer( return provider } - override fun addOutput(output: FlowConsumer) { - val consumer = Output(output) - if (_outputs.add(output)) { - _activeOutputs.add(consumer) - output.startConsumer(consumer) - } - } - override fun removeInput(input: FlowConsumer) { if (!_inputs.remove(input)) { return @@ -106,16 +111,38 @@ public class MaxMinFlowMultiplexer( (input as Input).close() } - override fun clear() { - for (input in _activeOutputs) { + override fun newOutput(): FlowSource { + val output = Output() + _outputs.add(output) + return output + } + + override fun removeOutput(output: FlowSource) { + if (!_outputs.remove(output)) { + return + } + + // This cast should always succeed since only `Output` instances should be added to `_outputs` + (output as Output).cancel() + } + + override fun clearInputs() { + for (input in _inputs) { input.cancel() } - _activeOutputs.clear() + _inputs.clear() + } - for (output in _activeInputs) { + override fun clearOutputs() { + for (output in _outputs) { output.cancel() } - _activeInputs.clear() + _outputs.clear() + } + + override fun clear() { + clearOutputs() + clearInputs() } /** @@ -125,10 +152,13 @@ public class MaxMinFlowMultiplexer( if (_schedulerActive) { return } - + val lastSchedulerCycle = _lastSchedulerCycle + val delta = max(0, now - lastSchedulerCycle) _schedulerActive = true + _lastSchedulerCycle = now + try { - doSchedule(now) + doSchedule(now, delta) } finally { _schedulerActive = false } @@ -137,12 +167,17 @@ public class MaxMinFlowMultiplexer( /** * Schedule the inputs over the outputs. */ - private fun doSchedule(now: Long) { + private fun doSchedule(now: Long, delta: Long) { val activeInputs = _activeInputs val activeOutputs = _activeOutputs + // Update the counters of the scheduler + updateCounters(delta) + // If there is no work yet, mark the inputs as idle. if (activeInputs.isEmpty()) { + _demand = 0.0 + _rate = 0.0 return } @@ -156,6 +191,7 @@ public class MaxMinFlowMultiplexer( // Remove outputs that have finished if (!input.isActive) { + input.actualRate = 0.0 inputIterator.remove() } } @@ -168,7 +204,8 @@ public class MaxMinFlowMultiplexer( // Divide the available output capacity fairly over the inputs using max-min fair sharing var remaining = activeInputs.size - for (input in activeInputs) { + for (i in activeInputs.indices) { + val input = activeInputs[i] val availableShare = availableCapacity / remaining-- val grantedRate = min(input.allowedRate, availableShare) @@ -192,7 +229,8 @@ public class MaxMinFlowMultiplexer( activeOutputs.sort() // Divide the requests over the available capacity of the input resources fairly - for (output in activeOutputs) { + for (i in activeOutputs.indices) { + val output = activeOutputs[i] val inputCapacity = output.capacity val fraction = inputCapacity / capacity val grantedSpeed = rate * fraction @@ -219,6 +257,29 @@ public class MaxMinFlowMultiplexer( } } + /** + * The previous capacity of the multiplexer. + */ + private var _previousCapacity = 0.0 + + /** + * Update the counters of the scheduler. + */ + private fun updateCounters(delta: Long) { + val previousCapacity = _previousCapacity + _previousCapacity = _capacity + + if (delta <= 0) { + return + } + + val deltaS = delta / 1000.0 + + _counters.demand += _demand * deltaS + _counters.actual += _rate * deltaS + _counters.remaining += (previousCapacity - _rate) * deltaS + } + /** * An internal [FlowConsumer] implementation for multiplexer inputs. */ @@ -252,6 +313,11 @@ public class MaxMinFlowMultiplexer( */ private var _lastPull: Long = Long.MIN_VALUE + /** + * The interference domain this input belongs to. + */ + private val interferenceDomain = this@MaxMinFlowMultiplexer.interferenceDomain + /** * Close the input. * @@ -269,7 +335,6 @@ public class MaxMinFlowMultiplexer( check(!_isClosed) { "Cannot re-use closed input" } _activeInputs += this - if (parent != null) { ctx.shouldConsumerConverge = true } @@ -287,14 +352,22 @@ public class MaxMinFlowMultiplexer( doUpdateCounters(delta) actualRate = 0.0 - this.limit = rate + limit = rate _lastPull = now runScheduler(now) } override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { - parent?.onConverge(now, delta) + val lastConverge = _lastConverge + val parent = parent + + if (parent != null && (lastConverge < now || _lastConvergeInput == null)) { + _lastConverge = now + _lastConvergeInput = this + + parent.onConverge(now, max(0, now - lastConverge)) + } } override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { @@ -303,6 +376,14 @@ public class MaxMinFlowMultiplexer( limit = 0.0 actualRate = 0.0 _lastPull = now + + // Assign a new input responsible for handling the convergence events + if (_lastConvergeInput == this) { + _lastConvergeInput = null + } + + // Re-run scheduler to distribute new load + runScheduler(now) } /* Comparable */ @@ -328,35 +409,31 @@ public class MaxMinFlowMultiplexer( // Compute the performance penalty due to flow interference val perfScore = if (interferenceDomain != null) { - val load = _rate / capacity + val load = _rate / _capacity interferenceDomain.apply(key, load) } else { 1.0 } val deltaS = delta / 1000.0 - val work = limit * deltaS - val actualWork = actualRate * deltaS - val remainingWork = work - actualWork + val demand = limit * deltaS + val actual = actualRate * deltaS + val remaining = (capacity - actualRate) * deltaS - updateCounters(work, actualWork, remainingWork) + updateCounters(demand, actual, remaining) - val distCounters = _counters - distCounters.demand += work - distCounters.actual += actualWork - distCounters.overcommit += remainingWork - distCounters.interference += actualWork * max(0.0, 1 - perfScore) + _counters.interference += actual * max(0.0, 1 - perfScore) } } /** * An internal [FlowSource] implementation for multiplexer outputs. */ - private inner class Output(private val provider: FlowConsumer) : FlowSource, Comparable { + private inner class Output : FlowSource, Comparable { /** * The active [FlowConnection] of this source. */ - private var _ctx: FlowConnection? = null + private var _conn: FlowConnection? = null /** * The capacity of this output. @@ -367,27 +444,33 @@ public class MaxMinFlowMultiplexer( * Push the specified rate to the consumer. */ fun push(rate: Double) { - _ctx?.push(rate) + _conn?.push(rate) } /** * Cancel this output. */ fun cancel() { - provider.cancel() + _conn?.close() } override fun onStart(conn: FlowConnection, now: Long) { - assert(_ctx == null) { "Source running concurrently" } - _ctx = conn + assert(_conn == null) { "Source running concurrently" } + _conn = conn capacity = conn.capacity + _activeOutputs.add(this) + updateCapacity() } override fun onStop(conn: FlowConnection, now: Long, delta: Long) { - _ctx = null + _conn = null capacity = 0.0 + _activeOutputs.remove(this) + updateCapacity() + + runScheduler(now) } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { @@ -397,6 +480,7 @@ public class MaxMinFlowMultiplexer( updateCapacity() } + // Re-run scheduler to distribute new load runScheduler(now) return Long.MAX_VALUE } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt index d548451f..12e72b8f 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/FlowForwarderTest.kt @@ -217,7 +217,7 @@ internal class FlowForwarderTest { assertEquals(2.0, source.counters.actual) assertEquals(source.counters.actual, forwarder.counters.actual) { "Actual work" } assertEquals(source.counters.demand, forwarder.counters.demand) { "Work demand" } - assertEquals(source.counters.overcommit, forwarder.counters.overcommit) { "Overcommitted work" } + assertEquals(source.counters.remaining, forwarder.counters.remaining) { "Overcommitted work" } assertEquals(2000, clock.millis()) } diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt deleted file mode 100644 index 3475f027..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ExclusiveFlowMultiplexerTest.kt +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow.mux - -import kotlinx.coroutines.yield -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll -import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.runBlockingSimulation -import org.opendc.simulator.flow.* -import org.opendc.simulator.flow.internal.FlowEngineImpl -import org.opendc.simulator.flow.source.FixedFlowSource -import org.opendc.simulator.flow.source.FlowSourceRateAdapter -import org.opendc.simulator.flow.source.TraceFlowSource - -/** - * Test suite for the [ForwardingFlowMultiplexer] class. - */ -internal class ExclusiveFlowMultiplexerTest { - /** - * Test a trace workload. - */ - @Test - fun testTrace() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val speed = mutableListOf() - - val duration = 5 * 60L - val workload = - TraceFlowSource( - sequenceOf( - TraceFlowSource.Fragment(duration * 1000, 28.0), - TraceFlowSource.Fragment(duration * 1000, 3500.0), - TraceFlowSource.Fragment(duration * 1000, 0.0), - TraceFlowSource.Fragment(duration * 1000, 183.0) - ), - ) - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - val forwarder = FlowForwarder(engine) - val adapter = FlowSourceRateAdapter(forwarder, speed::add) - source.startConsumer(adapter) - switch.addOutput(forwarder) - - val provider = switch.newInput() - provider.consume(workload) - yield() - - assertAll( - { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, - { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } - ) - } - - /** - * Test runtime workload on hypervisor. - */ - @Test - fun testRuntimeWorkload() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val duration = 5 * 60L * 1000 - val workload = FixedFlowSource(duration * 3.2, 1.0) - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - - switch.addOutput(source) - - val provider = switch.newInput() - provider.consume(workload) - yield() - - assertEquals(duration, clock.millis()) { "Took enough time" } - } - - /** - * Test two workloads running sequentially. - */ - @Test - fun testTwoWorkloads() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val duration = 5 * 60L * 1000 - val workload = object : FlowSource { - var isFirst = true - - override fun onStart(conn: FlowConnection, now: Long) { - isFirst = true - } - - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - return if (isFirst) { - isFirst = false - conn.push(1.0) - duration - } else { - conn.close() - Long.MAX_VALUE - } - } - } - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - - switch.addOutput(source) - - val provider = switch.newInput() - provider.consume(workload) - yield() - provider.consume(workload) - assertEquals(duration * 2, clock.millis()) { "Took enough time" } - } - - /** - * Test concurrent workloads on the machine. - */ - @Test - fun testConcurrentWorkloadFails() = runBlockingSimulation { - val engine = FlowEngineImpl(coroutineContext, clock) - - val switch = ForwardingFlowMultiplexer(engine) - val source = FlowSink(engine, 3200.0) - - switch.addOutput(source) - - switch.newInput() - assertThrows { switch.newInput() } - } -} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexerTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexerTest.kt new file mode 100644 index 00000000..187dacd9 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexerTest.kt @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.mux + +import kotlinx.coroutines.yield +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.flow.* +import org.opendc.simulator.flow.internal.FlowEngineImpl +import org.opendc.simulator.flow.source.FixedFlowSource +import org.opendc.simulator.flow.source.FlowSourceRateAdapter +import org.opendc.simulator.flow.source.TraceFlowSource + +/** + * Test suite for the [ForwardingFlowMultiplexer] class. + */ +internal class ForwardingFlowMultiplexerTest { + /** + * Test a trace workload. + */ + @Test + fun testTrace() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val speed = mutableListOf() + + val duration = 5 * 60L + val workload = + TraceFlowSource( + sequenceOf( + TraceFlowSource.Fragment(duration * 1000, 28.0), + TraceFlowSource.Fragment(duration * 1000, 3500.0), + TraceFlowSource.Fragment(duration * 1000, 0.0), + TraceFlowSource.Fragment(duration * 1000, 183.0) + ), + ) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + val forwarder = FlowForwarder(engine) + val adapter = FlowSourceRateAdapter(forwarder, speed::add) + source.startConsumer(adapter) + forwarder.startConsumer(switch.newOutput()) + + val provider = switch.newInput() + provider.consume(workload) + yield() + + assertAll( + { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, + { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } + ) + } + + /** + * Test runtime workload on hypervisor. + */ + @Test + fun testRuntimeWorkload() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L * 1000 + val workload = FixedFlowSource(duration * 3.2, 1.0) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + source.startConsumer(switch.newOutput()) + + val provider = switch.newInput() + provider.consume(workload) + yield() + + assertEquals(duration, clock.millis()) { "Took enough time" } + } + + /** + * Test two workloads running sequentially. + */ + @Test + fun testTwoWorkloads() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val duration = 5 * 60L * 1000 + val workload = object : FlowSource { + var isFirst = true + + override fun onStart(conn: FlowConnection, now: Long) { + isFirst = true + } + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + return if (isFirst) { + isFirst = false + conn.push(1.0) + duration + } else { + conn.close() + Long.MAX_VALUE + } + } + } + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + source.startConsumer(switch.newOutput()) + + val provider = switch.newInput() + provider.consume(workload) + yield() + provider.consume(workload) + assertEquals(duration * 2, clock.millis()) { "Took enough time" } + } + + /** + * Test concurrent workloads on the machine. + */ + @Test + fun testConcurrentWorkloadFails() = runBlockingSimulation { + val engine = FlowEngineImpl(coroutineContext, clock) + + val switch = ForwardingFlowMultiplexer(engine) + val source = FlowSink(engine, 3200.0) + + source.startConsumer(switch.newOutput()) + + switch.newInput() + assertThrows { switch.newInput() } + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt index 9f6b8a2c..6e2cdb98 100644 --- a/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt +++ b/opendc-simulator/opendc-simulator-flow/src/test/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexerTest.kt @@ -44,7 +44,7 @@ internal class MaxMinFlowMultiplexerTest { val switch = MaxMinFlowMultiplexer(scheduler) val sources = List(2) { FlowSink(scheduler, 2000.0) } - sources.forEach { switch.addOutput(it) } + sources.forEach { it.startConsumer(switch.newOutput()) } val provider = switch.newInput() val consumer = FixedFlowSource(2000.0, 1.0) @@ -76,10 +76,11 @@ internal class MaxMinFlowMultiplexerTest { ) val switch = MaxMinFlowMultiplexer(scheduler) + val sink = FlowSink(scheduler, 3200.0) val provider = switch.newInput() try { - switch.addOutput(FlowSink(scheduler, 3200.0)) + sink.startConsumer(switch.newOutput()) provider.consume(workload) yield() } finally { @@ -89,7 +90,7 @@ internal class MaxMinFlowMultiplexerTest { assertAll( { assertEquals(1113300.0, switch.counters.demand, "Requested work does not match") }, { assertEquals(1023300.0, switch.counters.actual, "Actual work does not match") }, - { assertEquals(90000.0, switch.counters.overcommit, "Overcommitted work does not match") }, + { assertEquals(2816700.0, switch.counters.remaining, "Remaining capacity does not match") }, { assertEquals(1200000, clock.millis()) } ) } @@ -122,11 +123,12 @@ internal class MaxMinFlowMultiplexerTest { ) val switch = MaxMinFlowMultiplexer(scheduler) + val sink = FlowSink(scheduler, 3200.0) val providerA = switch.newInput() val providerB = switch.newInput() try { - switch.addOutput(FlowSink(scheduler, 3200.0)) + sink.startConsumer(switch.newOutput()) coroutineScope { launch { providerA.consume(workloadA) } @@ -140,7 +142,7 @@ internal class MaxMinFlowMultiplexerTest { assertAll( { assertEquals(2073600.0, switch.counters.demand, "Requested work does not match") }, { assertEquals(1053600.0, switch.counters.actual, "Granted work does not match") }, - { assertEquals(1020000.0, switch.counters.overcommit, "Overcommitted work does not match") }, + { assertEquals(2786400.0, switch.counters.remaining, "Remaining capacity does not match") }, { assertEquals(1200000, clock.millis()) } ) } diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt index 2b7c1ad7..6667c80c 100644 --- a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt @@ -63,11 +63,9 @@ public class SimNetworkSwitchVirtual(private val engine: FlowEngine) : SimNetwor get() = _provider private val _provider = mux.newInput() - override fun createConsumer(): FlowSource { - val forwarder = FlowForwarder(engine, isCoupled = true) - mux.addOutput(forwarder) - return forwarder - } + private val _source = mux.newOutput() + + override fun createConsumer(): FlowSource = _source override fun close() { isClosed = true diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index d536f22d..9f88fecc 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -46,18 +46,14 @@ public class SimPdu( /** * The [FlowForwarder] that represents the input of the PDU. */ - private val forwarder = FlowForwarder(engine) + private val output = mux.newOutput() /** * Create a new PDU outlet. */ public fun newOutlet(): Outlet = Outlet(mux, mux.newInput()) - init { - mux.addOutput(forwarder) - } - - override fun createSource(): FlowSource = FlowMapper(forwarder) { _, rate -> + override fun createSource(): FlowSource = FlowMapper(output) { _, rate -> val loss = computePowerLoss(rate) rate + loss } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 312f1d0f..46d659f8 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -42,19 +42,19 @@ public class SimUps( /** * The resource aggregator used to combine the input sources. */ - private val switch = MaxMinFlowMultiplexer(engine) + private val mux = MaxMinFlowMultiplexer(engine) /** * The [FlowConsumer] that represents the output of the UPS. */ - private val provider = switch.newInput() + private val provider = mux.newInput() /** * Create a new UPS outlet. */ public fun newInlet(): SimPowerInlet { val forward = FlowForwarder(engine, isCoupled = true) - switch.addOutput(forward) + forward.startConsumer(mux.newOutput()) return Inlet(forward) } -- cgit v1.2.3 From 012fe8fa9be1676b8eef0cce795738a00c4260c0 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sat, 2 Oct 2021 13:08:06 +0200 Subject: perf(compute): Optimize telemetry collection This change optimizes the telemetry collection in the SimHost class. Previously, there was significant overhead in collecting the metrics of this and associated classes due large `Attributes` object that did not cache accesses to `hashCode()`. We now wrap this object and manually cache the hash code. --- .../kotlin/org/opendc/compute/simulator/SimHost.kt | 45 ++++++---- .../org/opendc/compute/simulator/internal/Guest.kt | 97 ++++++++++++++++------ 2 files changed, 102 insertions(+), 40 deletions(-) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 4b96872b..b9d02185 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -109,6 +109,7 @@ public class SimHost( * The virtual machines running on the hypervisor. */ private val guests = HashMap() + private val _guests = mutableListOf() override val state: HostState get() = _state @@ -199,7 +200,7 @@ public class SimHost( require(canFit(key)) { "Server does not fit" } val machine = hypervisor.createMachine(key.flavor.toMachineModel(), key.name) - Guest( + val newGuest = Guest( scope.coroutineContext, clock, this, @@ -208,6 +209,9 @@ public class SimHost( server, machine ) + + _guests.add(newGuest) + newGuest } if (start) { @@ -231,7 +235,7 @@ public class SimHost( override suspend fun delete(server: Server) { val guest = guests[server] ?: return - guest.terminate() + guest.delete() } override fun addListener(listener: HostListener) { @@ -253,7 +257,7 @@ public class SimHost( public suspend fun fail() { reset() - for (guest in guests.values) { + for (guest in _guests) { guest.fail() } } @@ -266,7 +270,7 @@ public class SimHost( // Wait for the hypervisor to launch before recovering the guests yield() - for (guest in guests.values) { + for (guest in _guests) { guest.recover() } } @@ -357,11 +361,17 @@ public class SimHost( var error = 0L var invalid = 0L - for ((_, guest) in guests) { + val guests = _guests.listIterator() + for (guest in guests) { when (guest.state) { ServerState.TERMINATED -> terminated++ ServerState.RUNNING -> running++ ServerState.ERROR -> error++ + ServerState.DELETED -> { + // Remove guests that have been deleted + this.guests.remove(guest.server) + guests.remove() + } else -> invalid++ } } @@ -380,8 +390,9 @@ public class SimHost( private fun collectCpuLimit(result: ObservableDoubleMeasurement) { result.observe(_cpuLimit) - for (guest in guests.values) { - guest.collectCpuLimit(result) + val guests = _guests + for (i in guests.indices) { + guests[i].collectCpuLimit(result) } } @@ -401,8 +412,9 @@ public class SimHost( result.observe(counters.cpuStealTime / 1000L, _stealState) result.observe(counters.cpuLostTime / 1000L, _lostState) - for (guest in guests.values) { - guest.collectCpuTime(result) + val guests = _guests + for (i in guests.indices) { + guests[i].collectCpuTime(result) } } @@ -423,8 +435,9 @@ public class SimHost( _downtime += duration } - for (guest in guests.values) { - guest.updateUptime(duration) + val guests = _guests + for (i in guests.indices) { + guests[i].updateUptime(duration) } } @@ -442,8 +455,9 @@ public class SimHost( result.observe(_uptime, _upState) result.observe(_downtime, _downState) - for (guest in guests.values) { - guest.collectUptime(result) + val guests = _guests + for (i in guests.indices) { + guests[i].collectUptime(result) } } @@ -457,8 +471,9 @@ public class SimHost( result.observe(_bootTime) } - for (guest in guests.values) { - guest.collectBootTime(result) + val guests = _guests + for (i in guests.indices) { + guests[i].collectBootTime(result) } } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index 3ac165c8..5ea1860d 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -24,6 +24,7 @@ package org.opendc.compute.simulator.internal import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes +import io.opentelemetry.api.common.AttributesBuilder import io.opentelemetry.api.metrics.ObservableDoubleMeasurement import io.opentelemetry.api.metrics.ObservableLongMeasurement import io.opentelemetry.semconv.resource.attributes.ResourceAttributes @@ -71,17 +72,7 @@ internal class Guest( /** * The attributes of the guest. */ - val attributes: Attributes = Attributes.builder() - .put(ResourceAttributes.HOST_NAME, server.name) - .put(ResourceAttributes.HOST_ID, server.uid.toString()) - .put(ResourceAttributes.HOST_TYPE, server.flavor.name) - .put(AttributeKey.longKey("host.num_cpus"), server.flavor.cpuCount.toLong()) - .put(AttributeKey.longKey("host.mem_capacity"), server.flavor.memorySize) - .put(AttributeKey.stringArrayKey("host.labels"), server.labels.map { (k, v) -> "$k:$v" }) - .put(ResourceAttributes.HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) - .put(ResourceAttributes.HOST_IMAGE_NAME, server.image.name) - .put(ResourceAttributes.HOST_IMAGE_ID, server.image.uid.toString()) - .build() + val attributes: Attributes = GuestAttributes(this) /** * Start the guest. @@ -114,12 +105,12 @@ internal class Guest( } /** - * Terminate the guest. + * Delete the guest. * * This operation will stop the guest if it is running on the host and remove all resources associated with the * guest. */ - suspend fun terminate() { + suspend fun delete() { stop() state = ServerState.DELETED @@ -224,12 +215,10 @@ internal class Guest( private var _uptime = 0L private var _downtime = 0L - private val _upState = Attributes.builder() - .putAll(attributes) + private val _upState = attributes.toBuilder() .put(STATE_KEY, "up") .build() - private val _downState = Attributes.builder() - .putAll(attributes) + private val _downState = attributes.toBuilder() .put(STATE_KEY, "down") .build() @@ -263,20 +252,16 @@ internal class Guest( } } - private val _activeState = Attributes.builder() - .putAll(attributes) + private val _activeState = attributes.toBuilder() .put(STATE_KEY, "active") .build() - private val _stealState = Attributes.builder() - .putAll(attributes) + private val _stealState = attributes.toBuilder() .put(STATE_KEY, "steal") .build() - private val _lostState = Attributes.builder() - .putAll(attributes) + private val _lostState = attributes.toBuilder() .put(STATE_KEY, "lost") .build() - private val _idleState = Attributes.builder() - .putAll(attributes) + private val _idleState = attributes.toBuilder() .put(STATE_KEY, "idle") .build() @@ -300,4 +285,66 @@ internal class Guest( fun collectCpuLimit(result: ObservableDoubleMeasurement) { result.observe(_cpuLimit, attributes) } + + /** + * An optimized [Attributes] implementation. + */ + private class GuestAttributes(private val uid: String, private val attributes: Attributes) : Attributes by attributes { + /** + * Construct a [GuestAttributes] instance from a [Guest]. + */ + constructor(guest: Guest) : this( + guest.server.uid.toString(), + Attributes.builder() + .put(ResourceAttributes.HOST_NAME, guest.server.name) + .put(ResourceAttributes.HOST_ID, guest.server.uid.toString()) + .put(ResourceAttributes.HOST_TYPE, guest.server.flavor.name) + .put(AttributeKey.longKey("host.num_cpus"), guest.server.flavor.cpuCount.toLong()) + .put(AttributeKey.longKey("host.mem_capacity"), guest.server.flavor.memorySize) + .put(AttributeKey.stringArrayKey("host.labels"), guest.server.labels.map { (k, v) -> "$k:$v" }) + .put(ResourceAttributes.HOST_ARCH, ResourceAttributes.HostArchValues.AMD64) + .put(ResourceAttributes.HOST_IMAGE_NAME, guest.server.image.name) + .put(ResourceAttributes.HOST_IMAGE_ID, guest.server.image.uid.toString()) + .build() + ) + + override fun get(key: AttributeKey): T? { + // Optimize access to the HOST_ID key which is accessed quite often + if (key == ResourceAttributes.HOST_ID) { + @Suppress("UNCHECKED_CAST") + return uid as T? + } + return attributes.get(key) + } + + override fun toBuilder(): AttributesBuilder { + val delegate = attributes.toBuilder() + return object : AttributesBuilder { + + override fun putAll(attributes: Attributes): AttributesBuilder { + delegate.putAll(attributes) + return this + } + + override fun put(key: AttributeKey, value: Int): AttributesBuilder { + delegate.put(key, value) + return this + } + + override fun put(key: AttributeKey, value: T): AttributesBuilder { + delegate.put(key, value) + return this + } + + override fun build(): Attributes = GuestAttributes(uid, delegate.build()) + } + } + + override fun equals(other: Any?): Boolean = attributes == other + + // Cache hash code + private val _hash = attributes.hashCode() + + override fun hashCode(): Int = _hash + } } -- cgit v1.2.3 From 5c4f9d936d7c08e8ad2705ed3dde5ea8dcd2ee64 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 4 Oct 2021 16:43:02 +0200 Subject: perf(simulator): Do not prune invocations on sync engine invocation --- .../simulator/flow/internal/FlowEngineImpl.kt | 112 +++++++++------------ 1 file changed, 49 insertions(+), 63 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index 019b5f10..a9234abf 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -38,7 +38,7 @@ import kotlin.coroutines.CoroutineContext * @param context The coroutine context to use. * @param clock The virtual simulation clock. */ -internal class FlowEngineImpl(private val context: CoroutineContext, override val clock: Clock) : FlowEngine { +internal class FlowEngineImpl(private val context: CoroutineContext, override val clock: Clock) : FlowEngine, Runnable { /** * The [Delay] instance that provides scheduled execution of [Runnable]s. */ @@ -82,7 +82,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va return } - runEngine(now) + doRunEngine(now) } /** @@ -100,7 +100,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va return } - runEngine(now) + doRunEngine(now) } override fun newContext(consumer: FlowSource, provider: FlowConsumerLogic): FlowConsumerContext = FlowConsumerContextImpl(this, consumer, provider) @@ -120,16 +120,13 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va } } - /** - * Run the engine and mark as active while running. - */ - private fun runEngine(now: Long) { - try { - batchIndex++ - doRunEngine(now) - } finally { - batchIndex-- - } + /* Runnable */ + override fun run() { + val now = clock.millis() + val invocation = futureInvocations.poll() // Clear invocation from future invocation queue + assert(now >= invocation.timestamp) { "Future invocations invariant violated" } + + doRunEngine(now) } /** @@ -141,44 +138,43 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va val futureInvocations = futureInvocations val visited = visited - // Remove any entries in the `futureInvocations` queue from the past - while (true) { - val head = futureInvocations.peek() - if (head == null || head.timestamp > now) { - break - } - futureInvocations.poll() - } - - // Execute all scheduled updates at current timestamp - while (true) { - val timer = futureQueue.peek() ?: break - val target = timer.target + try { + // Increment batch index so synchronous calls will not launch concurrent engine invocations + batchIndex++ - if (target > now) { - break - } + // Execute all scheduled updates at current timestamp + while (true) { + val timer = futureQueue.peek() ?: break + val target = timer.target - assert(target >= now) { "Internal inconsistency: found update of the past" } + if (target > now) { + break + } - futureQueue.poll() - timer.ctx.doUpdate(now, visited, futureQueue, isImmediate = false) - } + assert(target >= now) { "Internal inconsistency: found update of the past" } - // Repeat execution of all immediate updates until the system has converged to a steady-state - // We have to take into account that the onConverge callback can also trigger new actions. - do { - // Execute all immediate updates - while (true) { - val ctx = queue.poll() ?: break - ctx.doUpdate(now, visited, futureQueue, isImmediate = true) + futureQueue.poll() + timer.ctx.doUpdate(now, visited, futureQueue, isImmediate = false) } - while (true) { - val ctx = visited.poll() ?: break - ctx.onConverge(now) - } - } while (queue.isNotEmpty()) + // Repeat execution of all immediate updates until the system has converged to a steady-state + // We have to take into account that the onConverge callback can also trigger new actions. + do { + // Execute all immediate updates + while (true) { + val ctx = queue.poll() ?: break + ctx.doUpdate(now, visited, futureQueue, isImmediate = true) + } + + while (true) { + val ctx = visited.poll() ?: break + ctx.onConverge(now) + } + } while (queue.isNotEmpty()) + } finally { + // Decrement batch index to indicate no engine is active at the moment + batchIndex-- + } // Schedule an engine invocation for the next update to occur. val headTimer = futureQueue.peek() @@ -195,24 +191,14 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va * @param scheduled The queue of scheduled invocations. */ private fun trySchedule(now: Long, scheduled: ArrayDeque, target: Long) { - while (true) { - val invocation = scheduled.peekFirst() - if (invocation == null || invocation.timestamp > target) { - // Case 2: A new timer was registered ahead of the other timers. - // Solution: Schedule a new scheduler invocation - @OptIn(InternalCoroutinesApi::class) - val handle = delay.invokeOnTimeout(target - now, { runEngine(target) }, context) - scheduled.addFirst(Invocation(target, handle)) - break - } else if (invocation.timestamp < target) { - // Case 2: A timer was cancelled and the head of the timer queue is now later than excepted - // Solution: Cancel the next scheduler invocation - scheduled.pollFirst() - - invocation.cancel() - } else { - break - } + val head = scheduled.peek() + + // Only schedule a new scheduler invocation in case the target is earlier than all other pending + // scheduler invocations + if (head == null || target < head.timestamp) { + @OptIn(InternalCoroutinesApi::class) + val handle = delay.invokeOnTimeout(target - now, this, context) + scheduled.addFirst(Invocation(target, handle)) } } -- cgit v1.2.3 From 557797c63c19e80c908eccc96472f215eab0c2f3 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 4 Oct 2021 19:26:29 +0200 Subject: perf(experiments): Add benchmark for Capelin experiment --- .../opendc-experiments-capelin/build.gradle.kts | 1 + .../experiments/capelin/CapelinBenchmarks.kt | 83 ++++++++++++++++++++++ .../src/jmh/resources/log4j2.xml | 37 ++++++++++ .../simulator/compute/SimMachineBenchmarks.kt | 50 ++++++------- .../org/opendc/simulator/flow/FlowBenchmarks.kt | 63 ++++++++-------- 5 files changed, 170 insertions(+), 64 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-capelin/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt create mode 100644 opendc-experiments/opendc-experiments-capelin/src/jmh/resources/log4j2.xml diff --git a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts index 23a3e4a7..c20556b5 100644 --- a/opendc-experiments/opendc-experiments-capelin/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-capelin/build.gradle.kts @@ -26,6 +26,7 @@ description = "Experiments for the Capelin work" plugins { `experiment-conventions` `testing-conventions` + `benchmark-conventions` } dependencies { diff --git a/opendc-experiments/opendc-experiments-capelin/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt b/opendc-experiments/opendc-experiments-capelin/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt new file mode 100644 index 00000000..48a90985 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.experiments.capelin + +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.opendc.compute.service.scheduler.FilterScheduler +import org.opendc.compute.service.scheduler.filters.ComputeFilter +import org.opendc.compute.service.scheduler.filters.RamFilter +import org.opendc.compute.service.scheduler.filters.VCpuFilter +import org.opendc.compute.service.scheduler.weights.CoreRamWeigher +import org.opendc.compute.workload.* +import org.opendc.compute.workload.topology.Topology +import org.opendc.compute.workload.topology.apply +import org.opendc.experiments.capelin.topology.clusterTopology +import org.opendc.simulator.core.runBlockingSimulation +import org.openjdk.jmh.annotations.* +import java.io.File +import java.util.* +import java.util.concurrent.TimeUnit + +/** + * Benchmark suite for the Capelin experiments. + */ +@State(Scope.Thread) +@Fork(1) +@Warmup(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) +@OptIn(ExperimentalCoroutinesApi::class) +class CapelinBenchmarks { + private lateinit var vms: List + private lateinit var topology: Topology + + @Param("true", "false") + private var isOptimized: Boolean = false + + @Setup + fun setUp() { + val loader = ComputeWorkloadLoader(File("src/test/resources/trace")) + val source = trace("bitbrains-small") + vms = source.resolve(loader, Random(1L)) + topology = checkNotNull(object {}.javaClass.getResourceAsStream("/env/topology.txt")).use { clusterTopology(it) } + } + + @Benchmark + fun benchmarkCapelin() = runBlockingSimulation { + val computeScheduler = FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)) + ) + val runner = ComputeWorkloadRunner( + coroutineContext, + clock, + computeScheduler + ) + + try { + runner.apply(topology, isOptimized) + runner.run(vms, 0) + } finally { + runner.close() + } + } +} diff --git a/opendc-experiments/opendc-experiments-capelin/src/jmh/resources/log4j2.xml b/opendc-experiments/opendc-experiments-capelin/src/jmh/resources/log4j2.xml new file mode 100644 index 00000000..c496dd75 --- /dev/null +++ b/opendc-experiments/opendc-experiments-capelin/src/jmh/resources/log4j2.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index d654d58a..b8e0227a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -22,6 +22,7 @@ package org.opendc.simulator.compute +import javafx.application.Application.launch import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @@ -34,7 +35,6 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.core.SimulationCoroutineScope import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine import org.openjdk.jmh.annotations.* @@ -47,48 +47,38 @@ import java.util.concurrent.TimeUnit @Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) @OptIn(ExperimentalCoroutinesApi::class) class SimMachineBenchmarks { - private lateinit var scope: SimulationCoroutineScope - private lateinit var engine: FlowEngine private lateinit var machineModel: MachineModel + private lateinit var trace: Sequence @Setup fun setUp() { - scope = SimulationCoroutineScope() - engine = FlowEngine(scope.coroutineContext, scope.clock) - val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) machineModel = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) - } - @State(Scope.Thread) - class Workload { - lateinit var trace: Sequence - - @Setup - fun setUp() { - val random = ThreadLocalRandom.current() - val entries = List(10000) { SimTraceWorkload.Fragment(it * 1000L, 1000, random.nextDouble(0.0, 4500.0), 1) } - trace = entries.asSequence() - } + val random = ThreadLocalRandom.current() + val entries = List(10000) { SimTraceWorkload.Fragment(it * 1000L, 1000, random.nextDouble(0.0, 4500.0), 1) } + trace = entries.asSequence() } @Benchmark - fun benchmarkBareMetal(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkBareMetal() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - return@runBlockingSimulation machine.run(SimTraceWorkload(state.trace)) + return@runBlockingSimulation machine.run(SimTraceWorkload(trace)) } } @Benchmark - fun benchmarkSpaceSharedHypervisor(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkSpaceSharedHypervisor() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -99,7 +89,7 @@ class SimMachineBenchmarks { val vm = hypervisor.createMachine(machineModel) try { - return@runBlockingSimulation vm.run(SimTraceWorkload(state.trace)) + return@runBlockingSimulation vm.run(SimTraceWorkload(trace)) } finally { vm.close() machine.close() @@ -108,8 +98,9 @@ class SimMachineBenchmarks { } @Benchmark - fun benchmarkFairShareHypervisorSingle(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkFairShareHypervisorSingle() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -120,7 +111,7 @@ class SimMachineBenchmarks { val vm = hypervisor.createMachine(machineModel) try { - return@runBlockingSimulation vm.run(SimTraceWorkload(state.trace)) + return@runBlockingSimulation vm.run(SimTraceWorkload(trace)) } finally { vm.close() machine.close() @@ -129,8 +120,9 @@ class SimMachineBenchmarks { } @Benchmark - fun benchmarkFairShareHypervisorDouble(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkFairShareHypervisorDouble() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) @@ -144,7 +136,7 @@ class SimMachineBenchmarks { launch { try { - vm.run(SimTraceWorkload(state.trace)) + vm.run(SimTraceWorkload(trace)) } finally { machine.close() } diff --git a/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt b/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt index e927f81d..aabd2220 100644 --- a/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-flow/src/jmh/kotlin/org/opendc/simulator/flow/FlowBenchmarks.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.flow import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch -import org.opendc.simulator.core.SimulationCoroutineScope import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer @@ -39,61 +38,53 @@ import java.util.concurrent.TimeUnit @Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) @OptIn(ExperimentalCoroutinesApi::class) class FlowBenchmarks { - private lateinit var scope: SimulationCoroutineScope - private lateinit var engine: FlowEngine + private lateinit var trace: Sequence @Setup fun setUp() { - scope = SimulationCoroutineScope() - engine = FlowEngine(scope.coroutineContext, scope.clock) - } - - @State(Scope.Thread) - class Workload { - lateinit var trace: Sequence - - @Setup - fun setUp() { - val random = ThreadLocalRandom.current() - val entries = List(10000) { TraceFlowSource.Fragment(1000, random.nextDouble(0.0, 4500.0)) } - trace = entries.asSequence() - } + val random = ThreadLocalRandom.current() + val entries = List(10000) { TraceFlowSource.Fragment(1000, random.nextDouble(0.0, 4500.0)) } + trace = entries.asSequence() } @Benchmark - fun benchmarkSink(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkSink() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val provider = FlowSink(engine, 4200.0) - return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) + return@runBlockingSimulation provider.consume(TraceFlowSource(trace)) } } @Benchmark - fun benchmarkForward(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkForward() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val provider = FlowSink(engine, 4200.0) val forwarder = FlowForwarder(engine) provider.startConsumer(forwarder) - return@runBlockingSimulation forwarder.consume(TraceFlowSource(state.trace)) + return@runBlockingSimulation forwarder.consume(TraceFlowSource(trace)) } } @Benchmark - fun benchmarkMuxMaxMinSingleSource(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkMuxMaxMinSingleSource() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val switch = MaxMinFlowMultiplexer(engine) FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) val provider = switch.newInput() - return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) + return@runBlockingSimulation provider.consume(TraceFlowSource(trace)) } } @Benchmark - fun benchmarkMuxMaxMinTripleSource(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkMuxMaxMinTripleSource() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val switch = MaxMinFlowMultiplexer(engine) FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) @@ -102,28 +93,30 @@ class FlowBenchmarks { repeat(3) { launch { val provider = switch.newInput() - provider.consume(TraceFlowSource(state.trace)) + provider.consume(TraceFlowSource(trace)) } } } } @Benchmark - fun benchmarkMuxExclusiveSingleSource(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkMuxExclusiveSingleSource() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val switch = ForwardingFlowMultiplexer(engine) FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) val provider = switch.newInput() - return@runBlockingSimulation provider.consume(TraceFlowSource(state.trace)) + return@runBlockingSimulation provider.consume(TraceFlowSource(trace)) } } @Benchmark - fun benchmarkMuxExclusiveTripleSource(state: Workload) { - return scope.runBlockingSimulation { + fun benchmarkMuxExclusiveTripleSource() { + return runBlockingSimulation { + val engine = FlowEngine(coroutineContext, clock) val switch = ForwardingFlowMultiplexer(engine) FlowSink(engine, 3000.0).startConsumer(switch.newOutput()) @@ -132,7 +125,7 @@ class FlowBenchmarks { repeat(2) { launch { val provider = switch.newInput() - provider.consume(TraceFlowSource(state.trace)) + provider.consume(TraceFlowSource(trace)) } } } -- cgit v1.2.3 From 7c260ab0b083488b8855f61648548a40401cf62e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 4 Oct 2021 21:50:38 +0200 Subject: perf(simulator): Manage deadlines centrally in max min mux This change updates the MaxMinFlowMultiplexer implementation to centrally manage the deadlines of the `FlowSource`s as opposed to each source using its own timers. For large amounts of inputs, this is much faster as the multiplexer already needs to traverse each input on a timer expiration of an input. --- .../experiments/capelin/CapelinIntegrationTest.kt | 6 +- .../opendc/simulator/flow/FlowConsumerContext.kt | 14 ++- .../org/opendc/simulator/flow/internal/Flags.kt | 1 + .../flow/internal/FlowConsumerContextImpl.kt | 45 +++++-- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 140 ++++++++++++++++----- 5 files changed, 155 insertions(+), 51 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 9d540118..337d68bf 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -120,7 +120,7 @@ class CapelinIntegrationTest { { assertEquals(67006560, this@CapelinIntegrationTest.exporter.activeTime) { "Incorrect active time" } }, { assertEquals(3159377, this@CapelinIntegrationTest.exporter.stealTime) { "Incorrect steal time" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Incorrect lost time" } }, - { assertEquals(5.840207707767459E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, + { assertEquals(5.840212485920686E9, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } }, ) } @@ -164,7 +164,7 @@ class CapelinIntegrationTest { { assertEquals(9740289, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, { assertEquals(0, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } }, - { assertEquals(7.009945802750012E8, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } } + { assertEquals(7.0099453912813E8, this@CapelinIntegrationTest.exporter.energyUsage, 0.01) { "Incorrect power draw" } } ) } @@ -213,7 +213,7 @@ class CapelinIntegrationTest { { assertEquals(6013515, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724500, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(480866, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(481270, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt index 15f9b93b..d7182497 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt @@ -28,6 +28,11 @@ package org.opendc.simulator.flow * This interface is used by [FlowConsumer]s to control the connection between it and the source. */ public interface FlowConsumerContext : FlowConnection { + /** + * The deadline of the source. + */ + public val deadline: Long + /** * The capacity of the connection. */ @@ -38,13 +43,18 @@ public interface FlowConsumerContext : FlowConnection { */ public var shouldConsumerConverge: Boolean + /** + * A flag to control whether the timers for the [FlowSource] should be enabled. + */ + public var enableTimers: Boolean + /** * Start the flow over the connection. */ public fun start() /** - * Synchronously flush the changes of the connection. + * Synchronously pull the source of the connection. */ - public fun flush() + public fun pullSync() } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt index 81ed9f26..939c5c98 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt @@ -41,3 +41,4 @@ internal const val ConnUpdateSkipped = 1 shl 6 // An update of the connection wa internal const val ConnConvergePending = 1 shl 7 // Indication that a convergence is already pending internal const val ConnConvergeSource = 1 shl 8 // Enable convergence of the source internal const val ConnConvergeConsumer = 1 shl 9 // Enable convergence of the consumer +internal const val ConnDisableTimers = 1 shl 10 // Disable timers for the source diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index 9d36483e..c7a8c3de 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -69,23 +69,30 @@ internal class FlowConsumerContextImpl( */ override val demand: Double get() = _demand + private var _demand: Double = 0.0 // The current (pending) demand of the source + + /** + * The deadline of the source. + */ + override val deadline: Long + get() = _deadline + private var _deadline: Long = Long.MAX_VALUE // The deadline of the source's timer /** * Flags to control the convergence of the consumer and source. */ - override var shouldSourceConverge: Boolean = false + override var shouldSourceConverge: Boolean + get() = _flags and ConnConvergeSource == ConnConvergeSource set(value) { - field = value _flags = if (value) _flags or ConnConvergeSource else _flags and ConnConvergeSource.inv() } - override var shouldConsumerConverge: Boolean = false + override var shouldConsumerConverge: Boolean + get() = _flags and ConnConvergeConsumer == ConnConvergeConsumer set(value) { - field = value - _flags = if (value) _flags or ConnConvergeConsumer @@ -94,15 +101,22 @@ internal class FlowConsumerContextImpl( } /** - * The clock to track simulation time. + * Flag to control the timers on the [FlowSource] */ - private val _clock = engine.clock + override var enableTimers: Boolean + get() = _flags and ConnDisableTimers != ConnDisableTimers + set(value) { + _flags = + if (!value) + _flags or ConnDisableTimers + else + _flags and ConnDisableTimers.inv() + } /** - * The current state of the connection. + * The clock to track simulation time. */ - private var _demand: Double = 0.0 // The current (pending) demand of the source - private var _deadline: Long = Long.MAX_VALUE // The deadline of the source's timer + private val _clock = engine.clock /** * The flags of the flow connection, indicating certain actions. @@ -166,7 +180,7 @@ internal class FlowConsumerContextImpl( scheduleImmediate(_clock.millis(), flags or ConnPulled) } - override fun flush() { + override fun pullSync() { val flags = _flags // Do not attempt to flush the connection if the connection is closed or an update is already active @@ -308,8 +322,13 @@ internal class FlowConsumerContextImpl( // Check whether we need to schedule a new timer for this connection. That is the case when: // (1) The deadline is valid (not the maximum value) // (2) The connection is active - // (3) The current active timer for the connection points to a later deadline - if (newDeadline == Long.MAX_VALUE || flags and ConnState != ConnActive || (timer != null && newDeadline >= timer.target)) { + // (3) Timers are not disabled for the source + // (4) The current active timer for the connection points to a later deadline + if (newDeadline == Long.MAX_VALUE || + flags and ConnState != ConnActive || + flags and ConnDisableTimers != 0 || + (timer != null && newDeadline >= timer.target) + ) { // Ignore any deadline scheduled at the maximum value // This indicates that the source does not want to register a timer return diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 5ff0fb8d..22f6516d 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -97,6 +97,11 @@ public class MaxMinFlowMultiplexer( private var _lastConverge: Long = Long.MIN_VALUE private var _lastConvergeInput: Input? = null + /** + * An [Output] that is used to activate the scheduler. + */ + private var _activationOutput: Output? = null + override fun newInput(key: InterferenceKey?): FlowConsumer { val provider = Input(_capacity, key) _inputs.add(provider) @@ -146,19 +151,44 @@ public class MaxMinFlowMultiplexer( } /** - * Converge the scheduler of the multiplexer. + * Trigger the scheduler of the multiplexer. + * + * @param now The current virtual timestamp of the simulation. */ - private fun runScheduler(now: Long) { + private fun triggerScheduler(now: Long) { if (_schedulerActive) { + // No need to trigger the scheduler in case it is already active + return + } + + val activationOutput = _activationOutput + + // We can run the scheduler in two ways: + // (1) We can pull one of the multiplexer's outputs. This allows us to cascade multiple pushes by the input + // into a single scheduling cycle, but is slower in case of a few changes at the same timestamp. + // (2) We run the scheduler directly from this method call. This is the fastest approach when there are only + // a few inputs and little changes at the same timestamp. + // We always pick for option (1) unless there are no outputs available. + if (activationOutput != null) { + activationOutput.pull() return + } else { + runScheduler(now) } + } + + /** + * Synchronously run the scheduler of the multiplexer. + */ + private fun runScheduler(now: Long): Long { val lastSchedulerCycle = _lastSchedulerCycle - val delta = max(0, now - lastSchedulerCycle) - _schedulerActive = true _lastSchedulerCycle = now - try { - doSchedule(now, delta) + val delta = max(0, now - lastSchedulerCycle) + + return try { + _schedulerActive = true + doSchedule(delta) } finally { _schedulerActive = false } @@ -166,8 +196,10 @@ public class MaxMinFlowMultiplexer( /** * Schedule the inputs over the outputs. + * + * @return The deadline after which a new scheduling cycle should start. */ - private fun doSchedule(now: Long, delta: Long) { + private fun doSchedule(delta: Long): Long { val activeInputs = _activeInputs val activeOutputs = _activeOutputs @@ -178,7 +210,7 @@ public class MaxMinFlowMultiplexer( if (activeInputs.isEmpty()) { _demand = 0.0 _rate = 0.0 - return + return Long.MAX_VALUE } val capacity = _capacity @@ -187,7 +219,7 @@ public class MaxMinFlowMultiplexer( // Pull in the work of the outputs val inputIterator = activeInputs.listIterator() for (input in inputIterator) { - input.pull(now) + input.pullSync() // Remove outputs that have finished if (!input.isActive) { @@ -197,6 +229,7 @@ public class MaxMinFlowMultiplexer( } var demand = 0.0 + var deadline = Long.MAX_VALUE // Sort in-place the inputs based on their pushed flow. // Profiling shows that it is faster than maintaining some kind of sorted set. @@ -209,15 +242,11 @@ public class MaxMinFlowMultiplexer( val availableShare = availableCapacity / remaining-- val grantedRate = min(input.allowedRate, availableShare) - // Ignore empty sources - if (grantedRate <= 0.0) { - input.actualRate = 0.0 - continue - } - - input.actualRate = grantedRate demand += input.limit + deadline = min(deadline, input.deadline) availableCapacity -= grantedRate + + input.actualRate = grantedRate } val rate = capacity - availableCapacity @@ -237,6 +266,8 @@ public class MaxMinFlowMultiplexer( output.push(grantedSpeed) } + + return deadline } /** @@ -280,6 +311,18 @@ public class MaxMinFlowMultiplexer( _counters.remaining += (previousCapacity - _rate) * deltaS } + /** + * Updates the output that is used for scheduler activation. + */ + private fun updateActivationOutput() { + val output = _activeOutputs.firstOrNull() + _activationOutput = output + + for (input in _activeInputs) { + input.enableTimers = output == null + } + } + /** * An internal [FlowConsumer] implementation for multiplexer inputs. */ @@ -304,14 +347,24 @@ public class MaxMinFlowMultiplexer( get() = min(capacity, limit) /** - * A flag to indicate that the input is closed. + * The deadline of the input. */ - private var _isClosed: Boolean = false + val deadline: Long + get() = ctx?.deadline ?: Long.MAX_VALUE + + /** + * A flag to enable timers for the input. + */ + var enableTimers: Boolean = true + set(value) { + field = value + ctx?.enableTimers = value + } /** - * The timestamp at which we received the last command. + * A flag to indicate that the input is closed. */ - private var _lastPull: Long = Long.MIN_VALUE + private var _isClosed: Boolean = false /** * The interference domain this input belongs to. @@ -335,11 +388,15 @@ public class MaxMinFlowMultiplexer( check(!_isClosed) { "Cannot re-use closed input" } _activeInputs += this + if (parent != null) { ctx.shouldConsumerConverge = true } + enableTimers = _activationOutput == null // Disable timers of the source if one of the output manages it super.start(ctx) + + triggerScheduler(engine.clock.millis()) } /* FlowConsumerLogic */ @@ -353,9 +410,8 @@ public class MaxMinFlowMultiplexer( actualRate = 0.0 limit = rate - _lastPull = now - runScheduler(now) + triggerScheduler(now) } override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { @@ -375,7 +431,6 @@ public class MaxMinFlowMultiplexer( limit = 0.0 actualRate = 0.0 - _lastPull = now // Assign a new input responsible for handling the convergence events if (_lastConvergeInput == this) { @@ -383,7 +438,10 @@ public class MaxMinFlowMultiplexer( } // Re-run scheduler to distribute new load - runScheduler(now) + triggerScheduler(now) + + // BUG: Cancel the connection so that `ctx` is set to `null` + cancel() } /* Comparable */ @@ -392,11 +450,8 @@ public class MaxMinFlowMultiplexer( /** * Pull the source if necessary. */ - fun pull(now: Long) { - val ctx = ctx - if (ctx != null && _lastPull < now) { - ctx.flush() - } + fun pullSync() { + ctx?.pullSync() } /** @@ -454,6 +509,13 @@ public class MaxMinFlowMultiplexer( _conn?.close() } + /** + * Pull this output. + */ + fun pull() { + _conn?.pull() + } + override fun onStart(conn: FlowConnection, now: Long) { assert(_conn == null) { "Source running concurrently" } _conn = conn @@ -461,6 +523,7 @@ public class MaxMinFlowMultiplexer( _activeOutputs.add(this) updateCapacity() + updateActivationOutput() } override fun onStop(conn: FlowConnection, now: Long, delta: Long) { @@ -469,8 +532,9 @@ public class MaxMinFlowMultiplexer( _activeOutputs.remove(this) updateCapacity() + updateActivationOutput() - runScheduler(now) + triggerScheduler(now) } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { @@ -480,9 +544,19 @@ public class MaxMinFlowMultiplexer( updateCapacity() } - // Re-run scheduler to distribute new load - runScheduler(now) - return Long.MAX_VALUE + return if (_activationOutput == this) { + // If this output is the activation output, synchronously run the scheduler and return the new deadline + val deadline = runScheduler(now) + if (deadline == Long.MAX_VALUE) + deadline + else + deadline - now + } else { + // Output is not the activation output, so trigger activation output and do not install timer for this + // output (by returning `Long.MAX_VALUE`) + triggerScheduler(now) + Long.MAX_VALUE + } } override fun compareTo(other: Output): Int = capacity.compareTo(other.capacity) -- cgit v1.2.3 From 0ec821157767a630ff82f980f4990ec9d1b75573 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 5 Oct 2021 11:05:23 +0200 Subject: refactor(simulator): Extract scheduler for max min multiplexer --- .../org/opendc/simulator/flow/internal/Flags.kt | 6 +- .../flow/internal/FlowConsumerContextImpl.kt | 70 +-- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 554 +++++++++++++-------- 3 files changed, 383 insertions(+), 247 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt index 939c5c98..97d56fff 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Flags.kt @@ -35,9 +35,9 @@ internal const val ConnState = 0b11 // Mask for accessing the state of the flow */ internal const val ConnPulled = 1 shl 2 // The source should be pulled internal const val ConnPushed = 1 shl 3 // The source has pushed a value -internal const val ConnUpdateActive = 1 shl 4 // An update for the connection is active -internal const val ConnUpdatePending = 1 shl 5 // An (immediate) update of the connection is pending -internal const val ConnUpdateSkipped = 1 shl 6 // An update of the connection was not necessary +internal const val ConnClose = 1 shl 4 // The connection should be closed +internal const val ConnUpdateActive = 1 shl 5 // An update for the connection is active +internal const val ConnUpdatePending = 1 shl 6 // An (immediate) update of the connection is pending internal const val ConnConvergePending = 1 shl 7 // Indication that a convergence is already pending internal const val ConnConvergeSource = 1 shl 8 // Enable convergence of the source internal const val ConnConvergeConsumer = 1 shl 9 // Enable convergence of the consumer diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index c7a8c3de..f15d7fb0 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -150,23 +150,17 @@ internal class FlowConsumerContextImpl( } override fun close() { - var flags = _flags + val flags = _flags if (flags and ConnState == ConnClosed) { return } - engine.batch { - // Mark the connection as closed and pulled (in order to converge) - flags = (flags and ConnState.inv()) or ConnClosed or ConnPulled - _flags = flags - - if (flags and ConnUpdateActive == 0) { - val now = _clock.millis() - doStopSource(now) - - // FIX: Make sure the context converges - scheduleImmediate(now, flags) - } + // Toggle the close bit. In case no update is active, schedule a new update. + if (flags and ConnUpdateActive == 0) { + val now = _clock.millis() + scheduleImmediate(now, flags or ConnClose) + } else { + _flags = flags or ConnClose } } @@ -232,7 +226,7 @@ internal class FlowConsumerContextImpl( val deadline = _deadline val reachedDeadline = deadline == now - var newDeadline = deadline + var newDeadline: Long var hasUpdated = false try { @@ -259,9 +253,13 @@ internal class FlowConsumerContextImpl( deadline } + // Make the new deadline available for the consumer if it has changed + if (newDeadline != deadline) { + _deadline = newDeadline + } + // Push to the consumer if the rate of the source has changed (after a call to `push`) - val newState = flags and ConnState - if (newState == ConnActive && flags and ConnPushed != 0) { + if (flags and ConnPushed != 0) { val lastPush = _lastPush val delta = max(0, now - lastPush) @@ -274,17 +272,33 @@ internal class FlowConsumerContextImpl( // IMPORTANT: Re-fetch the flags after the callback might have changed those flags = _flags - } else if (newState == ConnClosed) { + } + + // Check whether the source or consumer have tried to close the connection + if (flags and ConnClose != 0) { hasUpdated = true // The source has called [FlowConnection.close], so clean up the connection doStopSource(now) + + // IMPORTANT: Re-fetch the flags after the callback might have changed those + // We now also mark the connection as closed + flags = (_flags and ConnState.inv()) or ConnClosed + + _demand = 0.0 + newDeadline = Long.MAX_VALUE } } catch (cause: Throwable) { + hasUpdated = true + + // Clean up the connection + doFailSource(now, cause) + // Mark the connection as closed flags = (flags and ConnState.inv()) or ConnClosed - doFailSource(now, cause) + _demand = 0.0 + newDeadline = Long.MAX_VALUE } // Check whether the connection needs to be added to the visited queue. This is the case when: @@ -316,9 +330,6 @@ internal class FlowConsumerContextImpl( _timer } - // Set the new deadline and schedule a delayed update for that deadline - _deadline = newDeadline - // Check whether we need to schedule a new timer for this connection. That is the case when: // (1) The deadline is valid (not the maximum value) // (2) The connection is active @@ -355,8 +366,8 @@ internal class FlowConsumerContextImpl( // The connection is converging now, so unset the convergence pending flag _flags = flags and ConnConvergePending.inv() - // Call the source converge callback if it has enabled convergence and the connection is active - if (flags and ConnState == ConnActive && flags and ConnConvergeSource != 0) { + // Call the source converge callback if it has enabled convergence + if (flags and ConnConvergeSource != 0) { val delta = max(0, now - _lastSourceConvergence) _lastSourceConvergence = now @@ -371,7 +382,13 @@ internal class FlowConsumerContextImpl( logic.onConverge(this, now, delta) } } catch (cause: Throwable) { + // Invoke the finish callbacks doFailSource(now, cause) + + // Mark the connection as closed + _flags = (_flags and ConnState.inv()) or ConnClosed + _demand = 0.0 + _deadline = Long.MAX_VALUE } } @@ -386,10 +403,6 @@ internal class FlowConsumerContextImpl( doFinishConsumer(now, null) } catch (cause: Throwable) { doFinishConsumer(now, cause) - return - } finally { - _deadline = Long.MAX_VALUE - _demand = 0.0 } } @@ -402,9 +415,6 @@ internal class FlowConsumerContextImpl( } catch (e: Throwable) { e.addSuppressed(cause) doFinishConsumer(now, e) - } finally { - _deadline = Long.MAX_VALUE - _demand = 0.0 } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 22f6516d..c6aa94e2 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -38,7 +38,7 @@ import kotlin.math.min */ public class MaxMinFlowMultiplexer( private val engine: FlowEngine, - private val parent: FlowConvergenceListener? = null, + parent: FlowConvergenceListener? = null, private val interferenceDomain: InterferenceDomain? = null ) : FlowMultiplexer { /** @@ -47,7 +47,6 @@ public class MaxMinFlowMultiplexer( override val inputs: Set get() = _inputs private val _inputs = mutableSetOf() - private val _activeInputs = mutableListOf() /** * The outputs of the multiplexer. @@ -55,55 +54,38 @@ public class MaxMinFlowMultiplexer( override val outputs: Set get() = _outputs private val _outputs = mutableSetOf() - private val _activeOutputs = mutableListOf() /** * The flow counters of this multiplexer. */ public override val counters: FlowCounters - get() = _counters - private val _counters = FlowCountersImpl() + get() = scheduler.counters /** * The actual processing rate of the multiplexer. */ public override val rate: Double - get() = _rate - private var _rate = 0.0 + get() = scheduler.rate /** * The demanded processing rate of the input. */ public override val demand: Double - get() = _demand - private var _demand = 0.0 + get() = scheduler.demand /** * The capacity of the outputs. */ public override val capacity: Double - get() = _capacity - private var _capacity = 0.0 + get() = scheduler.capacity /** - * Flag to indicate that the scheduler is active. + * The [Scheduler] instance of this multiplexer. */ - private var _schedulerActive = false - private var _lastSchedulerCycle = Long.MAX_VALUE - - /** - * The last convergence timestamp and the input. - */ - private var _lastConverge: Long = Long.MIN_VALUE - private var _lastConvergeInput: Input? = null - - /** - * An [Output] that is used to activate the scheduler. - */ - private var _activationOutput: Output? = null + private val scheduler = Scheduler(engine, parent) override fun newInput(key: InterferenceKey?): FlowConsumer { - val provider = Input(_capacity, key) + val provider = Input(engine, scheduler, interferenceDomain, key) _inputs.add(provider) return provider } @@ -117,7 +99,7 @@ public class MaxMinFlowMultiplexer( } override fun newOutput(): FlowSource { - val output = Output() + val output = Output(scheduler) _outputs.add(output) return output } @@ -151,185 +133,330 @@ public class MaxMinFlowMultiplexer( } /** - * Trigger the scheduler of the multiplexer. - * - * @param now The current virtual timestamp of the simulation. + * Helper class containing the scheduler state. */ - private fun triggerScheduler(now: Long) { - if (_schedulerActive) { - // No need to trigger the scheduler in case it is already active - return - } + private class Scheduler(private val engine: FlowEngine, private val parent: FlowConvergenceListener?) { + /** + * The flow counters of this scheduler. + */ + @JvmField val counters = FlowCountersImpl() - val activationOutput = _activationOutput + /** + * The flow rate of the multiplexer. + */ + @JvmField var rate = 0.0 - // We can run the scheduler in two ways: - // (1) We can pull one of the multiplexer's outputs. This allows us to cascade multiple pushes by the input - // into a single scheduling cycle, but is slower in case of a few changes at the same timestamp. - // (2) We run the scheduler directly from this method call. This is the fastest approach when there are only - // a few inputs and little changes at the same timestamp. - // We always pick for option (1) unless there are no outputs available. - if (activationOutput != null) { - activationOutput.pull() - return - } else { - runScheduler(now) - } - } + /** + * The demand for the multiplexer. + */ + @JvmField var demand = 0.0 - /** - * Synchronously run the scheduler of the multiplexer. - */ - private fun runScheduler(now: Long): Long { - val lastSchedulerCycle = _lastSchedulerCycle - _lastSchedulerCycle = now + /** + * The capacity of the multiplexer. + */ + @JvmField var capacity = 0.0 + + /** + * An [Output] that is used to activate the scheduler. + */ + @JvmField var activationOutput: Output? = null - val delta = max(0, now - lastSchedulerCycle) + /** + * The active inputs registered with the scheduler. + */ + private val _activeInputs = mutableListOf() - return try { - _schedulerActive = true - doSchedule(delta) - } finally { - _schedulerActive = false + /** + * The active outputs registered with the scheduler. + */ + private val _activeOutputs = mutableListOf() + + /** + * Flag to indicate that the scheduler is active. + */ + private var _schedulerActive = false + private var _lastSchedulerCycle = Long.MAX_VALUE + + /** + * The last convergence timestamp and the input. + */ + private var _lastConverge: Long = Long.MIN_VALUE + private var _lastConvergeInput: Input? = null + + /** + * Register the specified [input] to this scheduler. + */ + fun registerInput(input: Input) { + _activeInputs.add(input) + + val hasActivationOutput = activationOutput != null + + // Disable timers and convergence of the source if one of the output manages it + input.shouldConsumerConverge = !hasActivationOutput + input.enableTimers = !hasActivationOutput + input.capacity = capacity + trigger(engine.clock.millis()) } - } - /** - * Schedule the inputs over the outputs. - * - * @return The deadline after which a new scheduling cycle should start. - */ - private fun doSchedule(delta: Long): Long { - val activeInputs = _activeInputs - val activeOutputs = _activeOutputs - - // Update the counters of the scheduler - updateCounters(delta) - - // If there is no work yet, mark the inputs as idle. - if (activeInputs.isEmpty()) { - _demand = 0.0 - _rate = 0.0 - return Long.MAX_VALUE + /** + * De-register the specified [input] from this scheduler. + */ + fun deregisterInput(input: Input, now: Long) { + // Assign a new input responsible for handling the convergence events + if (_lastConvergeInput == input) { + _lastConvergeInput = null + } + + // Re-run scheduler to distribute new load + trigger(now) } - val capacity = _capacity - var availableCapacity = capacity + /** + * This method is invoked when one of the inputs converges. + */ + fun convergeInput(input: Input, now: Long) { - // Pull in the work of the outputs - val inputIterator = activeInputs.listIterator() - for (input in inputIterator) { - input.pullSync() + val lastConverge = _lastConverge + val lastConvergeInput = _lastConvergeInput + val parent = parent + + if (parent != null && (now > lastConverge || lastConvergeInput == null || lastConvergeInput == input)) { + _lastConverge = now + _lastConvergeInput = input - // Remove outputs that have finished - if (!input.isActive) { - input.actualRate = 0.0 - inputIterator.remove() + parent.onConverge(now, max(0, now - lastConverge)) } } - var demand = 0.0 - var deadline = Long.MAX_VALUE + /** + * Register the specified [output] to this scheduler. + */ + fun registerOutput(output: Output) { + _activeOutputs.add(output) - // Sort in-place the inputs based on their pushed flow. - // Profiling shows that it is faster than maintaining some kind of sorted set. - activeInputs.sort() + updateCapacity() + updateActivationOutput() + } - // Divide the available output capacity fairly over the inputs using max-min fair sharing - var remaining = activeInputs.size - for (i in activeInputs.indices) { - val input = activeInputs[i] - val availableShare = availableCapacity / remaining-- - val grantedRate = min(input.allowedRate, availableShare) + /** + * De-register the specified [output] from this scheduler. + */ + fun deregisterOutput(output: Output, now: Long) { + _activeOutputs.remove(output) + updateCapacity() - demand += input.limit - deadline = min(deadline, input.deadline) - availableCapacity -= grantedRate + trigger(now) + } + + /** + * This method is invoked when one of the outputs converges. + */ + fun convergeOutput(output: Output, now: Long) { + val lastConverge = _lastConverge + val parent = parent + + if (parent != null) { + _lastConverge = now + + parent.onConverge(now, max(0, now - lastConverge)) + } - input.actualRate = grantedRate + if (!output.isActive) { + output.isActivationOutput = false + updateActivationOutput() + } } - val rate = capacity - availableCapacity + /** + * Trigger the scheduler of the multiplexer. + * + * @param now The current virtual timestamp of the simulation. + */ + fun trigger(now: Long) { + if (_schedulerActive) { + // No need to trigger the scheduler in case it is already active + return + } - _demand = demand - _rate = rate + val activationOutput = activationOutput - // Sort all consumers by their capacity - activeOutputs.sort() + // We can run the scheduler in two ways: + // (1) We can pull one of the multiplexer's outputs. This allows us to cascade multiple pushes by the input + // into a single scheduling cycle, but is slower in case of a few changes at the same timestamp. + // (2) We run the scheduler directly from this method call. This is the fastest approach when there are only + // a few inputs and little changes at the same timestamp. + // We always pick for option (1) unless there are no outputs available. + if (activationOutput != null) { + activationOutput.pull() + return + } else { + runScheduler(now) + } + } + + /** + * Synchronously run the scheduler of the multiplexer. + */ + fun runScheduler(now: Long): Long { + val lastSchedulerCycle = _lastSchedulerCycle + _lastSchedulerCycle = now - // Divide the requests over the available capacity of the input resources fairly - for (i in activeOutputs.indices) { - val output = activeOutputs[i] - val inputCapacity = output.capacity - val fraction = inputCapacity / capacity - val grantedSpeed = rate * fraction + val delta = max(0, now - lastSchedulerCycle) - output.push(grantedSpeed) + return try { + _schedulerActive = true + doRunScheduler(delta) + } finally { + _schedulerActive = false + } } - return deadline - } + /** + * Recompute the capacity of the multiplexer. + */ + fun updateCapacity() { + val newCapacity = _activeOutputs.sumOf(Output::capacity) - /** - * Recompute the capacity of the multiplexer. - */ - private fun updateCapacity() { - val newCapacity = _activeOutputs.sumOf(Output::capacity) + // No-op if the capacity is unchanged + if (capacity == newCapacity) { + return + } - // No-op if the capacity is unchanged - if (_capacity == newCapacity) { - return + capacity = newCapacity + + for (input in _activeInputs) { + input.capacity = newCapacity + } } - _capacity = newCapacity + /** + * Updates the output that is used for scheduler activation. + */ + private fun updateActivationOutput() { + val output = _activeOutputs.firstOrNull() + activationOutput = output - for (input in _inputs) { - input.capacity = newCapacity + if (output != null) { + output.isActivationOutput = true + } + + val hasActivationOutput = output != null + + for (input in _activeInputs) { + input.shouldConsumerConverge = !hasActivationOutput + input.enableTimers = !hasActivationOutput + } } - } - /** - * The previous capacity of the multiplexer. - */ - private var _previousCapacity = 0.0 + /** + * Schedule the inputs over the outputs. + * + * @return The deadline after which a new scheduling cycle should start. + */ + private fun doRunScheduler(delta: Long): Long { + val activeInputs = _activeInputs + val activeOutputs = _activeOutputs + + // Update the counters of the scheduler + updateCounters(delta) + + // If there is no work yet, mark the inputs as idle. + if (activeInputs.isEmpty()) { + demand = 0.0 + rate = 0.0 + return Long.MAX_VALUE + } - /** - * Update the counters of the scheduler. - */ - private fun updateCounters(delta: Long) { - val previousCapacity = _previousCapacity - _previousCapacity = _capacity + val capacity = capacity + var availableCapacity = capacity + + // Pull in the work of the outputs + val inputIterator = activeInputs.listIterator() + for (input in inputIterator) { + input.pullSync() + + // Remove outputs that have finished + if (!input.isActive) { + input.actualRate = 0.0 + inputIterator.remove() + } + } - if (delta <= 0) { - return + var demand = 0.0 + var deadline = Long.MAX_VALUE + + // Sort in-place the inputs based on their pushed flow. + // Profiling shows that it is faster than maintaining some kind of sorted set. + activeInputs.sort() + + // Divide the available output capacity fairly over the inputs using max-min fair sharing + val size = activeInputs.size + for (i in activeInputs.indices) { + val input = activeInputs[i] + val availableShare = availableCapacity / (size - i) + val grantedRate = min(input.allowedRate, availableShare) + + demand += input.limit + deadline = min(deadline, input.deadline) + availableCapacity -= grantedRate + + input.actualRate = grantedRate + } + + val rate = capacity - availableCapacity + + this.demand = demand + this.rate = rate + + // Sort all consumers by their capacity + activeOutputs.sort() + + // Divide the requests over the available capacity of the input resources fairly + for (i in activeOutputs.indices) { + val output = activeOutputs[i] + val inputCapacity = output.capacity + val fraction = inputCapacity / capacity + val grantedSpeed = rate * fraction + + output.push(grantedSpeed) + } + + return deadline } - val deltaS = delta / 1000.0 + /** + * The previous capacity of the multiplexer. + */ + private var _previousCapacity = 0.0 - _counters.demand += _demand * deltaS - _counters.actual += _rate * deltaS - _counters.remaining += (previousCapacity - _rate) * deltaS - } + /** + * Update the counters of the scheduler. + */ + private fun updateCounters(delta: Long) { + val previousCapacity = _previousCapacity + _previousCapacity = capacity - /** - * Updates the output that is used for scheduler activation. - */ - private fun updateActivationOutput() { - val output = _activeOutputs.firstOrNull() - _activationOutput = output + if (delta <= 0) { + return + } + + val deltaS = delta / 1000.0 - for (input in _activeInputs) { - input.enableTimers = output == null + counters.demand += demand * deltaS + counters.actual += rate * deltaS + counters.remaining += (previousCapacity - rate) * deltaS } } /** * An internal [FlowConsumer] implementation for multiplexer inputs. */ - private inner class Input(capacity: Double, val key: InterferenceKey?) : - AbstractFlowConsumer(engine, capacity), - FlowConsumerLogic, - Comparable { + private class Input( + engine: FlowEngine, + private val scheduler: Scheduler, + private val interferenceDomain: InterferenceDomain?, + @JvmField val key: InterferenceKey? + ) : AbstractFlowConsumer(engine, scheduler.capacity), FlowConsumerLogic, Comparable { /** * The requested limit. */ @@ -340,18 +467,18 @@ public class MaxMinFlowMultiplexer( */ @JvmField var actualRate: Double = 0.0 - /** - * The processing rate that is allowed by the model constraints. - */ - val allowedRate: Double - get() = min(capacity, limit) - /** * The deadline of the input. */ val deadline: Long get() = ctx?.deadline ?: Long.MAX_VALUE + /** + * The processing rate that is allowed by the model constraints. + */ + val allowedRate: Double + get() = min(capacity, limit) + /** * A flag to enable timers for the input. */ @@ -362,14 +489,18 @@ public class MaxMinFlowMultiplexer( } /** - * A flag to indicate that the input is closed. + * A flag to control whether the input should converge. */ - private var _isClosed: Boolean = false + var shouldConsumerConverge: Boolean = true + set(value) { + field = value + ctx?.shouldConsumerConverge = value + } /** - * The interference domain this input belongs to. + * A flag to indicate that the input is closed. */ - private val interferenceDomain = this@MaxMinFlowMultiplexer.interferenceDomain + private var _isClosed: Boolean = false /** * Close the input. @@ -386,17 +517,8 @@ public class MaxMinFlowMultiplexer( override fun start(ctx: FlowConsumerContext) { check(!_isClosed) { "Cannot re-use closed input" } - - _activeInputs += this - - if (parent != null) { - ctx.shouldConsumerConverge = true - } - enableTimers = _activationOutput == null // Disable timers of the source if one of the output manages it - + scheduler.registerInput(this) super.start(ctx) - - triggerScheduler(engine.clock.millis()) } /* FlowConsumerLogic */ @@ -411,19 +533,7 @@ public class MaxMinFlowMultiplexer( actualRate = 0.0 limit = rate - triggerScheduler(now) - } - - override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { - val lastConverge = _lastConverge - val parent = parent - - if (parent != null && (lastConverge < now || _lastConvergeInput == null)) { - _lastConverge = now - _lastConvergeInput = this - - parent.onConverge(now, max(0, now - lastConverge)) - } + scheduler.trigger(now) } override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { @@ -432,18 +542,16 @@ public class MaxMinFlowMultiplexer( limit = 0.0 actualRate = 0.0 - // Assign a new input responsible for handling the convergence events - if (_lastConvergeInput == this) { - _lastConvergeInput = null - } - - // Re-run scheduler to distribute new load - triggerScheduler(now) + scheduler.deregisterInput(this, now) // BUG: Cancel the connection so that `ctx` is set to `null` cancel() } + override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { + scheduler.convergeInput(this, now) + } + /* Comparable */ override fun compareTo(other: Input): Int = allowedRate.compareTo(other.allowedRate) @@ -464,7 +572,7 @@ public class MaxMinFlowMultiplexer( // Compute the performance penalty due to flow interference val perfScore = if (interferenceDomain != null) { - val load = _rate / _capacity + val load = scheduler.rate / scheduler.capacity interferenceDomain.apply(key, load) } else { 1.0 @@ -477,14 +585,14 @@ public class MaxMinFlowMultiplexer( updateCounters(demand, actual, remaining) - _counters.interference += actual * max(0.0, 1 - perfScore) + scheduler.counters.interference += actual * max(0.0, 1 - perfScore) } } /** * An internal [FlowSource] implementation for multiplexer outputs. */ - private inner class Output : FlowSource, Comparable { + private class Output(private val scheduler: Scheduler) : FlowSource, Comparable { /** * The active [FlowConnection] of this source. */ @@ -495,6 +603,22 @@ public class MaxMinFlowMultiplexer( */ @JvmField var capacity: Double = 0.0 + /** + * A flag to indicate that this output is the activation output. + */ + var isActivationOutput: Boolean + get() = _isActivationOutput + set(value) { + _isActivationOutput = value + _conn?.shouldSourceConverge = value + } + private var _isActivationOutput: Boolean = false + + /** + * A flag to indicate that the output is active. + */ + @JvmField var isActive = false + /** * Push the specified rate to the consumer. */ @@ -520,33 +644,29 @@ public class MaxMinFlowMultiplexer( assert(_conn == null) { "Source running concurrently" } _conn = conn capacity = conn.capacity - _activeOutputs.add(this) + isActive = true - updateCapacity() - updateActivationOutput() + scheduler.registerOutput(this) } override fun onStop(conn: FlowConnection, now: Long, delta: Long) { _conn = null capacity = 0.0 - _activeOutputs.remove(this) + isActive = false - updateCapacity() - updateActivationOutput() - - triggerScheduler(now) + scheduler.deregisterOutput(this, now) } override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { val capacity = capacity if (capacity != conn.capacity) { this.capacity = capacity - updateCapacity() + scheduler.updateCapacity() } - return if (_activationOutput == this) { + return if (_isActivationOutput) { // If this output is the activation output, synchronously run the scheduler and return the new deadline - val deadline = runScheduler(now) + val deadline = scheduler.runScheduler(now) if (deadline == Long.MAX_VALUE) deadline else @@ -554,11 +674,17 @@ public class MaxMinFlowMultiplexer( } else { // Output is not the activation output, so trigger activation output and do not install timer for this // output (by returning `Long.MAX_VALUE`) - triggerScheduler(now) + scheduler.trigger(now) Long.MAX_VALUE } } + override fun onConverge(conn: FlowConnection, now: Long, delta: Long) { + if (_isActivationOutput) { + scheduler.convergeOutput(this, now) + } + } + override fun compareTo(other: Output): Int = capacity.compareTo(other.capacity) } } -- cgit v1.2.3 From bb5da0b8c3f6cea938b0630048af737ee05913ce Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 5 Oct 2021 12:57:56 +0200 Subject: perf(simulator): Ignore sync pulls without changes --- .../org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index f15d7fb0..9a568897 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -182,7 +182,11 @@ internal class FlowConsumerContextImpl( return } - engine.scheduleSync(_clock.millis(), this) + val now = _clock.millis() + + if (flags and (ConnPulled or ConnPushed) != 0 || _deadline == now) { + engine.scheduleSync(now, this) + } } override fun push(rate: Double) { -- cgit v1.2.3 From a6eec366f2a171f112a94d4ed50fe2c6521792a5 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 5 Oct 2021 17:06:09 +0200 Subject: perf(simulator): Only sort outputs on capacity change This change removes the sorting step for the outputs in the scheduling procedure for the max min multiplexer. This step is only necessary when the capacity of one of the outputs changes, which does not happen often. --- .../kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index c6aa94e2..97059e93 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -327,6 +327,9 @@ public class MaxMinFlowMultiplexer( for (input in _activeInputs) { input.capacity = newCapacity } + + // Sort outputs by their capacity + _activeOutputs.sort() } /** @@ -408,9 +411,6 @@ public class MaxMinFlowMultiplexer( this.demand = demand this.rate = rate - // Sort all consumers by their capacity - activeOutputs.sort() - // Divide the requests over the available capacity of the input resources fairly for (i in activeOutputs.indices) { val output = activeOutputs[i] -- cgit v1.2.3 From 94fa3d33d4ef77aca5e70cc7f91ae9dca71d25e7 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 6 Oct 2021 13:12:18 +0200 Subject: perf(simulator): Optimize SimTraceWorkload This change improves the performance of the SimTraceWorkload class by changing the way trace fragments are read and processed by the CPU consumers. --- .../org/opendc/compute/simulator/SimHostTest.kt | 32 +-- .../compute/workload/ComputeWorkloadLoader.kt | 61 ++++-- .../org/opendc/compute/workload/VirtualMachine.kt | 6 +- .../serverless/trace/FunctionTraceWorkload.kt | 5 +- .../simulator/compute/SimMachineBenchmarks.kt | 13 +- .../opendc/simulator/compute/workload/SimTrace.kt | 233 +++++++++++++++++++++ .../simulator/compute/workload/SimTraceFragment.kt | 38 ++++ .../simulator/compute/workload/SimTraceWorkload.kt | 83 +------- .../compute/kernel/SimFairShareHypervisorTest.kt | 52 ++--- .../compute/kernel/SimSpaceSharedHypervisorTest.kt | 14 +- .../compute/workload/SimTraceWorkloadTest.kt | 40 ++-- 11 files changed, 405 insertions(+), 172 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTrace.kt create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceFragment.kt diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 26089b6d..a0ff9228 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -39,6 +39,8 @@ import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.compute.workload.SimTrace +import org.opendc.simulator.compute.workload.SimTraceFragment import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine @@ -105,11 +107,11 @@ internal class SimHostTest { emptyMap(), mapOf( "workload" to SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 2 * 3500.0, 2), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 2), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 2 * 183.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), + SimTraceFragment(duration * 1000, duration * 1000, 2 * 3500.0, 2), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 3000, duration * 1000, 2 * 183.0, 2) ), offset = 1 ) @@ -121,11 +123,11 @@ internal class SimHostTest { emptyMap(), mapOf( "workload" to SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 2), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 2 * 73.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), + SimTraceFragment(duration * 1000, duration * 1000, 2 * 3100.0, 2), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 3000, duration * 1000, 2 * 73.0, 2) ), offset = 1 ) @@ -217,11 +219,11 @@ internal class SimHostTest { emptyMap(), mapOf( "workload" to SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(duration * 1000L, duration * 1000, 2 * 3500.0, 2), - SimTraceWorkload.Fragment(duration * 2000L, duration * 1000, 0.0, 2), - SimTraceWorkload.Fragment(duration * 3000L, duration * 1000, 2 * 183.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), + SimTraceFragment(duration * 1000L, duration * 1000, 2 * 3500.0, 2), + SimTraceFragment(duration * 2000L, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 3000L, duration * 1000, 2 * 183.0, 2) ), offset = 1 ) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index 7c579e39..1a6624f7 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -23,13 +23,14 @@ package org.opendc.compute.workload import mu.KotlinLogging -import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimTrace import org.opendc.trace.* import java.io.File import java.time.Duration import java.time.Instant import java.util.* import java.util.concurrent.ConcurrentHashMap +import kotlin.math.max import kotlin.math.roundToLong /** @@ -51,7 +52,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { /** * Read the fragments into memory. */ - private fun parseFragments(trace: Trace): Map> { + private fun parseFragments(trace: Trace): Map { val reader = checkNotNull(trace.getTable(TABLE_RESOURCE_STATES)).newReader() val idCol = reader.resolve(RESOURCE_ID) @@ -60,7 +61,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { val coresCol = reader.resolve(RESOURCE_CPU_COUNT) val usageCol = reader.resolve(RESOURCE_STATE_CPU_USAGE) - val fragments = mutableMapOf>() + val fragments = mutableMapOf() return try { while (reader.nextRow()) { @@ -70,14 +71,10 @@ public class ComputeWorkloadLoader(private val baseDir: File) { val cores = reader.getInt(coresCol) val cpuUsage = reader.getDouble(usageCol) - val fragment = SimTraceWorkload.Fragment( - time.toEpochMilli(), - duration.toMillis(), - cpuUsage, - cores - ) - - fragments.computeIfAbsent(id) { mutableListOf() }.add(fragment) + val timeMs = time.toEpochMilli() + val deadlineMs = timeMs + duration.toMillis() + val builder = fragments.computeIfAbsent(id) { Builder() } + builder.add(timeMs, deadlineMs, cpuUsage, cores) } fragments @@ -89,7 +86,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { /** * Read the metadata into a workload. */ - private fun parseMeta(trace: Trace, fragments: Map>): List { + private fun parseMeta(trace: Trace, fragments: Map): List { val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader() val idCol = reader.resolve(RESOURCE_ID) @@ -115,8 +112,8 @@ public class ComputeWorkloadLoader(private val baseDir: File) { val requiredMemory = reader.getDouble(memCol) / 1000.0 // Convert from KB to MB val uid = UUID.nameUUIDFromBytes("$id-${counter++}".toByteArray()) - val vmFragments = fragments.getValue(id).asSequence() - val totalLoad = vmFragments.sumOf { (it.usage * it.duration) / 1000.0 } // avg MHz * duration = MFLOPs + val builder = fragments.getValue(id) + val totalLoad = builder.totalLoad entries.add( VirtualMachine( @@ -127,7 +124,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) { totalLoad, submissionTime, endTime, - vmFragments + builder.build() ) ) } @@ -165,4 +162,38 @@ public class ComputeWorkloadLoader(private val baseDir: File) { public fun reset() { cache.clear() } + + /** + * A builder for a VM trace. + */ + private class Builder { + /** + * The total load of the trace. + */ + @JvmField var totalLoad: Double = 0.0 + + /** + * The internal builder for the trace. + */ + private val builder = SimTrace.builder() + + /** + * Add a fragment to the trace. + * + * @param timestamp Timestamp at which the fragment starts (in epoch millis). + * @param deadline Timestamp at which the fragment ends (in epoch millis). + * @param usage CPU usage of this fragment. + * @param cores Number of cores used. + */ + fun add(timestamp: Long, deadline: Long, usage: Double, cores: Int) { + val duration = max(0, deadline - timestamp) + totalLoad += (usage * duration) / 1000.0 // avg MHz * duration = MFLOPs + builder.add(timestamp, deadline, usage, cores) + } + + /** + * Build the trace. + */ + fun build(): SimTrace = builder.build() + } } diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt index 40484b68..5dd239f6 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt @@ -22,7 +22,7 @@ package org.opendc.compute.workload -import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimTrace import java.time.Instant import java.util.* @@ -35,7 +35,7 @@ import java.util.* * @param memCapacity The provisioned memory for the VM. * @param startTime The start time of the VM. * @param stopTime The stop time of the VM. - * @param trace The trace fragments that belong to this VM. + * @param trace The trace that belong to this VM. */ public data class VirtualMachine( val uid: UUID, @@ -45,5 +45,5 @@ public data class VirtualMachine( val totalLoad: Double, val startTime: Instant, val stopTime: Instant, - val trace: Sequence, + val trace: SimTrace, ) diff --git a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt index a119a219..bbe130e3 100644 --- a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt +++ b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt @@ -23,12 +23,15 @@ package org.opendc.experiments.serverless.trace import org.opendc.faas.simulator.workload.SimFaaSWorkload +import org.opendc.simulator.compute.workload.SimTrace +import org.opendc.simulator.compute.workload.SimTraceFragment import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload /** * A [SimFaaSWorkload] for a [FunctionTrace]. */ -public class FunctionTraceWorkload(trace: FunctionTrace) : SimFaaSWorkload, SimWorkload by SimTraceWorkload(trace.samples.asSequence().map { SimTraceWorkload.Fragment(it.timestamp, it.duration, it.cpuUsage, 1) }) { +class FunctionTraceWorkload(trace: FunctionTrace) : + SimFaaSWorkload, SimWorkload by SimTraceWorkload(SimTrace.ofFragments(trace.samples.map { SimTraceFragment(it.timestamp, it.duration, it.cpuUsage, 1) })) { override suspend fun invoke() {} } diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index b8e0227a..cb52d24f 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -22,7 +22,6 @@ package org.opendc.simulator.compute -import javafx.application.Application.launch import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @@ -34,6 +33,7 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.compute.workload.SimTrace import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine @@ -48,7 +48,7 @@ import java.util.concurrent.TimeUnit @OptIn(ExperimentalCoroutinesApi::class) class SimMachineBenchmarks { private lateinit var machineModel: MachineModel - private lateinit var trace: Sequence + private lateinit var trace: SimTrace @Setup fun setUp() { @@ -60,8 +60,13 @@ class SimMachineBenchmarks { ) val random = ThreadLocalRandom.current() - val entries = List(10000) { SimTraceWorkload.Fragment(it * 1000L, 1000, random.nextDouble(0.0, 4500.0), 1) } - trace = entries.asSequence() + val builder = SimTrace.builder() + repeat(10000) { + val timestamp = it.toLong() + val deadline = timestamp + 1000 + builder.add(timestamp, deadline, random.nextDouble(0.0, 4500.0), 1) + } + trace = builder.build() } @Benchmark diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTrace.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTrace.kt new file mode 100644 index 00000000..4f567b55 --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTrace.kt @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.compute.workload + +import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.flow.FlowConnection +import org.opendc.simulator.flow.FlowSource +import kotlin.math.min + +/** + * A workload trace that describes the resource utilization over time in a collection of [SimTraceFragment]s. + * + * @param usageCol The column containing the CPU usage of each fragment (in MHz). + * @param timestampCol The column containing the starting timestamp for each fragment (in epoch millis). + * @param deadlineCol The column containing the ending timestamp for each fragment (in epoch millis). + * @param coresCol The column containing the utilized cores. + * @param size The number of fragments in the trace. + */ +public class SimTrace( + private val usageCol: DoubleArray, + private val timestampCol: LongArray, + private val deadlineCol: LongArray, + private val coresCol: IntArray, + private val size: Int, +) { + init { + require(size >= 0) { "Invalid trace size" } + require(usageCol.size >= size) { "Invalid number of usage entries" } + require(timestampCol.size >= size) { "Invalid number of timestamp entries" } + require(deadlineCol.size >= size) { "Invalid number of deadline entries" } + require(coresCol.size >= size) { "Invalid number of core entries" } + } + + public companion object { + /** + * Construct a [SimTrace] with the specified fragments. + */ + public fun ofFragments(fragments: List): SimTrace { + val size = fragments.size + val usageCol = DoubleArray(size) + val timestampCol = LongArray(size) + val deadlineCol = LongArray(size) + val coresCol = IntArray(size) + + for (i in fragments.indices) { + val fragment = fragments[i] + usageCol[i] = fragment.usage + timestampCol[i] = fragment.timestamp + deadlineCol[i] = fragment.timestamp + fragment.duration + coresCol[i] = fragment.cores + } + + return SimTrace(usageCol, timestampCol, deadlineCol, coresCol, size) + } + + /** + * Construct a [SimTrace] with the specified fragments. + */ + @JvmStatic + public fun ofFragments(vararg fragments: SimTraceFragment): SimTrace { + val size = fragments.size + val usageCol = DoubleArray(size) + val timestampCol = LongArray(size) + val deadlineCol = LongArray(size) + val coresCol = IntArray(size) + + for (i in fragments.indices) { + val fragment = fragments[i] + usageCol[i] = fragment.usage + timestampCol[i] = fragment.timestamp + deadlineCol[i] = fragment.timestamp + fragment.duration + coresCol[i] = fragment.cores + } + + return SimTrace(usageCol, timestampCol, deadlineCol, coresCol, size) + } + + /** + * Create a [SimTrace.Builder] instance. + */ + @JvmStatic + public fun builder(): Builder = Builder() + } + + /** + * Construct a new [FlowSource] for the specified [cpu]. + */ + public fun newSource(cpu: ProcessingUnit, offset: Long): FlowSource { + return CpuConsumer(cpu, offset, usageCol, timestampCol, deadlineCol, coresCol, size) + } + + /** + * A builder class for a [SimTrace]. + */ + public class Builder internal constructor() { + /** + * The columns of the trace. + */ + private var usageCol: DoubleArray = DoubleArray(16) + private var timestampCol: LongArray = LongArray(16) + private var deadlineCol: LongArray = LongArray(16) + private var coresCol: IntArray = IntArray(16) + + /** + * The number of entries in the trace. + */ + private var size = 0 + + /** + * Add the specified [SimTraceFragment] to the trace. + */ + public fun add(fragment: SimTraceFragment) { + add(fragment.timestamp, fragment.timestamp + fragment.duration, fragment.usage, fragment.cores) + } + + /** + * Add a fragment to the trace. + * + * @param timestamp Timestamp at which the fragment starts (in epoch millis). + * @param deadline Timestamp at which the fragment ends (in epoch millis). + * @param usage CPU usage of this fragment. + * @param cores Number of cores used. + */ + public fun add(timestamp: Long, deadline: Long, usage: Double, cores: Int) { + val size = size + + if (size == usageCol.size) { + grow() + } + + timestampCol[size] = timestamp + deadlineCol[size] = deadline + usageCol[size] = usage + coresCol[size] = cores + + this.size++ + } + + /** + * Helper function to grow the capacity of the column arrays. + */ + private fun grow() { + val arraySize = usageCol.size + val newSize = arraySize * 2 + + usageCol = usageCol.copyOf(newSize) + timestampCol = timestampCol.copyOf(newSize) + deadlineCol = deadlineCol.copyOf(newSize) + coresCol = coresCol.copyOf(newSize) + } + + /** + * Construct the immutable [SimTrace]. + */ + public fun build(): SimTrace { + return SimTrace(usageCol, timestampCol, deadlineCol, coresCol, size) + } + } + + /** + * A CPU consumer for the trace workload. + */ + private class CpuConsumer( + cpu: ProcessingUnit, + private val offset: Long, + private val usageCol: DoubleArray, + private val timestampCol: LongArray, + private val deadlineCol: LongArray, + private val coresCol: IntArray, + private val size: Int + ) : FlowSource { + private val id = cpu.id + private val coreCount = cpu.node.coreCount + + /** + * The index in the trace. + */ + private var _idx = 0 + + override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { + val size = size + val nowOffset = now - offset + + var idx = _idx + val deadlines = deadlineCol + var deadline = deadlines[idx] + + while (deadline <= nowOffset && ++idx < size) { + deadline = deadlines[idx] + } + + if (idx >= size) { + conn.close() + return Long.MAX_VALUE + } + + _idx = idx + val timestamp = timestampCol[idx] + + // Fragment is in the future + if (timestamp > nowOffset) { + conn.push(0.0) + return timestamp - nowOffset + } + + val cores = min(coreCount, coresCol[idx]) + val usage = usageCol[idx] + + conn.push(if (id < cores) usage / cores else 0.0) + return deadline - nowOffset + } + } +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceFragment.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceFragment.kt new file mode 100644 index 00000000..5285847f --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceFragment.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.compute.workload + +/** + * A fragment of the workload trace. + * + * @param timestamp The timestamp at which the fragment starts (in epoch millis). + * @param duration The duration of the fragment (in milliseconds). + * @param usage The CPU usage during the fragment (in MHz). + * @param cores The amount of cores utilized during the fragment. + */ +public data class SimTraceFragment( + @JvmField val timestamp: Long, + @JvmField val duration: Long, + @JvmField val usage: Double, + @JvmField val cores: Int +) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index 49ae5933..53c98409 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -23,10 +23,6 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.flow.FlowConnection -import org.opendc.simulator.flow.FlowSource -import kotlin.math.min /** * A [SimWorkload] that replays a workload trace consisting of multiple fragments, each indicating the resource @@ -35,89 +31,14 @@ import kotlin.math.min * @param trace The trace of fragments to use. * @param offset The offset for the timestamps. */ -public class SimTraceWorkload(public val trace: Sequence, private val offset: Long = 0L) : SimWorkload { - private val iterator = trace.iterator() - private var fragment: Fragment? = null - +public class SimTraceWorkload(private val trace: SimTrace, private val offset: Long = 0L) : SimWorkload { override fun onStart(ctx: SimMachineContext) { val lifecycle = SimWorkloadLifecycle(ctx) for (cpu in ctx.cpus) { - cpu.startConsumer(lifecycle.waitFor(Consumer(cpu.model))) + cpu.startConsumer(lifecycle.waitFor(trace.newSource(cpu.model, offset))) } } override fun toString(): String = "SimTraceWorkload" - - /** - * Obtain the fragment with a timestamp equal or greater than [now]. - */ - private fun pullFragment(now: Long): Fragment? { - // Return the most recent fragment if its starting time + duration is later than `now` - var fragment = fragment - if (fragment != null && fragment.timestamp + offset + fragment.duration > now) { - return fragment - } - - while (iterator.hasNext()) { - fragment = iterator.next() - if (fragment.timestamp + offset + fragment.duration > now) { - this.fragment = fragment - return fragment - } - } - - this.fragment = null - return null - } - - private inner class Consumer(cpu: ProcessingUnit) : FlowSource { - private val offset = this@SimTraceWorkload.offset - private val id = cpu.id - private val coreCount = cpu.node.coreCount - - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - val fragment = pullFragment(now) - - if (fragment == null) { - conn.close() - return Long.MAX_VALUE - } - - val timestamp = fragment.timestamp + offset - - // Fragment is in the future - if (timestamp > now) { - conn.push(0.0) - return timestamp - now - } - - val cores = min(coreCount, fragment.cores) - val usage = if (fragment.cores > 0) - fragment.usage / cores - else - 0.0 - val deadline = timestamp + fragment.duration - val duration = deadline - now - - conn.push(if (id < cores && usage > 0.0) usage else 0.0) - - return duration - } - } - - /** - * A fragment of the workload. - * - * @param timestamp The timestamp at which the fragment starts. - * @param duration The duration of the fragment. - * @param usage The CPU usage during the fragment. - * @param cores The amount of cores utilized during the fragment. - */ - public data class Fragment( - @JvmField val timestamp: Long, - @JvmField val duration: Long, - @JvmField val usage: Double, - @JvmField val cores: Int - ) } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt index 9db2e6ec..6f32cf46 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt @@ -38,6 +38,8 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver +import org.opendc.simulator.compute.workload.SimTrace +import org.opendc.simulator.compute.workload.SimTraceFragment import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine @@ -66,11 +68,11 @@ internal class SimFairShareHypervisorTest { val duration = 5 * 60L val workloadA = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 28.0, 1), + SimTraceFragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceFragment(duration * 3000, duration * 1000, 183.0, 1) ), ) @@ -106,20 +108,20 @@ internal class SimFairShareHypervisorTest { val duration = 5 * 60L val workloadA = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 28.0, 1), + SimTraceFragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceFragment(duration * 3000, duration * 1000, 183.0, 1) ), ) val workloadB = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3100.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 28.0, 1), + SimTraceFragment(duration * 1000, duration * 1000, 3100.0, 1), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceFragment(duration * 3000, duration * 1000, 73.0, 1) ) ) @@ -201,20 +203,20 @@ internal class SimFairShareHypervisorTest { val duration = 5 * 60L val workloadA = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 0.0, 1), + SimTraceFragment(duration * 1000, duration * 1000, 28.0, 1), + SimTraceFragment(duration * 2000, duration * 1000, 3500.0, 1), + SimTraceFragment(duration * 3000, duration * 1000, 183.0, 1) ), ) val workloadB = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 3100.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 73.0, 1) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 0.0, 1), + SimTraceFragment(duration * 1000, duration * 1000, 28.0, 1), + SimTraceFragment(duration * 2000, duration * 1000, 3100.0, 1), + SimTraceFragment(duration * 3000, duration * 1000, 73.0, 1) ) ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index b05ffd22..02d308ff 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -36,9 +36,7 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.compute.workload.SimFlopsWorkload -import org.opendc.simulator.compute.workload.SimRuntimeWorkload -import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.* import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine @@ -66,11 +64,11 @@ internal class SimSpaceSharedHypervisorTest { val duration = 5 * 60L val workloadA = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, duration * 1000, 28.0, 1), - SimTraceWorkload.Fragment(duration * 1000, duration * 1000, 3500.0, 1), - SimTraceWorkload.Fragment(duration * 2000, duration * 1000, 0.0, 1), - SimTraceWorkload.Fragment(duration * 3000, duration * 1000, 183.0, 1) + SimTrace.ofFragments( + SimTraceFragment(0, duration * 1000, 28.0, 1), + SimTraceFragment(duration * 1000, duration * 1000, 3500.0, 1), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 1), + SimTraceFragment(duration * 3000, duration * 1000, 183.0, 1) ), ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt index cdbffe4b..574860e8 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkloadTest.kt @@ -58,11 +58,11 @@ class SimTraceWorkloadTest { ) val workload = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(2000, 1000, 0.0, 2), - SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, 1000, 2 * 28.0, 2), + SimTraceFragment(1000, 1000, 2 * 3100.0, 2), + SimTraceFragment(2000, 1000, 0.0, 2), + SimTraceFragment(3000, 1000, 2 * 73.0, 2) ), offset = 0 ) @@ -85,11 +85,11 @@ class SimTraceWorkloadTest { ) val workload = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(2000, 1000, 0.0, 2), - SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, 1000, 2 * 28.0, 2), + SimTraceFragment(1000, 1000, 2 * 3100.0, 2), + SimTraceFragment(2000, 1000, 0.0, 2), + SimTraceFragment(3000, 1000, 2 * 73.0, 2) ), offset = 1000 ) @@ -112,11 +112,11 @@ class SimTraceWorkloadTest { ) val workload = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(2000, 1000, 0.0, 2), - SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, 1000, 2 * 28.0, 2), + SimTraceFragment(1000, 1000, 2 * 3100.0, 2), + SimTraceFragment(2000, 1000, 0.0, 2), + SimTraceFragment(3000, 1000, 2 * 73.0, 2) ), offset = 0 ) @@ -140,11 +140,11 @@ class SimTraceWorkloadTest { ) val workload = SimTraceWorkload( - sequenceOf( - SimTraceWorkload.Fragment(0, 1000, 2 * 28.0, 2), - SimTraceWorkload.Fragment(1000, 1000, 2 * 3100.0, 2), - SimTraceWorkload.Fragment(2000, 1000, 0.0, 0), - SimTraceWorkload.Fragment(3000, 1000, 2 * 73.0, 2) + SimTrace.ofFragments( + SimTraceFragment(0, 1000, 2 * 28.0, 2), + SimTraceFragment(1000, 1000, 2 * 3100.0, 2), + SimTraceFragment(2000, 1000, 0.0, 0), + SimTraceFragment(3000, 1000, 2 * 73.0, 2) ), offset = 0 ) -- cgit v1.2.3 From a0340a8752c4c4ed8413944b1dfb81b9481b6556 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 6 Oct 2021 14:29:31 +0200 Subject: perf(simulator): Skip fair-share algorithm if capacity remaining This change updates the MaxMinFlowMultiplexer implementation to skip the fair-share algorithm in case the total demand is lower than the available capacity. In this case, no re-division of capacity is necessary. --- .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 60 ++++++++++++++-------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 337d68bf..e34c5bdc 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -213,7 +213,7 @@ class CapelinIntegrationTest { { assertEquals(6013515, this@CapelinIntegrationTest.exporter.idleTime) { "Idle time incorrect" } }, { assertEquals(14724500, this@CapelinIntegrationTest.exporter.activeTime) { "Active time incorrect" } }, { assertEquals(12530742, this@CapelinIntegrationTest.exporter.stealTime) { "Steal time incorrect" } }, - { assertEquals(481270, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } + { assertEquals(481251, this@CapelinIntegrationTest.exporter.lostTime) { "Lost time incorrect" } } ) } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 97059e93..9131eb54 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -372,6 +372,8 @@ public class MaxMinFlowMultiplexer( val capacity = capacity var availableCapacity = capacity + var deadline = Long.MAX_VALUE + var demand = 0.0 // Pull in the work of the outputs val inputIterator = activeInputs.listIterator() @@ -382,32 +384,36 @@ public class MaxMinFlowMultiplexer( if (!input.isActive) { input.actualRate = 0.0 inputIterator.remove() + } else { + demand += input.limit + deadline = min(deadline, input.deadline) } } - var demand = 0.0 - var deadline = Long.MAX_VALUE + val rate = if (demand > capacity) { + // If the demand is higher than the capacity, we need use max-min fair sharing to distribute the + // constrained capacity across the inputs. - // Sort in-place the inputs based on their pushed flow. - // Profiling shows that it is faster than maintaining some kind of sorted set. - activeInputs.sort() + // Sort in-place the inputs based on their pushed flow. + // Profiling shows that it is faster than maintaining some kind of sorted set. + activeInputs.sort() - // Divide the available output capacity fairly over the inputs using max-min fair sharing - val size = activeInputs.size - for (i in activeInputs.indices) { - val input = activeInputs[i] - val availableShare = availableCapacity / (size - i) - val grantedRate = min(input.allowedRate, availableShare) + // Divide the available output capacity fairly over the inputs using max-min fair sharing + val size = activeInputs.size + for (i in activeInputs.indices) { + val input = activeInputs[i] + val availableShare = availableCapacity / (size - i) + val grantedRate = min(input.allowedRate, availableShare) - demand += input.limit - deadline = min(deadline, input.deadline) - availableCapacity -= grantedRate + availableCapacity -= grantedRate + input.actualRate = grantedRate + } - input.actualRate = grantedRate + capacity - availableCapacity + } else { + demand } - val rate = capacity - availableCapacity - this.demand = demand this.rate = rate @@ -467,6 +473,11 @@ public class MaxMinFlowMultiplexer( */ @JvmField var actualRate: Double = 0.0 + /** + * The processing rate that is allowed by the model constraints. + */ + @JvmField var allowedRate: Double = 0.0 + /** * The deadline of the input. */ @@ -474,10 +485,14 @@ public class MaxMinFlowMultiplexer( get() = ctx?.deadline ?: Long.MAX_VALUE /** - * The processing rate that is allowed by the model constraints. + * The capacity of the input. */ - val allowedRate: Double - get() = min(capacity, limit) + override var capacity: Double + get() = super.capacity + set(value) { + allowedRate = min(limit, value) + super.capacity = value + } /** * A flag to enable timers for the input. @@ -530,8 +545,10 @@ public class MaxMinFlowMultiplexer( ) { doUpdateCounters(delta) - actualRate = 0.0 + val allowed = min(rate, capacity) limit = rate + actualRate = allowed + allowedRate = allowed scheduler.trigger(now) } @@ -541,6 +558,7 @@ public class MaxMinFlowMultiplexer( limit = 0.0 actualRate = 0.0 + allowedRate = 0.0 scheduler.deregisterInput(this, now) -- cgit v1.2.3 From 774ed886ac8f84ae2974c1204534ee332d920864 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 7 Oct 2021 14:39:03 +0200 Subject: fix(simulator): Count interference for multiplexer inputs This change updates the SimAbstractHypervisor and MaxMinFlowMultiplexer to count interference of multiplexer inputs, instead of only counting them for the scheduler as a whole. --- .../compute/kernel/SimAbstractHypervisor.kt | 90 +++++++------ .../opendc/simulator/flow/AbstractFlowConsumer.kt | 26 +--- .../org/opendc/simulator/flow/FlowForwarder.kt | 9 +- .../kotlin/org/opendc/simulator/flow/FlowSink.kt | 12 +- .../simulator/flow/internal/FlowCountersImpl.kt | 46 ------- .../simulator/flow/internal/MutableFlowCounters.kt | 56 ++++++++ .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 147 ++++++++++++++------- 7 files changed, 225 insertions(+), 161 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/MutableFlowCounters.kt diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index aac8b959..f6d8f628 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -66,45 +66,7 @@ public abstract class SimAbstractHypervisor( */ public override val counters: SimHypervisorCounters get() = _counters - private val _counters = object : SimHypervisorCounters { - @JvmField var d = 1.0 // Number of CPUs divided by total CPU capacity - - override var cpuActiveTime: Long = 0L - override var cpuIdleTime: Long = 0L - override var cpuStealTime: Long = 0L - override var cpuLostTime: Long = 0L - - private var _previousDemand = 0.0 - private var _previousActual = 0.0 - private var _previousRemaining = 0.0 - private var _previousInterference = 0.0 - - /** - * Record the CPU time of the hypervisor. - */ - fun record() { - val counters = mux.counters - val demand = counters.demand - val actual = counters.actual - val remaining = counters.remaining - val interference = counters.interference - - val demandDelta = demand - _previousDemand - val actualDelta = actual - _previousActual - val remainingDelta = remaining - _previousRemaining - val interferenceDelta = interference - _previousInterference - - _previousDemand = demand - _previousActual = actual - _previousRemaining = remaining - _previousInterference = interference - - cpuActiveTime += (actualDelta * d).roundToLong() - cpuIdleTime += (remainingDelta * d).roundToLong() - cpuStealTime += ((demandDelta - actualDelta) * d).roundToLong() - cpuLostTime += (interferenceDelta * d).roundToLong() - } - } + private val _counters = CountersImpl(this) /** * The CPU capacity of the hypervisor in MHz. @@ -204,7 +166,7 @@ public abstract class SimAbstractHypervisor( get() = (cpus.sumOf { it.counters.actual + it.counters.remaining } * d).roundToLong() override val cpuStealTime: Long get() = (cpus.sumOf { it.counters.demand - it.counters.actual } * d).roundToLong() - override val cpuLostTime: Long = 0L + override val cpuLostTime: Long = (cpus.sumOf { it.counters.interference } * d).roundToLong() } /** @@ -277,4 +239,52 @@ public abstract class SimAbstractHypervisor( override val min: Double = 0.0 } + + /** + * Implementation of [SimHypervisorCounters]. + */ + private class CountersImpl(private val hv: SimAbstractHypervisor) : SimHypervisorCounters { + @JvmField var d = 1.0 // Number of CPUs divided by total CPU capacity + + override val cpuActiveTime: Long + get() = _cpuTime[0] + override val cpuIdleTime: Long + get() = _cpuTime[1] + override val cpuStealTime: Long + get() = _cpuTime[2] + override val cpuLostTime: Long + get() = _cpuTime[3] + + private val _cpuTime = LongArray(4) + private val _previous = DoubleArray(4) + + /** + * Record the CPU time of the hypervisor. + */ + fun record() { + val cpuTime = _cpuTime + val previous = _previous + val counters = hv.mux.counters + + val demand = counters.demand + val actual = counters.actual + val remaining = counters.remaining + val interference = counters.interference + + val demandDelta = demand - previous[0] + val actualDelta = actual - previous[1] + val remainingDelta = remaining - previous[2] + val interferenceDelta = interference - previous[3] + + previous[0] = demand + previous[1] = actual + previous[2] = remaining + previous[3] = interference + + cpuTime[0] += (actualDelta * d).roundToLong() + cpuTime[1] += (remainingDelta * d).roundToLong() + cpuTime[2] += ((demandDelta - actualDelta) * d).roundToLong() + cpuTime[3] += (interferenceDelta * d).roundToLong() + } + } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt index b02426e3..5f1057e8 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt @@ -22,7 +22,7 @@ package org.opendc.simulator.flow -import org.opendc.simulator.flow.internal.FlowCountersImpl +import org.opendc.simulator.flow.internal.MutableFlowCounters /** * Abstract implementation of the [FlowConsumer] which can be re-used by other implementations. @@ -55,13 +55,6 @@ public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initi public override val demand: Double get() = ctx?.demand ?: 0.0 - /** - * The flow counters to track the flow metrics of the consumer. - */ - public override val counters: FlowCounters - get() = _counters - private val _counters = FlowCountersImpl() - /** * The [FlowConsumerContext] that is currently running. */ @@ -89,7 +82,7 @@ public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initi /** * Update the counters of the flow consumer. */ - protected fun updateCounters(ctx: FlowConnection, delta: Long) { + protected fun MutableFlowCounters.update(ctx: FlowConnection, delta: Long) { val demand = _previousDemand val capacity = _previousCapacity @@ -100,25 +93,12 @@ public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initi return } - val counters = _counters val deltaS = delta / 1000.0 val total = demand * deltaS val work = capacity * deltaS val actualWork = ctx.rate * deltaS - counters.demand += work - counters.actual += actualWork - counters.remaining += (total - actualWork) - } - - /** - * Update the counters of the flow consumer. - */ - protected fun updateCounters(demand: Double, actual: Double, remaining: Double) { - val counters = _counters - counters.demand += demand - counters.actual += actual - counters.remaining += remaining + increment(work, actualWork, (total - actualWork), 0.0) } final override fun startConsumer(source: FlowSource) { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index 7eaaf6c2..229fd96a 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -23,7 +23,7 @@ package org.opendc.simulator.flow import mu.KotlinLogging -import org.opendc.simulator.flow.internal.FlowCountersImpl +import org.opendc.simulator.flow.internal.MutableFlowCounters import kotlin.math.max /** @@ -117,7 +117,7 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled override val counters: FlowCounters get() = _counters - private val _counters = FlowCountersImpl() + private val _counters = MutableFlowCounters() override fun startConsumer(source: FlowSource) { check(delegate == null) { "Forwarder already active" } @@ -245,8 +245,7 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled val total = ctx.capacity * deltaS val work = _demand * deltaS val actualWork = ctx.rate * deltaS - counters.demand += work - counters.actual += actualWork - counters.remaining += (total - actualWork) + + counters.increment(work, actualWork, (total - actualWork), 0.0) } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt index b4eb6a38..170ab1c0 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt @@ -22,6 +22,8 @@ package org.opendc.simulator.flow +import org.opendc.simulator.flow.internal.MutableFlowCounters + /** * A [FlowSink] represents a sink with a fixed capacity. * @@ -34,6 +36,12 @@ public class FlowSink( initialCapacity: Double, private val parent: FlowConvergenceListener? = null ) : AbstractFlowConsumer(engine, initialCapacity) { + /** + * The flow counters to track the flow metrics of the consumer. + */ + public override val counters: FlowCounters + get() = _counters + private val _counters = MutableFlowCounters() override fun start(ctx: FlowConsumerContext) { if (parent != null) { @@ -52,11 +60,11 @@ public class FlowSink( delta: Long, rate: Double ) { - updateCounters(ctx, delta) + _counters.update(ctx, delta) } override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { - updateCounters(ctx, delta) + _counters.update(ctx, delta) cancel() } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt deleted file mode 100644 index d2fa5228..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowCountersImpl.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow.internal - -import org.opendc.simulator.flow.FlowCounters - -/** - * Mutable implementation of the [FlowCounters] interface. - */ -internal class FlowCountersImpl : FlowCounters { - override var demand: Double = 0.0 - override var actual: Double = 0.0 - override var remaining: Double = 0.0 - override var interference: Double = 0.0 - - override fun reset() { - demand = 0.0 - actual = 0.0 - remaining = 0.0 - interference = 0.0 - } - - override fun toString(): String { - return "FlowCounters[demand=$demand,actual=$actual,remaining=$remaining,interference=$interference]" - } -} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/MutableFlowCounters.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/MutableFlowCounters.kt new file mode 100644 index 00000000..d990dc61 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/MutableFlowCounters.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +import org.opendc.simulator.flow.FlowCounters + +/** + * Mutable implementation of the [FlowCounters] interface. + */ +public class MutableFlowCounters : FlowCounters { + override val demand: Double + get() = _counters[0] + override val actual: Double + get() = _counters[1] + override val remaining: Double + get() = _counters[2] + override val interference: Double + get() = _counters[3] + private val _counters = DoubleArray(4) + + override fun reset() { + _counters.fill(0.0) + } + + public fun increment(demand: Double, actual: Double, remaining: Double, interference: Double) { + val counters = _counters + counters[0] += demand + counters[1] += actual + counters[2] += remaining + counters[3] += interference + } + + override fun toString(): String { + return "FlowCounters[demand=$demand,actual=$actual,remaining=$remaining,interference=$interference]" + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 9131eb54..eaa3f7c5 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -25,7 +25,7 @@ package org.opendc.simulator.flow.mux import org.opendc.simulator.flow.* import org.opendc.simulator.flow.interference.InterferenceDomain import org.opendc.simulator.flow.interference.InterferenceKey -import org.opendc.simulator.flow.internal.FlowCountersImpl +import org.opendc.simulator.flow.internal.MutableFlowCounters import kotlin.math.max import kotlin.math.min @@ -85,7 +85,7 @@ public class MaxMinFlowMultiplexer( private val scheduler = Scheduler(engine, parent) override fun newInput(key: InterferenceKey?): FlowConsumer { - val provider = Input(engine, scheduler, interferenceDomain, key) + val provider = Input(engine, scheduler, interferenceDomain, key, scheduler.capacity) _inputs.add(provider) return provider } @@ -135,11 +135,11 @@ public class MaxMinFlowMultiplexer( /** * Helper class containing the scheduler state. */ - private class Scheduler(private val engine: FlowEngine, private val parent: FlowConvergenceListener?) { + private class Scheduler(engine: FlowEngine, private val parent: FlowConvergenceListener?) { /** * The flow counters of this scheduler. */ - @JvmField val counters = FlowCountersImpl() + @JvmField val counters = MutableFlowCounters() /** * The flow rate of the multiplexer. @@ -183,6 +183,11 @@ public class MaxMinFlowMultiplexer( private var _lastConverge: Long = Long.MIN_VALUE private var _lastConvergeInput: Input? = null + /** + * The simulation clock. + */ + private val _clock = engine.clock + /** * Register the specified [input] to this scheduler. */ @@ -195,7 +200,7 @@ public class MaxMinFlowMultiplexer( input.shouldConsumerConverge = !hasActivationOutput input.enableTimers = !hasActivationOutput input.capacity = capacity - trigger(engine.clock.millis()) + trigger(_clock.millis()) } /** @@ -447,10 +452,15 @@ public class MaxMinFlowMultiplexer( } val deltaS = delta / 1000.0 - - counters.demand += demand * deltaS - counters.actual += rate * deltaS - counters.remaining += (previousCapacity - rate) * deltaS + val demand = demand + val rate = rate + + counters.increment( + demand = demand * deltaS, + actual = rate * deltaS, + remaining = (previousCapacity - rate) * deltaS, + interference = 0.0 + ) } } @@ -458,41 +468,48 @@ public class MaxMinFlowMultiplexer( * An internal [FlowConsumer] implementation for multiplexer inputs. */ private class Input( - engine: FlowEngine, + private val engine: FlowEngine, private val scheduler: Scheduler, private val interferenceDomain: InterferenceDomain?, - @JvmField val key: InterferenceKey? - ) : AbstractFlowConsumer(engine, scheduler.capacity), FlowConsumerLogic, Comparable { - /** - * The requested limit. - */ - @JvmField var limit: Double = 0.0 - + @JvmField val key: InterferenceKey?, + initialCapacity: Double, + ) : FlowConsumer, FlowConsumerLogic, Comparable { /** - * The actual processing speed. + * A flag to indicate that the consumer is active. */ - @JvmField var actualRate: Double = 0.0 + override val isActive: Boolean + get() = _ctx != null /** - * The processing rate that is allowed by the model constraints. + * The demand of the consumer. */ - @JvmField var allowedRate: Double = 0.0 + override val demand: Double + get() = limit /** - * The deadline of the input. + * The processing rate of the consumer. */ - val deadline: Long - get() = ctx?.deadline ?: Long.MAX_VALUE + override val rate: Double + get() = actualRate /** * The capacity of the input. */ override var capacity: Double - get() = super.capacity + get() = _capacity set(value) { allowedRate = min(limit, value) - super.capacity = value + _capacity = value + _ctx?.capacity = value } + private var _capacity = initialCapacity + + /** + * The flow counters to track the flow metrics of the consumer. + */ + override val counters: FlowCounters + get() = _counters + private val _counters = MutableFlowCounters() /** * A flag to enable timers for the input. @@ -500,7 +517,7 @@ public class MaxMinFlowMultiplexer( var enableTimers: Boolean = true set(value) { field = value - ctx?.enableTimers = value + _ctx?.enableTimers = value } /** @@ -509,9 +526,35 @@ public class MaxMinFlowMultiplexer( var shouldConsumerConverge: Boolean = true set(value) { field = value - ctx?.shouldConsumerConverge = value + _ctx?.shouldConsumerConverge = value } + /** + * The requested limit. + */ + @JvmField var limit: Double = 0.0 + + /** + * The actual processing speed. + */ + @JvmField var actualRate: Double = 0.0 + + /** + * The processing rate that is allowed by the model constraints. + */ + @JvmField var allowedRate: Double = 0.0 + + /** + * The deadline of the input. + */ + val deadline: Long + get() = _ctx?.deadline ?: Long.MAX_VALUE + + /** + * The [FlowConsumerContext] that is currently running. + */ + private var _ctx: FlowConsumerContext? = null + /** * A flag to indicate that the input is closed. */ @@ -527,13 +570,33 @@ public class MaxMinFlowMultiplexer( cancel() } - /* AbstractFlowConsumer */ - override fun createLogic(): FlowConsumerLogic = this + /** + * Pull the source if necessary. + */ + fun pullSync() { + _ctx?.pullSync() + } - override fun start(ctx: FlowConsumerContext) { + /* FlowConsumer */ + override fun startConsumer(source: FlowSource) { check(!_isClosed) { "Cannot re-use closed input" } + check(_ctx == null) { "Consumer is in invalid state" } + + val ctx = engine.newContext(source, this) + _ctx = ctx + + ctx.capacity = capacity scheduler.registerInput(this) - super.start(ctx) + + ctx.start() + } + + override fun pull() { + _ctx?.pull() + } + + override fun cancel() { + _ctx?.close() } /* FlowConsumerLogic */ @@ -562,8 +625,7 @@ public class MaxMinFlowMultiplexer( scheduler.deregisterInput(this, now) - // BUG: Cancel the connection so that `ctx` is set to `null` - cancel() + _ctx = null } override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { @@ -573,13 +635,6 @@ public class MaxMinFlowMultiplexer( /* Comparable */ override fun compareTo(other: Input): Int = allowedRate.compareTo(other.allowedRate) - /** - * Pull the source if necessary. - */ - fun pullSync() { - ctx?.pullSync() - } - /** * Helper method to update the flow counters of the multiplexer. */ @@ -596,14 +651,16 @@ public class MaxMinFlowMultiplexer( 1.0 } + val actualRate = actualRate + val deltaS = delta / 1000.0 val demand = limit * deltaS val actual = actualRate * deltaS - val remaining = (capacity - actualRate) * deltaS - - updateCounters(demand, actual, remaining) + val remaining = (_capacity - actualRate) * deltaS + val interference = actual * max(0.0, 1 - perfScore) - scheduler.counters.interference += actual * max(0.0, 1 - perfScore) + _counters.increment(demand, actual, remaining, interference) + scheduler.counters.increment(0.0, 0.0, 0.0, interference) } } -- cgit v1.2.3 From 54f83291aaff75ed875e507d8dbf9037d3e93710 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 8 Oct 2021 10:58:43 +0200 Subject: refactor(simulator): Simplify FlowSink implementation This change simplifies the FlowSink implementation by not relying on the AbstractFlowConsumer, but instead implementing the FlowConsumer interface itself. --- .../opendc/simulator/flow/AbstractFlowConsumer.kt | 127 --------------------- .../org/opendc/simulator/flow/FlowForwarder.kt | 3 +- .../kotlin/org/opendc/simulator/flow/FlowSink.kt | 123 ++++++++++++++++---- .../opendc/simulator/flow/internal/Constants.kt | 28 +++++ .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 5 +- 5 files changed, 133 insertions(+), 153 deletions(-) delete mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Constants.kt diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt deleted file mode 100644 index 5f1057e8..00000000 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/AbstractFlowConsumer.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.simulator.flow - -import org.opendc.simulator.flow.internal.MutableFlowCounters - -/** - * Abstract implementation of the [FlowConsumer] which can be re-used by other implementations. - */ -public abstract class AbstractFlowConsumer(private val engine: FlowEngine, initialCapacity: Double) : FlowConsumer { - /** - * A flag to indicate that the flow consumer is active. - */ - public override val isActive: Boolean - get() = ctx != null - - /** - * The capacity of the consumer. - */ - public override var capacity: Double = initialCapacity - set(value) { - field = value - ctx?.capacity = value - } - - /** - * The current processing rate of the consumer. - */ - public override val rate: Double - get() = ctx?.rate ?: 0.0 - - /** - * The flow processing rate demand at this instant. - */ - public override val demand: Double - get() = ctx?.demand ?: 0.0 - - /** - * The [FlowConsumerContext] that is currently running. - */ - protected var ctx: FlowConsumerContext? = null - private set - - /** - * Construct the [FlowConsumerLogic] instance for a new source. - */ - protected abstract fun createLogic(): FlowConsumerLogic - - /** - * Start the specified [FlowConsumerContext]. - */ - protected open fun start(ctx: FlowConsumerContext) { - ctx.start() - } - - /** - * The previous demand for the consumer. - */ - private var _previousDemand = 0.0 - private var _previousCapacity = 0.0 - - /** - * Update the counters of the flow consumer. - */ - protected fun MutableFlowCounters.update(ctx: FlowConnection, delta: Long) { - val demand = _previousDemand - val capacity = _previousCapacity - - _previousDemand = ctx.demand - _previousCapacity = ctx.capacity - - if (delta <= 0) { - return - } - - val deltaS = delta / 1000.0 - val total = demand * deltaS - val work = capacity * deltaS - val actualWork = ctx.rate * deltaS - - increment(work, actualWork, (total - actualWork), 0.0) - } - - final override fun startConsumer(source: FlowSource) { - check(ctx == null) { "Consumer is in invalid state" } - val ctx = engine.newContext(source, createLogic()) - - ctx.capacity = capacity - this.ctx = ctx - - start(ctx) - } - - final override fun pull() { - ctx?.pull() - } - - final override fun cancel() { - val ctx = ctx - if (ctx != null) { - this.ctx = null - ctx.close() - } - } - - override fun toString(): String = "AbstractFlowConsumer[capacity=$capacity]" -} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index 229fd96a..7230a966 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -23,6 +23,7 @@ package org.opendc.simulator.flow import mu.KotlinLogging +import org.opendc.simulator.flow.internal.D_MS_TO_S import org.opendc.simulator.flow.internal.MutableFlowCounters import kotlin.math.max @@ -241,7 +242,7 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled } val counters = _counters - val deltaS = delta / 1000.0 + val deltaS = delta * D_MS_TO_S val total = ctx.capacity * deltaS val work = _demand * deltaS val actualWork = ctx.rate * deltaS diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt index 170ab1c0..e9094443 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowSink.kt @@ -22,6 +22,7 @@ package org.opendc.simulator.flow +import org.opendc.simulator.flow.internal.D_MS_TO_S import org.opendc.simulator.flow.internal.MutableFlowCounters /** @@ -35,7 +36,34 @@ public class FlowSink( private val engine: FlowEngine, initialCapacity: Double, private val parent: FlowConvergenceListener? = null -) : AbstractFlowConsumer(engine, initialCapacity) { +) : FlowConsumer { + /** + * A flag to indicate that the flow consumer is active. + */ + public override val isActive: Boolean + get() = _ctx != null + + /** + * The capacity of the consumer. + */ + public override var capacity: Double = initialCapacity + set(value) { + field = value + _ctx?.capacity = value + } + + /** + * The current processing rate of the consumer. + */ + public override val rate: Double + get() = _ctx?.rate ?: 0.0 + + /** + * The flow processing rate demand at this instant. + */ + public override val demand: Double + get() = _ctx?.demand ?: 0.0 + /** * The flow counters to track the flow metrics of the consumer. */ @@ -43,36 +71,85 @@ public class FlowSink( get() = _counters private val _counters = MutableFlowCounters() - override fun start(ctx: FlowConsumerContext) { + /** + * The current active [FlowConsumerLogic] of this sink. + */ + private var _ctx: FlowConsumerContext? = null + + override fun startConsumer(source: FlowSource) { + check(_ctx == null) { "Consumer is in invalid state" } + + val ctx = engine.newContext(source, Logic(parent, _counters)) + _ctx = ctx + + ctx.capacity = capacity if (parent != null) { ctx.shouldConsumerConverge = true } - super.start(ctx) + + ctx.start() } - override fun createLogic(): FlowConsumerLogic { - return object : FlowConsumerLogic { - private val parent = this@FlowSink.parent - - override fun onPush( - ctx: FlowConsumerContext, - now: Long, - delta: Long, - rate: Double - ) { - _counters.update(ctx, delta) - } + override fun pull() { + _ctx?.pull() + } - override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { - _counters.update(ctx, delta) - cancel() - } + override fun cancel() { + _ctx?.close() + } + + override fun toString(): String = "FlowSink[capacity=$capacity]" + + /** + * [FlowConsumerLogic] of a sink. + */ + private inner class Logic(private val parent: FlowConvergenceListener?, private val counters: MutableFlowCounters) : FlowConsumerLogic { + override fun onPush( + ctx: FlowConsumerContext, + now: Long, + delta: Long, + rate: Double + ) { + updateCounters(ctx, delta, rate, ctx.capacity) + } + + override fun onFinish(ctx: FlowConsumerContext, now: Long, delta: Long, cause: Throwable?) { + updateCounters(ctx, delta, 0.0, 0.0) + + _ctx = null + } + + override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { + parent?.onConverge(now, delta) + } + + /** + * The previous demand and capacity for the consumer. + */ + private val _previous = DoubleArray(2) + + /** + * Update the counters of the flow consumer. + */ + private fun updateCounters(ctx: FlowConnection, delta: Long, nextDemand: Double, nextCapacity: Double) { + val counters = counters + val previous = _previous + val demand = previous[0] + val capacity = previous[1] - override fun onConverge(ctx: FlowConsumerContext, now: Long, delta: Long) { - parent?.onConverge(now, delta) + previous[0] = nextDemand + previous[1] = nextCapacity + + if (delta <= 0) { + return } + + val deltaS = delta * D_MS_TO_S + val total = demand * deltaS + val work = capacity * deltaS + val actualWork = ctx.rate * deltaS + + counters.increment(work, actualWork, (total - actualWork), 0.0) } } - - override fun toString(): String = "FlowSink[capacity=$capacity]" } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Constants.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Constants.kt new file mode 100644 index 00000000..450195ec --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/Constants.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +/** + * Constant for converting milliseconds into seconds. + */ +internal const val D_MS_TO_S = 1 / 1000.0 diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index eaa3f7c5..31fb5b73 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -25,6 +25,7 @@ package org.opendc.simulator.flow.mux import org.opendc.simulator.flow.* import org.opendc.simulator.flow.interference.InterferenceDomain import org.opendc.simulator.flow.interference.InterferenceKey +import org.opendc.simulator.flow.internal.D_MS_TO_S import org.opendc.simulator.flow.internal.MutableFlowCounters import kotlin.math.max import kotlin.math.min @@ -451,7 +452,7 @@ public class MaxMinFlowMultiplexer( return } - val deltaS = delta / 1000.0 + val deltaS = delta * D_MS_TO_S val demand = demand val rate = rate @@ -653,7 +654,7 @@ public class MaxMinFlowMultiplexer( val actualRate = actualRate - val deltaS = delta / 1000.0 + val deltaS = delta * D_MS_TO_S val demand = limit * deltaS val actual = actualRate * deltaS val remaining = (_capacity - actualRate) * deltaS -- cgit v1.2.3 From 043ad5b2713164c76b09ba8cd07af9f0ca1f35e4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 8 Oct 2021 11:16:49 +0200 Subject: perf(simulator): Do not update outputs if rate is unchanged --- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 31fb5b73..28743276 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -421,16 +421,19 @@ public class MaxMinFlowMultiplexer( } this.demand = demand - this.rate = rate - - // Divide the requests over the available capacity of the input resources fairly - for (i in activeOutputs.indices) { - val output = activeOutputs[i] - val inputCapacity = output.capacity - val fraction = inputCapacity / capacity - val grantedSpeed = rate * fraction - - output.push(grantedSpeed) + if (this.rate != rate) { + // Only update the outputs if the output rate has changed + this.rate = rate + + // Divide the requests over the available capacity of the input resources fairly + for (i in activeOutputs.indices) { + val output = activeOutputs[i] + val inputCapacity = output.capacity + val fraction = inputCapacity / capacity + val grantedSpeed = rate * fraction + + output.push(grantedSpeed) + } } return deadline -- cgit v1.2.3 From 4623316cb23ce95cb8ce8db0987f948a8dc1a349 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 8 Oct 2021 11:54:45 +0200 Subject: perf(simulator): Eliminate ArrayList iteration overhead This change eliminates the overhead caused by ArrayList iteration in the MaxMinFlowMultiplexer class. --- .../simulator/flow/mux/MaxMinFlowMultiplexer.kt | 40 ++++++++++++++++------ 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index 28743276..eab5b299 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -167,6 +167,11 @@ public class MaxMinFlowMultiplexer( */ private val _activeInputs = mutableListOf() + /** + * An array containing the active inputs, which is used to reduce the overhead of an [ArrayList]. + */ + private var _inputArray = emptyArray() + /** * The active outputs registered with the scheduler. */ @@ -194,6 +199,7 @@ public class MaxMinFlowMultiplexer( */ fun registerInput(input: Input) { _activeInputs.add(input) + _inputArray = _activeInputs.toTypedArray() val hasActivationOutput = activationOutput != null @@ -201,6 +207,7 @@ public class MaxMinFlowMultiplexer( input.shouldConsumerConverge = !hasActivationOutput input.enableTimers = !hasActivationOutput input.capacity = capacity + trigger(_clock.millis()) } @@ -213,6 +220,8 @@ public class MaxMinFlowMultiplexer( _lastConvergeInput = null } + _activeInputs.remove(input) + // Re-run scheduler to distribute new load trigger(now) } @@ -365,12 +374,14 @@ public class MaxMinFlowMultiplexer( private fun doRunScheduler(delta: Long): Long { val activeInputs = _activeInputs val activeOutputs = _activeOutputs + var inputArray = _inputArray + var inputSize = _inputArray.size // Update the counters of the scheduler updateCounters(delta) // If there is no work yet, mark the inputs as idle. - if (activeInputs.isEmpty()) { + if (inputSize == 0) { demand = 0.0 rate = 0.0 return Long.MAX_VALUE @@ -380,35 +391,42 @@ public class MaxMinFlowMultiplexer( var availableCapacity = capacity var deadline = Long.MAX_VALUE var demand = 0.0 + var shouldRebuild = false - // Pull in the work of the outputs - val inputIterator = activeInputs.listIterator() - for (input in inputIterator) { + // Pull in the work of the inputs + for (i in 0 until inputSize) { + val input = inputArray[i] input.pullSync() - // Remove outputs that have finished + // Remove inputs that have finished if (!input.isActive) { input.actualRate = 0.0 - inputIterator.remove() + shouldRebuild = true } else { demand += input.limit deadline = min(deadline, input.deadline) } } + // Slow-path: Rebuild the input array based on the (apparently) updated `activeInputs` + if (shouldRebuild) { + inputArray = activeInputs.toTypedArray() + inputSize = inputArray.size + _inputArray = inputArray + } + val rate = if (demand > capacity) { // If the demand is higher than the capacity, we need use max-min fair sharing to distribute the // constrained capacity across the inputs. // Sort in-place the inputs based on their pushed flow. // Profiling shows that it is faster than maintaining some kind of sorted set. - activeInputs.sort() + inputArray.sort() // Divide the available output capacity fairly over the inputs using max-min fair sharing - val size = activeInputs.size - for (i in activeInputs.indices) { - val input = activeInputs[i] - val availableShare = availableCapacity / (size - i) + for (i in 0 until inputSize) { + val input = inputArray[i] + val availableShare = availableCapacity / (inputSize - i) val grantedRate = min(input.allowedRate, availableShare) availableCapacity -= grantedRate -- cgit v1.2.3 From f9483bc5782d86637777c0d21c383ce3e2c0851b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 8 Oct 2021 12:23:48 +0200 Subject: perf(simulator): Optimize clock storage --- .../core/SimulationCoroutineDispatcher.kt | 44 +++++++++++++--------- .../simulator/flow/internal/FlowEngineImpl.kt | 13 +++++-- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/SimulationCoroutineDispatcher.kt b/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/SimulationCoroutineDispatcher.kt index e2f7874c..908e902a 100644 --- a/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/SimulationCoroutineDispatcher.kt +++ b/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/SimulationCoroutineDispatcher.kt @@ -36,11 +36,6 @@ import kotlin.coroutines.CoroutineContext */ @OptIn(InternalCoroutinesApi::class) public class SimulationCoroutineDispatcher : CoroutineDispatcher(), SimulationController, Delay { - /** - * The virtual clock of this dispatcher. - */ - override val clock: Clock = VirtualClock() - /** * Queue of ordered tasks to run. */ @@ -54,7 +49,12 @@ public class SimulationCoroutineDispatcher : CoroutineDispatcher(), SimulationCo /** * The current virtual time of simulation */ - private var _time = 0L + private var _clock = SimClock() + + /** + * The virtual clock of this dispatcher. + */ + override val clock: Clock = ClockAdapter(_clock) override fun dispatch(context: CoroutineContext, block: Runnable) { block.run() @@ -79,14 +79,14 @@ public class SimulationCoroutineDispatcher : CoroutineDispatcher(), SimulationCo } override fun toString(): String { - return "SimulationCoroutineDispatcher[time=${_time}ms, queued=${queue.size}]" + return "SimulationCoroutineDispatcher[time=${_clock.time}ms, queued=${queue.size}]" } private fun post(block: Runnable) = queue.add(TimedRunnable(block, _counter++)) private fun postDelayed(block: Runnable, delayTime: Long) = - TimedRunnable(block, _counter++, safePlus(_time, delayTime)) + TimedRunnable(block, _counter++, safePlus(_clock.time, delayTime)) .also { queue.add(it) } @@ -100,31 +100,41 @@ public class SimulationCoroutineDispatcher : CoroutineDispatcher(), SimulationCo override fun advanceUntilIdle(): Long { val queue = queue - val oldTime = _time - while (queue.isNotEmpty()) { - val current = queue.poll() + val clock = _clock + val oldTime = clock.time + + while (true) { + val current = queue.poll() ?: break // If the scheduled time is 0 (immediate) use current virtual time if (current.time != 0L) { - _time = current.time + clock.time = current.time } current.run() } - return _time - oldTime + return clock.time - oldTime } - private inner class VirtualClock(private val zone: ZoneId = ZoneId.systemDefault()) : Clock() { + /** + * A helper class that holds the time of the simulation. + */ + private class SimClock(@JvmField var time: Long = 0) + + /** + * A helper class to expose a [Clock] instance for this dispatcher. + */ + private class ClockAdapter(private val clock: SimClock, private val zone: ZoneId = ZoneId.systemDefault()) : Clock() { override fun getZone(): ZoneId = zone - override fun withZone(zone: ZoneId): Clock = VirtualClock(zone) + override fun withZone(zone: ZoneId): Clock = ClockAdapter(clock, zone) override fun instant(): Instant = Instant.ofEpochMilli(millis()) - override fun millis(): Long = _time + override fun millis(): Long = clock.time - override fun toString(): String = "SimulationCoroutineDispatcher.VirtualClock[time=$_time]" + override fun toString(): String = "SimulationCoroutineDispatcher.ClockAdapter[time=${clock.time}]" } /** diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index a9234abf..450556f8 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -38,7 +38,7 @@ import kotlin.coroutines.CoroutineContext * @param context The coroutine context to use. * @param clock The virtual simulation clock. */ -internal class FlowEngineImpl(private val context: CoroutineContext, override val clock: Clock) : FlowEngine, Runnable { +internal class FlowEngineImpl(private val context: CoroutineContext, clock: Clock) : FlowEngine, Runnable { /** * The [Delay] instance that provides scheduled execution of [Runnable]s. */ @@ -70,6 +70,13 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va */ private var batchIndex = 0 + /** + * The virtual [Clock] of this engine. + */ + override val clock: Clock + get() = _clock + private val _clock: Clock = clock + /** * Update the specified [ctx] synchronously. */ @@ -113,7 +120,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va try { // Flush the work if the engine is not already running if (batchIndex == 1 && queue.isNotEmpty()) { - doRunEngine(clock.millis()) + doRunEngine(_clock.millis()) } } finally { batchIndex-- @@ -122,7 +129,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, override va /* Runnable */ override fun run() { - val now = clock.millis() + val now = _clock.millis() val invocation = futureInvocations.poll() // Clear invocation from future invocation queue assert(now >= invocation.timestamp) { "Future invocations invariant violated" } -- cgit v1.2.3 From 4433185388f843140aad096dfdd88dfe2398bf2b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 8 Oct 2021 16:49:55 +0200 Subject: perf(simulator): Specialize FlowEngine queues This change specializes the queues used by the FlowEngine implementation in order to reduce the overhead caused by type-erasure of generics. --- .../flow/internal/FlowConsumerContextImpl.kt | 22 ++- .../opendc/simulator/flow/internal/FlowDeque.kt | 116 ++++++++++++ .../simulator/flow/internal/FlowEngineImpl.kt | 38 +--- .../simulator/flow/internal/FlowTimerQueue.kt | 195 +++++++++++++++++++++ 4 files changed, 329 insertions(+), 42 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowDeque.kt create mode 100644 opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowTimerQueue.kt diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index 9a568897..0baa7880 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -134,8 +134,8 @@ internal class FlowConsumerContextImpl( /** * The timers at which the context is scheduled to be interrupted. */ - private var _timer: FlowEngineImpl.Timer? = null - private val _pendingTimers: ArrayDeque = ArrayDeque(5) + private var _timer: Long = Long.MAX_VALUE + private val _pendingTimers: ArrayDeque = ArrayDeque(5) override fun start() { check(_flags and ConnState == ConnPending) { "Consumer is already started" } @@ -217,8 +217,8 @@ internal class FlowConsumerContextImpl( */ fun doUpdate( now: Long, - visited: ArrayDeque, - timerQueue: PriorityQueue, + visited: FlowDeque, + timerQueue: FlowTimerQueue, isImmediate: Boolean ) { var flags = _flags @@ -326,8 +326,7 @@ internal class FlowConsumerContextImpl( // Prune the head timer if this is a delayed update val timer = if (!isImmediate) { // Invariant: Any pending timer should only point to a future timestamp - // See also `scheduleDelayed` - val timer = pendingTimers.poll() + val timer = pendingTimers.poll() ?: Long.MAX_VALUE _timer = timer timer } else { @@ -342,7 +341,7 @@ internal class FlowConsumerContextImpl( if (newDeadline == Long.MAX_VALUE || flags and ConnState != ConnActive || flags and ConnDisableTimers != 0 || - (timer != null && newDeadline >= timer.target) + (timer != Long.MAX_VALUE && newDeadline >= timer) ) { // Ignore any deadline scheduled at the maximum value // This indicates that the source does not want to register a timer @@ -350,12 +349,11 @@ internal class FlowConsumerContextImpl( } // Construct a timer for the new deadline and add it to the global queue of timers - val newTimer = FlowEngineImpl.Timer(this, newDeadline) - _timer = newTimer - timerQueue.add(newTimer) + _timer = newDeadline + timerQueue.add(this, newDeadline) - // A timer already exists for this connection, so add it to the queue of pending timers - if (timer != null) { + // Slow-path: a timer already exists for this connection, so add it to the queue of pending timers + if (timer != Long.MAX_VALUE) { pendingTimers.addFirst(timer) } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowDeque.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowDeque.kt new file mode 100644 index 00000000..c6cba4b7 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowDeque.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +import java.util.* + +/** + * A specialized [ArrayDeque] for [FlowConsumerContextImpl] implementations. + */ +internal class FlowDeque(initialCapacity: Int = 256) { + /** + * The array of elements in the queue. + */ + private var _elements: Array = arrayOfNulls(initialCapacity) + private var _head = 0 + private var _tail = 0 + + /** + * Determine whether this queue is not empty. + */ + fun isNotEmpty(): Boolean { + return _head != _tail + } + + /** + * Add the specified [ctx] to the queue. + */ + fun add(ctx: FlowConsumerContextImpl) { + val es = _elements + var tail = _tail + + es[tail] = ctx + + tail = inc(tail, es.size) + _tail = tail + + if (_head == tail) { + doubleCapacity() + } + } + + /** + * Remove a [FlowConsumerContextImpl] from the queue or `null` if the queue is empty. + */ + fun poll(): FlowConsumerContextImpl? { + val es = _elements + val head = _head + val ctx = es[head] + + if (ctx != null) { + es[head] = null + _head = inc(head, es.size) + } + + return ctx + } + + /** + * Clear the queue. + */ + fun clear() { + _elements.fill(null) + _head = 0 + _tail = 0 + } + + private fun inc(i: Int, modulus: Int): Int { + var x = i + if (++x >= modulus) { + x = 0 + } + return x + } + + /** + * Doubles the capacity of this deque + */ + private fun doubleCapacity() { + assert(_head == _tail) + val p = _head + val n = _elements.size + val r = n - p // number of elements to the right of p + + val newCapacity = n shl 1 + check(newCapacity >= 0) { "Sorry, deque too big" } + + val a = arrayOfNulls(newCapacity) + + _elements.copyInto(a, 0, p, r) + _elements.copyInto(a, r, 0, p) + + _elements = a + _head = 0 + _tail = n + } +} diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index 450556f8..55debef0 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -48,12 +48,12 @@ internal class FlowEngineImpl(private val context: CoroutineContext, clock: Cloc /** * The queue of connection updates that are scheduled for immediate execution. */ - private val queue = ArrayDeque() + private val queue = FlowDeque() /** * A priority queue containing the connection updates to be scheduled in the future. */ - private val futureQueue = PriorityQueue() + private val futureQueue = FlowTimerQueue() /** * The stack of engine invocations to occur in the future. @@ -63,7 +63,7 @@ internal class FlowEngineImpl(private val context: CoroutineContext, clock: Cloc /** * The systems that have been visited during the engine cycle. */ - private val visited: ArrayDeque = ArrayDeque() + private val visited = FlowDeque() /** * The index in the batch stack. @@ -151,17 +151,8 @@ internal class FlowEngineImpl(private val context: CoroutineContext, clock: Cloc // Execute all scheduled updates at current timestamp while (true) { - val timer = futureQueue.peek() ?: break - val target = timer.target - - if (target > now) { - break - } - - assert(target >= now) { "Internal inconsistency: found update of the past" } - - futureQueue.poll() - timer.ctx.doUpdate(now, visited, futureQueue, isImmediate = false) + val ctx = futureQueue.poll(now) ?: break + ctx.doUpdate(now, visited, futureQueue, isImmediate = false) } // Repeat execution of all immediate updates until the system has converged to a steady-state @@ -184,9 +175,9 @@ internal class FlowEngineImpl(private val context: CoroutineContext, clock: Cloc } // Schedule an engine invocation for the next update to occur. - val headTimer = futureQueue.peek() - if (headTimer != null) { - trySchedule(now, futureInvocations, headTimer.target) + val headDeadline = futureQueue.peekDeadline() + if (headDeadline != Long.MAX_VALUE) { + trySchedule(now, futureInvocations, headDeadline) } } @@ -224,17 +215,4 @@ internal class FlowEngineImpl(private val context: CoroutineContext, clock: Cloc */ fun cancel() = handle.dispose() } - - /** - * An update call for [ctx] that is scheduled for [target]. - * - * This class represents an update in the future at [target] requested by [ctx]. - */ - class Timer(@JvmField val ctx: FlowConsumerContextImpl, @JvmField val target: Long) : Comparable { - override fun compareTo(other: Timer): Int { - return target.compareTo(other.target) - } - - override fun toString(): String = "Timer[ctx=$ctx,timestamp=$target]" - } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowTimerQueue.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowTimerQueue.kt new file mode 100644 index 00000000..22a390e6 --- /dev/null +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowTimerQueue.kt @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.simulator.flow.internal + +/** + * Specialized priority queue for flow timers. + */ +internal class FlowTimerQueue(initialCapacity: Int = 256) { + /** + * The binary heap of deadlines. + */ + private var _deadlines = LongArray(initialCapacity) { Long.MIN_VALUE } + + /** + * The binary heap of [FlowConsumerContextImpl]s. + */ + private var _pending = arrayOfNulls(initialCapacity) + + /** + * The number of elements in the priority queue. + */ + private var size = 0 + + /** + * Register a timer for [ctx] with [deadline]. + */ + fun add(ctx: FlowConsumerContextImpl, deadline: Long) { + val i = size + val deadlines = _deadlines + if (i >= deadlines.size) { + grow() + } + + siftUp(deadlines, _pending, i, ctx, deadline) + + size = i + 1 + } + + /** + * Update all pending [FlowConsumerContextImpl]s at the timestamp [now]. + */ + fun poll(now: Long): FlowConsumerContextImpl? { + if (size == 0) { + return null + } + + val deadlines = _deadlines + val deadline = deadlines[0] + + if (now < deadline) { + return null + } + + val pending = _pending + val res = pending[0] + val s = --size + + val nextDeadline = deadlines[s] + val next = pending[s]!! + + // Clear the last element of the queue + pending[s] = null + deadlines[s] = Long.MIN_VALUE + + if (s != 0) { + siftDown(deadlines, pending, next, nextDeadline) + } + + return res + } + + /** + * Find the earliest deadline in the queue. + */ + fun peekDeadline(): Long { + return if (size == 0) Long.MAX_VALUE else _deadlines[0] + } + + /** + * Increases the capacity of the array. + */ + private fun grow() { + val oldCapacity = _deadlines.size + // Double size if small; else grow by 50% + val newCapacity = oldCapacity + if (oldCapacity < 64) oldCapacity + 2 else oldCapacity shr 1 + + _deadlines = _deadlines.copyOf(newCapacity) + _pending = _pending.copyOf(newCapacity) + } + + /** + * Insert item [ctx] at position [pos], maintaining heap invariant by promoting [ctx] up the tree until it is + * greater than or equal to its parent, or is the root. + * + * @param deadlines The heap of deadlines. + * @param pending The heap of contexts. + * @param pos The position to fill. + * @param ctx The [FlowConsumerContextImpl] to insert. + * @param deadline The deadline of the context. + */ + private fun siftUp( + deadlines: LongArray, + pending: Array, + pos: Int, + ctx: FlowConsumerContextImpl, + deadline: Long + ) { + var k = pos + + while (k > 0) { + val parent = (k - 1) ushr 1 + val parentDeadline = deadlines[parent] + + if (deadline >= parentDeadline) { + break + } + + deadlines[k] = parentDeadline + pending[k] = pending[parent] + + k = parent + } + + deadlines[k] = deadline + pending[k] = ctx + } + + /** + * Inserts [ctx] at the top, maintaining heap invariant by demoting [ctx] down the tree repeatedly until it + * is less than or equal to its children or is a leaf. + * + * @param deadlines The heap of deadlines. + * @param pending The heap of contexts. + * @param ctx The [FlowConsumerContextImpl] to insert. + * @param deadline The deadline of the context. + */ + private fun siftDown( + deadlines: LongArray, + pending: Array, + ctx: FlowConsumerContextImpl, + deadline: Long + ) { + var k = 0 + val size = size + val half = size ushr 1 + + while (k < half) { + var child = (k shl 1) + 1 + + var childDeadline = deadlines[child] + val right = child + 1 + + if (right < size) { + val rightDeadline = deadlines[right] + + if (childDeadline > rightDeadline) { + child = right + childDeadline = rightDeadline + } + } + + if (deadline <= childDeadline) { + break + } + + deadlines[k] = childDeadline + pending[k] = pending[child] + + k = child + } + + deadlines[k] = deadline + pending[k] = ctx + } +} -- cgit v1.2.3 From e2f002358e9d5be2239fa2cb7ca92c9c96a21b6f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 8 Oct 2021 17:10:45 +0200 Subject: perf(simulator): Eliminate clock access in hot path This change eliminates the clock calls in the hot path, by passing the current timestamp directly as method parameter. --- .../kotlin/org/opendc/simulator/flow/FlowConnection.kt | 7 +++++++ .../org/opendc/simulator/flow/FlowConsumerContext.kt | 4 +++- .../kotlin/org/opendc/simulator/flow/FlowForwarder.kt | 4 ++++ .../simulator/flow/internal/FlowConsumerContextImpl.kt | 12 +++++++----- .../opendc/simulator/flow/internal/FlowEngineImpl.kt | 5 +---- .../opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt | 18 ++++++++++-------- 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt index c327e1e9..8ff0bc76 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConnection.kt @@ -51,6 +51,13 @@ public interface FlowConnection : AutoCloseable { */ public fun pull() + /** + * Pull the source. + * + * @param now The timestamp at which the connection is pulled. + */ + public fun pull(now: Long) + /** * Push the given flow [rate] over this connection. * diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt index d7182497..98922ab3 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowConsumerContext.kt @@ -55,6 +55,8 @@ public interface FlowConsumerContext : FlowConnection { /** * Synchronously pull the source of the connection. + * + * @param now The timestamp at which the connection is pulled. */ - public fun pullSync() + public fun pullSync(now: Long) } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt index 7230a966..e3bdd7ba 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowForwarder.kt @@ -72,6 +72,10 @@ public class FlowForwarder(private val engine: FlowEngine, private val isCoupled _innerCtx?.pull() } + override fun pull(now: Long) { + _innerCtx?.pull(now) + } + @JvmField var lastPull = Long.MAX_VALUE override fun push(rate: Double) { diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt index 0baa7880..58ca918b 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt @@ -164,17 +164,21 @@ internal class FlowConsumerContextImpl( } } - override fun pull() { + override fun pull(now: Long) { val flags = _flags if (flags and ConnState != ConnActive) { return } // Mark connection as pulled - scheduleImmediate(_clock.millis(), flags or ConnPulled) + scheduleImmediate(now, flags or ConnPulled) } - override fun pullSync() { + override fun pull() { + pull(_clock.millis()) + } + + override fun pullSync(now: Long) { val flags = _flags // Do not attempt to flush the connection if the connection is closed or an update is already active @@ -182,8 +186,6 @@ internal class FlowConsumerContextImpl( return } - val now = _clock.millis() - if (flags and (ConnPulled or ConnPushed) != 0 || _deadline == now) { engine.scheduleSync(now, this) } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt index 55debef0..3c79d54e 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowEngineImpl.kt @@ -129,11 +129,8 @@ internal class FlowEngineImpl(private val context: CoroutineContext, clock: Cloc /* Runnable */ override fun run() { - val now = _clock.millis() val invocation = futureInvocations.poll() // Clear invocation from future invocation queue - assert(now >= invocation.timestamp) { "Future invocations invariant violated" } - - doRunEngine(now) + doRunEngine(invocation.timestamp) } /** diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt index eab5b299..a0fb8a4e 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt +++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt @@ -302,7 +302,7 @@ public class MaxMinFlowMultiplexer( // a few inputs and little changes at the same timestamp. // We always pick for option (1) unless there are no outputs available. if (activationOutput != null) { - activationOutput.pull() + activationOutput.pull(now) return } else { runScheduler(now) @@ -320,7 +320,7 @@ public class MaxMinFlowMultiplexer( return try { _schedulerActive = true - doRunScheduler(delta) + doRunScheduler(now, delta) } finally { _schedulerActive = false } @@ -371,7 +371,7 @@ public class MaxMinFlowMultiplexer( * * @return The deadline after which a new scheduling cycle should start. */ - private fun doRunScheduler(delta: Long): Long { + private fun doRunScheduler(now: Long, delta: Long): Long { val activeInputs = _activeInputs val activeOutputs = _activeOutputs var inputArray = _inputArray @@ -396,7 +396,8 @@ public class MaxMinFlowMultiplexer( // Pull in the work of the inputs for (i in 0 until inputSize) { val input = inputArray[i] - input.pullSync() + + input.pullSync(now) // Remove inputs that have finished if (!input.isActive) { @@ -595,8 +596,8 @@ public class MaxMinFlowMultiplexer( /** * Pull the source if necessary. */ - fun pullSync() { - _ctx?.pullSync() + fun pullSync(now: Long) { + _ctx?.pullSync(now) } /* FlowConsumer */ @@ -733,8 +734,8 @@ public class MaxMinFlowMultiplexer( /** * Pull this output. */ - fun pull() { - _conn?.pull() + fun pull(now: Long) { + _conn?.pull(now) } override fun onStart(conn: FlowConnection, now: Long) { @@ -772,6 +773,7 @@ public class MaxMinFlowMultiplexer( // Output is not the activation output, so trigger activation output and do not install timer for this // output (by returning `Long.MAX_VALUE`) scheduler.trigger(now) + Long.MAX_VALUE } } -- cgit v1.2.3